目次
前
通信処理
PIC16F627Aには、シリアルインタフェースモジュールが
内蔵されています。ピンアサインは、以下。
シリアル通信には、電圧レベル変換と論理変換が必要なので
抵抗とトランジスタを利用したインタフェースを使います。
シリアル通信用インタフェースを用意したテスト基板は以下。
シリアルインタフェースを利用するために、送信、受信の
モジュールを使うので、対応するレジスタの内容を見て
おきます。
送信モジュールをイネーブルにすればよいので、TXENを
セットします。
TXSTA = (1 << BRGH) | (1 << TXEN);
送信、受信のモジュールを使うので、関連レジスタを見ます。
RB1、RB2をRxD、TxDを使うのと、調歩同期を連続でと指定。
RCSTA = (1 << SPEN) | (1 << CREN) ;
通信条件を以下とすると、データ転送速度の設定が必要になります。
- Speed 9600bps
- Data Length 8bits
- Stop bit 1bit
- Parity None
- Flow control None
データ転送速度は、利用しているクロックに依存しますが
計算して、レジスタに設定しなければなりません。
計算方法と結果を設定するレジスタは、次のように規定
されています。
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)
目次
前