目次
前
次
エレクトリックキーヤー
エレクトリックキーヤーは、アマチュア無線の
モールス符号を出力するときに使う装置です。
エレクトリックキーヤーをPIC12F629で実現しました。
2つのキーのどちらかを押すことで、短点(・)と
長点(−)を生成します。
押すボタンにより、論理レベルのHを出力している
時間を変えて、短点(・)、長点(−)に相当する
搬送波をアンテナに送り込みます。
マイコンで、論理レベルHの出力時間を調整します。
2つのプッシュスイッチのどちらを押したのか
を判断して、Hレベルの出力時間を変えます。
プッシュスイッチを押したことを判断するため
シフトレジスタを2つ用意し、10msごとに値
を読み取り、エッジを判定します。
if ( tflag == ON ) {
/* clear flag */
tflag = OFF ;
/* shift */
t_sft <<= 1 ;
e_sft <<= 1 ;
/* mask */
t_sft &= MASK03 ;
e_sft &= MASK03 ;
/* long */
if ( LONG_SW == OFF ) { t_sft |= ON ; }
/* short */
if ( SHORT_SW == OFF ) { e_sft |= ON ; }
/* judge */
xflag = OFF ;
if ( t_sft == ON ) {
xflag = ON ;
sflag = ON ;
}
if ( e_sft == ON ) {
xflag = ON ;
sflag = OFF ;
}
}
短点(・)、長点(−)は、アルファバットのe、tに
なるので、シフトレジスタの頭文字を、対応する1文字
としました。
どちらのスイッチを押したのかで、論理レベルHの
出力時間を変更できるようにフラグを使います。
論理レベルHの出力を実行するために、フラグを
用意し、そのフラグがセットされたときだけ
ピンに論理レベルHを出力します。
if ( xflag == ON ) {
/* clear flag */
xflag = OFF ;
/* set enable flag */
eflag = ON ;
CW_OUT = ON ;
/* delay 2sec. */
delay_ms( SINTC ) ;
if ( sflag ) {
/* clear flag */
sflag = OFF ;
/* add 3sec. */
delay_ms( LINTC ) ;
}
/* disable enable flag */
eflag = OFF ;
CW_OUT = OFF ;
}
短点、長点の出力になっていることをモニタする
ため、サイドトーンと呼ぶ、音を出力します。
サイドトーン出力用フラグをeflagとしています。
シフトレジスタのシフトタイミング生成、サイドトーンの
発音には、タイマー割込みを使います。
周期を1msとします。
void interrupt(void) {
/* generate 1ms */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = 6 ;
/* increment */
timcnt++ ;
scnt++ ;
/* judge */
timv = timcnt & MASKFF ;
if ( timv == 10 ) { tflag = ON ; } /* 10ms */
/* generate sound */
tmp = OFF ;
if ( eflag == ON ) { tmp = (scnt & ON) ; }
TONE_OUT = tmp ;
}
}
サイドトーンは、出力ピンに50%Duty比のパルスを出力します。
パルス出力をeflagの論理値で判断します。
主要な処理を考え、定義したのでスイッチや
サイドトーン出力を、どのピンに配置するか
決めます。
部品点数を減らすため、スイッチに接続する
プルアップ抵抗は、内蔵抵抗を利用します。
ソースコードを作成します。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
typedef unsigned long ULONG ;
#define OFF 0
#define ON OFF+1
#define MASKFF 0xff
#define MASK30 0x30
#define MASK03 0x03
#define MASK0F 0x0f
#define SINTC 1000
#define LINTC 3000
volatile UBYTE tflag ;
volatile UBYTE eflag ;
volatile ULONG timcnt ;
volatile UBYTE timv ;
volatile UBYTE tmp ;
volatile UBYTE sflag ;
volatile UBYTE xflag ;
volatile UBYTE scnt ;
volatile UBYTE t_sft ;
volatile UBYTE e_sft ;
/* function prototype */
void init_usr(void);
void delay_ms(UWORD x);
#define CW_OUT GPIO.B0
#define TONE_OUT GPIO.B1
#define SHORT_SW GPIO.B4
#define LONG_SW GPIO.B5
/* interrupt handler */
void interrupt(void) {
/* generate 1ms */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = 6 ;
/* increment */
timcnt++ ;
scnt++ ;
/* judge */
timv = timcnt & MASKFF ;
if ( timv == 10 ) { tflag = ON ; } /* 10ms */
/* generate sound */
tmp = OFF ;
if ( eflag == ON ) { tmp = (scnt & ON) ; }
TONE_OUT = tmp ;
}
}
void main(void) {
/* user initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* switch handling */
if ( tflag == ON ) {
/* clear flag */
tflag = OFF ;
/* shift */
t_sft <<= 1 ;
e_sft <<= 1 ;
/* mask */
t_sft &= MASK03 ;
e_sft &= MASK03 ;
/* long */
if ( LONG_SW == OFF ) { t_sft |= ON ; }
/* short */
if ( SHORT_SW == OFF ) { e_sft |= ON ; }
/* judge */
xflag = OFF ;
if ( t_sft == ON ) {
xflag = ON ;
sflag = ON ;
}
if ( e_sft == ON ) {
xflag = ON ;
sflag = OFF ;
}
}
/* sound handling */
if ( xflag == ON ) {
/* clear flag */
xflag = OFF ;
/* set enable flag */
eflag = ON ;
CW_OUT = ON ;
/* delay 2sec. */
delay_ms( SINTC ) ;
if ( sflag ) {
/* clear flag */
sflag = OFF ;
/* add 3sec. */
delay_ms( LINTC ) ;
}
/* disable enable flag */
eflag = OFF ;
CW_OUT = OFF ;
}
}
}
/* define function body */
void init_usr(void)
{
/* I/O state */
GPIO = 0x00 ;
/* I/O directions */
TRISIO = 0x30 ; /* bit3,5 as input , others as output */
/* disable compare module */
CMCON = 0x07 ;
/* pull-up */
WPU = 0x30 ;
/* initialize Timer 0 */
{
/*
4MHz/4 = 1MHz -> 1MHz/4 = 250kHz prescaler = 1:4
all inputs are pull-up .
*/
OPTION_REG = 0x01 ;
/* 256 - 250 = 6 */
TMR0 = 6 ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flags */
tflag = OFF ;
sflag = OFF ;
xflag = OFF ;
eflag = OFF ;
/* clear */
timcnt = 0 ;
scnt = 0 ;
t_sft = 0 ;
e_sft = 0 ;
}
void delay_ms(UWORD x)
{
ULONG target ;
/* calcualte last count */
target = timcnt + x ;
/* wait */
while ( timcnt < target ) ;
}
PIC12F629を実装する基板は、以下です。
内蔵クロックを利用するので、回路は簡単。
目次
前
次