18F14K50には、シリアル通信を行うためのEUSART(Enhanced Universal Synchronous Asynchronous Receiver Transmitter )が組み込まれています。EUSARTには、同期および非同期のシリアル送受信を行う機能がありますが、このページでは、非同期の送信にかかわる機能だけの説明です。 非同期の送信は、TXIFの内容を読み込みTXREG(送信バッファ)の準備ができたこと(TXIF = 1)を確認し、送信データをTXREGに書き込みます。Tx Shift Registor(TSR)の内容が送り出されるとTXREGの内容が、TSRに移され、TXIFが1になります。このとき送信インタラプト(TXIE =1)が許可されているとインタラプトが発生します。 非同期の送信に必要なシフトクロックは、システムクロックをBaud Rate Genaratorで分周して発生させます。
サンプルで作成したプログラムは、8ビット、パリティなし、9600bps で「Hello OK」と送信します。非同期の送信に関連するレジスター一覧を下表に示します。
*注意*
TX/CK(RB7)ピンの対応するTRISビットは、入力にセットします。SPEN ビットをセットすると、TX/CK(RB7)ピンは、UARTの出力に設定されますが、RB7ピンを汎用デジタル出力に使用することはできせん。
ボーレート | SYNC = 0, BRGH = 1, BRG16 = 1 | |||||
---|---|---|---|---|---|---|
4M | 8M | 48M | ||||
SPBRG | % Error | SPBRG | % Error | SPBRG | % Error | |
2400 | 416 | 0.08 | 832 | 0.04 | 4999 | 0.00 |
9600 | 103 | 0.16 | 207 | 0.16 | 1249 | 0.00 |
19.2K | 51 | 0.16 | 103 | 0.16 | 624 | 0.00 |
レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
RCON | IPEN | SBOREN | — | RI | TO | PD | POR | BOR |
INTCON | GIEH | GIEL | TMR0IE | INTE | IOCIE | TMR0IF | INTF | IOCIF |
PIE1 | TMR1GIE | ADIE | RCIE | TXIE | SSP1IE | SSP1IE | TMR2IE | TMR1IE |
PIR1 | TMR1GIF | ADIF | RCIF | TXIF | SSP1IF | SSP1IF | TMR2IF | TMR1IF |
IPR1 | — | ADIP | RCIP | TXIP | SSPIP | CCP1IP | TMR2IP | TMR1IP |
RCSTA | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
TXSTA | CSRC | TX9 | TXEN | SYNC | SENDB | BRGH | TRMT | TX9D |
TXREG | EUSART Transmit Data Register | |||||||
BAUDCON | ABDOVF | RCIDL | DTRXP | CKTXP | BRG16 | - | WUE | ABDEN |
SPBRGH | Baud Rate Generator<15:8> | |||||||
SPBRG | Baud Rate Generator< 7:0> |
レジスタ | BIT | 名 | 内容 | 1 | 0 |
---|---|---|---|---|---|
RCON | 7 | IPEN | 2レベルのインタラプト優先度 | 使用 | 不 |
INTCON | 7 | GIEH | 高優先度インタラプトを使用許可 | 許可 | 不 |
6 | GIEL | 低優先度インタラプトを使用許可 | 許可 | 不 | |
PIR1 | 4 | TXIIF | 送信バッファ フラグ | 空 | 待ち |
PIE1 | 4 | TXIIE | インタラプトを使用許可 | 許可 | 不 |
IPR1 | 4 | TXIIP | インタラプト優先度 | 高 | 低 |
RCSTA | 7 | SPEN | 出力ピンのシリアル設定 | ON | OFF |
TXSTA | 7 | CSRC | Clock Source Select (同期モードのみ) | - | - |
6 | TX9 | 9 ビット送信 | 9bit | 8bit | |
5 | TXEN | 送信許可 | 許可 | 不 | |
4 | SYNC | 同期モード | 同期 | 非同期 | |
3 | SENDB | Break文字を送信 | 送信 | 完了 | |
2 | BRGH | High Baud Rate選択 | High | Low | |
1 | TRMT | TSRステイタス(Read Only) | 空 | フル | |
0 | TX9D | 9 ビット目送信データ | 1 | 0 | |
BAUDCON | 4 | CKTXP | 送信極性 | 反転出力 | 正論理 |
3 | BRG16 | Baud Rate Generatorのビット長 | 16bit | 8bit |
シリアル送信の例として、PortC - RC0に続されたPushSWを押すと「Hello OK>」を送信、その後、押すたびに AB・・・と送信するプログラムを作成しました。 接続された SW を押すとLEDも点灯します。送信は、非同期8ビットシリアル、パリティーなし、9600bpsです。 下の写真は、シリアル受信機の受信端子にPICからのデジタル出力を直接接続しサンプルプログラムを動作させたものです。
<回路図>
<プログラム>
//********************************************************* // PIC18F14K50 UART 送信 Program// : MPLABV XC8 // 内部クロック4Mhz Baud Rate:9600BPS, 16-bit Baud Rate // PushSWを押すと「Hello OK>」を送信、 // その後、押すたびに AB・・・と送信、 // LEDは、PushSWを押すごとに点滅 // LED : RC0 // PushSW : RC7 // UART Output : RB7 //********************************************************* #include <xc.h> #define _XTAL_FREQ 4000000 // delay_ms(x) のための定義 #define pushSW PORTCbits.RC7 #define LED LATCbits.LATC0 //-------------- コンフィグレーション ---------------------- #pragma config PWRTEN = OFF, BOREN = OFF, BORV = 30 #pragma config WDTEN = OFF, WDTPS = 32768 #pragma config STVREN = ON #pragma config FOSC = IRC // 内部クロック #pragma config PLLEN = ON, CPUDIV = NOCLKDIV, USBDIV = OFF #pragma config FCMEN = OFF, IESO = OFF, HFOFST = OFF #pragma config LVP = OFF, XINST = OFF, BBSIZ = OFF #pragma config CP0 = OFF, CP1 = OFF, CPB = OFF, CPD = OFF #pragma config WRT0 = OFF, WRT1 = OFF #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTRB = OFF void strOutUSART(char *); //********************************************************* void main(void){ char char_data = 0x41; // 'A' OSCCON = 0b01010010; // 内部クロック4Mhz ANSEL = 0; // Port をデジタルで使用 ANSELH = 0; LATC = 0; TRISC = 0xF0; // ----------- UART 初期化 ----------- TRISB = 0xF0; RCSTA = 0b10010000; // UART送受信を有効 TXSTA = 0b00100100; // 8Bit非同期送受信 BAUDCON = 0b00001000; // HI-16Bitボーレート SPBRGH = 0; // 9600 SPBRG = 103; while(pushSW); // RC0が押されるのを待つ __delay_ms(10); // 10mS遅延 strOutUSART("Hello OK>"); // 開始のメッセージ // ----------- 繰返し ----------- while(1){ while(!pushSW); // SWが離れるのを待つ __delay_ms(10); // 10mS遅延 while(pushSW); // SWが押されるのを待つ __delay_ms(10); // 10mS遅延 LED = !LED; // LEDを点滅 TXREG = char_data++; // AB・・・と送信 } } //-------- 文字列出力 void strOutUSART(char *str){ while(*str){ //文字列の終わり(00)まで継続 while (!PIR1bits.TXIF); //送信終了待ち TXREG = *str++; //文字出力しポインタ+1 } }
Foscとボーレートの関連