18F26J50には、シリアル通信を行うためのEUSART(Enhanced Universal Synchronous Asynchronous Receiver Transmitter )が2セット組み込まれています。EUSARTには、同期および非同期のシリアル送受信を行う機能がありますが、ここでは、非同期の受信にかかわる機能の説明です。なお、2つのEUSARTは同じ構造をしているため、両方に該当する場合はEUSARTxと表記しています。関連レジスターも同様に「x」には、1または2の番号が入ります。
ただし、EUSART1は、その入出力ピンが、RC6,RC7に固定されているのに対し、EUSART2は、Peripheral Pin Select (PPS)機能で任意のRPnピンに指定できることに大きな違いがあります。
非同期の受信は、RCxDTピンから入力されたデータをRSR レジスタに読み込み、1ワード分の処理が終わると、受信内容を2本のFIFO(受信バッファ)に取り込みます。同時に準備ができたこと(RCxIF = 1)で通知します。このとき受信インタラプト(RCxIE =1)が許可されているとインタラプトが発生します。
非同期の受信に必要なシフトクロックは、システムクロックを送信と共有のBaud Rate Genaratorで分周して発生させます。
*注意*
EUSART1を使用する場合
EUSART2を使用する場合
TX2とRX2は、PPS機能で任意のRPnピンに指定することができるため、この指定を行った上で、
ボーレート | 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 |
ADコンバータに関連するに関連するレジスターを一覧で説明します。
レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
RCON | IPEN | SBOREN | — | RI | TO | PD | POR | BOR |
INTCON | GIE | PEIE | TMR0IE | INTE | IOCIE | TMR0IF | INTF | IOCIF |
PIE1 | TMR1GIE | ADIE | RC1IE | TX1IE | SSP1IE | SSP1IE | TMR2IE | TMR1IE |
PIR1 | TMR1GIF | ADIF | RC1IF | TX1IF | SSP1IF | SSP1IF | TMR2IF | TMR1IF |
IPR1 | — | ADIP | RC1IP | TX1IP | SSPIP | CCP1IP | TMR2IP | TMR1IP |
PIR3 | SSP2IF | BCL2IF | RC2IF | TX2IF | TMR4IF | CTMUIF | TMR3GIF | RTCCIF |
PIE3 | SSP2IE | BCL2IE | RC2IE | TX2IE | TMR4IE | CTMUIE | TMR3GIE | RTCCIE |
IPR3 | SSP2IP | BCL2IP | RC2IP | TX2IP | TMR4IP | CTMUIP | TMR3GIP | RTCCIP |
RCSTAx | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
TXSTAx | CSRC | TX9 | TXEN | SYNC | SENDB | BRGH | TRMT | TX9D |
RCREGx | EUSART Recive Data Register | |||||||
BAUDCONx | ABDOVF | RCIDL | RXDTP | TXCKP | BRG16 | - | WUE | ABDEN |
SPBRGHx | EUSART Baud Rate Generator Register <15:8> | |||||||
SPBRGx | EUSART Baud Rate Generator Register <7:0> |
レジスタ | BIT | 名 | 内容 | 1 | 0 |
---|---|---|---|---|---|
RCON | 7 | IPEN | 2レベルのインタラプト優先度 | 使用 | 不 |
INTCON | 7 | GIEH | 高優先度インタラプトを使用許可 | 許可 | 不 |
6 | GIEL | 低優先度インタラプトを使用許可 | 許可 | 不 | |
PIR1 | 5 | RC1IF | 受信バッファ フラグ | 空 | 待ち |
PIE1 | 5 | RC1IE | インタラプトを使用許可 | 許可 | 不 |
IPR1 | 5 | RC1IP | インタラプト優先度 | 高 | 低 |
PIR3 | 5 | RC2IF | 受信バッファ フラグ | 空 | 待ち |
PIE3 | 5 | RC2IE | インタラプトを使用許可 | 許可 | 不 |
IPR3 | 5 | RC2IP | インタラプト優先度 | 高 | 低 |
RCSTAx | 7 | SPEN | 出力ピンのシリアル設定 | ON | OFF |
6 | RX9 | 9 ビット受信 | 9bit | 8bit | |
5 | SREN | シングル受信 (同期モードのみ) | ON | OFF | |
4 | CREN | 連続受信 | ON | OFF | |
3 | ADDEN | アドレス検出 (RX9 = 0では使用しない) | ON | OFF | |
2 | FERR | フレーミング エラー (Read Only) | あり | なし | |
1 | OERR | オーバーランエラー (Read Only) | あり | なし | |
0 | RX9D | 受信データの9 ビット目 (Read Only) | |||
TXSTAx | 4 | SYNC | 同期モード | 同期 | 非同期 |
2 | BRGH | High Baud Rate選択 | High | Low | |
BAUDCONx | 7 | ABDOVF | 自動baud レート検出オーバーフロー (Read Only) | あり | なし |
6 | RCIDL | 受信アイドル (Read Only) | アイドル | 作動中 | |
5 | RXDTP | 受信極性 | 反転入力 | 正論理 | |
3 | BRG16 | Baud Rate Generatorのビット長 | 16bit | 8bit | |
1 | WUE | ウェイクアップ | ON | OFF | |
0 | ABDEN: | 自動baud レート検出 | ON | OFF |
非同期8ビットシリアル、パリティーなし、9600bpsで受信するUSART1とUSART2のプログラム例を作成しました。 USART2ではRX2をRP18 (RC7)に指定しています。 受信したASCII文字データにより、指定されたLEDをON/OFFします。
<回路図>
<プログラム>
//********************************************************* // PIC18F26J50 UART1 受信 Program// : MPLAB xc8 // 内部クロック4Mhz Baud Rate:9600BPS, 16-bit Baud Rate // シリアルデータの受信で該当LEDのOnOffを反転させる // 受信データ、 // 0 : 全LED OFF // 1 : LED0 ON/OFF // 2 : LED1 ON/OFF // 3 : LED2 ON/OFF // 4 : LED3 ON/OFF // ポートの設定 // UART Input : RC7 // UART Output : RC6 //********************************************************* #include <xc.h> #define LED0 LATBbits.LATB0 #define LED1 LATBbits.LATB1 #define LED2 LATBbits.LATB2 #define LED3 LATBbits.LATB3 //-------------- コンフィグレーション ---------------------- // #pragma config WDTEN = OFF, PLLDIV = 2, STVREN = ON, XINST = OFF #pragma config CPUDIV = OSC1, CP0 = OFF #pragma config OSC = INTOSC, T1DIG = OFF #pragma config LPT1OSC = OFF, FCMEN = OFF, IESO = OFF #pragma config WDTPS = 32768 #pragma config DSWDTOSC = INTOSCREF, RTCOSC = T1OSCREF #pragma config DSBOREN = OFF, DSWDTEN = OFF, DSWDTPS = 8192 #pragma config IOL1WAY = OFF, MSSP7B_EN = MSK7 #pragma config WPFP = PAGE_1, WPEND = PAGE_0, WPCFG = OFF #pragma config WPDIS = OFF //********************************************************* void main(void){ char RxData; OSCCON = 0b01100010; // 内部クロック4Mhz LATB = 0; // PortBのすべてのビットを「0」 TRISB = 0b11110000; // LEDのポートを出力に設定 TRISC = 0b10111111; // TX1のポートを出力に設定 ANCON0 = 0b00011111; // すべてのポートをデジタルに設定 ANCON1 = 0b00011111; // // UART関連レジスタは以下のように設定される RCSTA1 = 0b10010000; TXSTA1 = 0b00000100; BAUDCON1 = 0b00001000; SPBRGH1 = 0; SPBRG1 = 103; while(1){ while (!PIR1bits.RC1IF); // 受信するまで待つ RxData = RCREG1; // 受信データを取り込む switch(RxData){ // データに対応したLEDを点灯/消灯 case '0': LED0=0; LED1=0; LED2=0; LED3=0; break; case '1': LED0=!LED0; break; case '2': LED1=!LED1; break; case '3': LED2=!LED2; break; case '4': LED3=!LED3; break; } } }
<プログラム> UART2_Rx を RP18 (RC7)に指定
//********************************************************* // PIC18F26J50 UART2 受信 Program// : MPLAB xc8 // 内部クロック4Mhz Baud Rate:9600BPS, 16-bit Baud Rate // シリアルデータの受信で該当LEDのOnOffを反転させる // 受信データ、 // 0 : 全LED OFF // 1 : LED0 ON/OFF // 2 : LED1 ON/OFF // 3 : LED2 ON/OFF // 4 : LED3 ON/OFF // ポートの設定 // UART Input : RP18(RC7) //********************************************************* #include <xc.h> #define LED0 LATBbits.LATB0 #define LED1 LATBbits.LATB1 #define LED2 LATBbits.LATB2 #define LED3 LATBbits.LATB3 //-------------- コンフィグレーション ---------------------- // #pragma config WDTEN = OFF, PLLDIV = 2, STVREN = ON, XINST = OFF #pragma config CPUDIV = OSC1, CP0 = OFF #pragma config OSC = INTOSC, T1DIG = OFF #pragma config LPT1OSC = OFF, FCMEN = OFF, IESO = OFF #pragma config WDTPS = 32768 #pragma config DSWDTOSC = INTOSCREF, RTCOSC = T1OSCREF #pragma config DSBOREN = OFF, DSWDTEN = OFF, DSWDTPS = 8192 #pragma config IOL1WAY = OFF, MSSP7B_EN = MSK7 #pragma config WPFP = PAGE_1, WPEND = PAGE_0, WPCFG = OFF #pragma config WPDIS = OFF //********************************************************* void main(void){ char RxData; OSCCON = 0b01100010; // 内部クロック4Mhz LATB = 0; // PortBのすべてのビットを「0」 TRISB = 0b11110000; // LEDのポートを出力に設定 TRISC = 0b10111111; // TX1のポートを出力に設定 ANCON0 = 0b00011111; // すべてのポートをデジタルに設定 ANCON1 = 0b00011111; // RPINR16 = 18; //RX2 = RP18(RC7) // UART関連レジスタは以下のように設定される RCSTA2 = 0b10010000; TXSTA2 = 0b00000100; BAUDCON2 = 0b00001000; SPBRGH2 = 0; SPBRG2 = 103; while(1){ while (!PIR3bits.RC2IF); // 受信するまで待つ RxData = RCREG2; // 受信データを取り込む switch(RxData){ // データに対応したLEDを点灯/消灯 case '0': LED0=0; LED1=0; LED2=0; LED3=0; break; case '1': LED0=!LED0; break; case '2': LED1=!LED1; break; case '3': LED2=!LED2; break; case '4': LED3=!LED3; break; } } }
SFoscとボーレートの関連