目次

エレクトリックキーヤー

 エレクトリックキーヤーは、アマチュア無線の
 モールス符号を出力するときに使う装置です。
 エレクトリックキーヤーを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を実装する基板は、以下です。



 内蔵クロックを利用するので、回路は簡単。




目次

inserted by FC2 system