目次

通信処理

 PIC16F627Aには、シリアルインタフェースモジュールが
 内蔵されています。ピンアサインは、以下。



 シリアル通信には、電圧レベル変換と論理変換が必要なので
 抵抗とトランジスタを利用したインタフェースを使います。



 シリアル通信用インタフェースを用意したテスト基板は以下。



 シリアルインタフェースを利用するために、送信、受信の
 モジュールを使うので、対応するレジスタの内容を見て
 おきます。



 送信モジュールをイネーブルにすればよいので、TXENを
 セットします。

  TXSTA = (1 << BRGH) | (1 << TXEN);


 送信、受信のモジュールを使うので、関連レジスタを見ます。



 RB1、RB2をRxD、TxDを使うのと、調歩同期を連続でと指定。

  RCSTA = (1 << SPEN) | (1 << CREN) ;

 通信条件を以下とすると、データ転送速度の設定が必要になります。

 データ転送速度は、利用しているクロックに依存しますが
 計算して、レジスタに設定しなければなりません。
 計算方法と結果を設定するレジスタは、次のように規定
 されています。



 4MHzをシステムクロックにすると、次のように計算できます。

    9600 = 40000/16(x+1)
    x+1 = 26.04
      x = 25

    SPBRG = 25 ;

 1文字の送信、受信には、TXREG、RCREGを利用。

 1文字送信の場合、送信バッファが空であることを
 確認してから、レジスタTXREGに1バイトを転送。

void rs_putchar(UBYTE x)
{
  /* judge empty */
  while ( TXSTA.TRMT == OFF ) ;
  /* transmit */
  TXREG = x ;
}

 受信には、受信バッファを用意し、受信割込みで
 1文字ずつバッファにためていくのがよいでしょう。
 受信割込みは、以下のように定義。

void interrupt(void)
{
  /* judge interrupt term */
  if ( PIR1.RCIF == ON ) {
    /* clear flag */
    PIR1.RCIF = OFF ;
    /* get data */
    ch = RCREG ;
    /* store */
    *(sbuf+sindex) = ch ;
    /* update pointer */
    sindex++ ;
    /* judge */
    if ( ch == '\r' ) {
      sindex = 0 ;
      uflag = ON ;
    }
  }
}

 受信割込みを利用するには、対応するレジスタの
 指定ビットに1か0を設定。

  PIE1 = (1 << RCIE) ;

 シリアル通信関連の初期化は、以下とします。

  TXSTA = (1 << BRGH) | (1 << TXEN);
  RCSTA = (1 << SPEN) | (1 << CREN) ;
  SPBRG = 25 ;
  PIE1 = (1 << RCIE) ;
  sindex = 0 ;
  uflag = OFF ;

 受信バッファとバッファ内ポインタは、次のように定義します。

UBYTE sbuf[8];
UBYTE sindex ;
UBYTE uflag ;

 テストにエコーバック処理をしてみます。

#define OFF 0
#define ON  OFF+1

typedef unsigned char  UBYTE ;
typedef unsigned short UWORD ;

volatile UBYTE sbuf[8];
volatile UBYTE sindex ;
volatile UBYTE uflag ;
volatile UBYTE ii ;
volatile UBYTE tmp ;

/* prototype */
void  usr_init(void);
void  rs_putchar(UBYTE x);
void  crlf(void);

void main(void)
{
  UWORD ldrv ;
  /* initialize */
  usr_init();
  /* endless loop */
  while (ON) {
    /* interrupt handling */
    if ( uflag == ON ) {
      /* clear flag */
      uflag = OFF ;
      /* echo back */
      for ( ii = 0 ; ii < 8 ; ii++ ) {
        /* get 1 byte from receive buffer */
        tmp = *(sbuf+ii);
        /* judge */
        if ( tmp == '\r' ) break ;
        /* show */
        rs_putchar( tmp );
      }
      /* new line */
      crlf();
    }
  }
}

void usr_init(void)
{
  /* disable analog comparator */
  CMCON = 0x07 ;
  /* initialize PORT values */
  PORTA = 0x00 ;
  PORTB = 0x02 ;
  /* set directions */
  TRISA = 0x00 ;
  TRISB = 0x02 ;
  /* initialize serial port */
  {
    TXSTA = (1 << BRGH) | (1 << TXEN);
    RCSTA = (1 << SPEN) | (1 << CREN) ;
    SPBRG = 25 ;
    PIE1.RCIE = ON ;
    sindex = 0 ;
    uflag = OFF ;
  }
  /* enable global interrupt */
  INTCON.GIE = ON ;
}

void rs_putchar(UBYTE x)
{
  /* judge empty */
  while ( TXSTA.TRMT == OFF ) ;
  /* transmit */
  TXREG = x ;
}

void  crlf(void)
{
  rs_putchar('\r');
  rs_putchar('\n');
}

(under construction)

目次

inserted by FC2 system