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ピンに指定できることに大きな違いがあります。
非同期の送信は、TXxIFの内容を読み込みTXxREG(送信バッファ)の準備ができたこと(TXxIF = 1)を確認し、送信データをTXxREGに書き込みます。Tx Shift Registor(TSR)の内容が送り出されるとTXxREGの内容が、TSRに移され、TXxIFが1になります。このとき送信インタラプト(TXxIE =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 |
| レジスタ | 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 | RCIE | TX1IE | SSP1IE | SSP1IE | TMR2IE | TMR1IE |
| PIR1 | TMR1GIF | ADIF | RCIF | TX1IF | SSP1IF | SSP1IF | TMR2IF | TMR1IF |
| IPR1 | — | ADIP | RCIP | 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 |
| TXREGx | EUSART Transmit 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 | 4 | TX1IF | 送信バッファ フラグ | 空 | 待ち |
| PIE1 | 4 | TX1IE | インタラプトを使用許可 | 許可 | 不 |
| IPR1 | 4 | TX1IP | インタラプト優先度 | 高 | 低 |
| PIR3 | 4 | TX2IF | 送信バッファ フラグ | 空 | 待ち |
| PIE3 | 4 | TX2IE | インタラプトを使用許可 | 許可 | 不 |
| IPR3 | 4 | TX2IP | インタラプト優先度 | 高 | 低 |
| RCSTAx | 7 | SPEN | 出力ピンのシリアル設定 | ON | OFF |
| TXSTAx | 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 | |
| BAUDCONx | 4 | TXCKP | 送信極性 | 反転出力 | 正論理 |
| 3 | BRG16 | Baud Rate Generatorのビット長 | 16bit | 8bit |
シリアル送信の例として、PortA - RA5に続されたPushSWを押すと「OK>」を送信、その後、押すたびに AB・・・と送信するプログラムを作成しました。 接続された SW を押すとLEDも点灯します。送信は、非同期8ビットシリアル、パリティーなし、9600bpsです。USART1とUSART2の例を作成しました。USART2ではTX2をRP17(RC6)に指定しています。
<回路図>
<プログラム>
//*********************************************************
// PIC18F26J50 UART1 送信 Program// : MPLAB xc8
// 内部クロック4Mhz Baud Rate:9600BPS, 16-bit Baud Rate
// PushSWを押すと「OK>」を送信、
// その後、押すたびに AB・・・と送信、
// LEDは、PushSWを押すごとに点滅
// LED : RB0
// PushSW : RA5
// UART Output : RC6
//*********************************************************
#include <xc.h>
#define _XTAL_FREQ 4000000 // delay_ms(x) のための定義
#define pushSW PORTAbits.RA5
#define LED0 LATBbits.LATB0
//-------------- コンフィグレーション ----------------------
//
#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 strOutUSART1(char *);
//*********************************************************
void main(void){
char char_data = 0x41; // "A"
OSCCON = 0b01100011; // 内部クロック4Mhz
LATB = 0; // PortBのすべてのビットを「0」
TRISB = 0b11111110; // LEDのポートを出力に設定
TRISC = 0b10111111; // TX1のポートを出力に設定
ANCON0 = 0b00011111; // すべてのポートをデジタルに設定
ANCON1 = 0b00011111; //
// ----------- UART 初期化 -----------
TRISB = 0xF0;
RCSTA1 = 0b10010000; // UART送受信を有効
TXSTA1 = 0b00100100; // 8Bit非同期送受信
BAUDCON1 = 0b00001000; // HI-16Bitボーレート
SPBRGH1 = 0; // 9600
SPBRG1 = 103;
while(pushSW); // RC0が押されるのを待つ
__delay_ms(10); // 10mS遅延
strOutUSART1("Hello OK>"); // 開始のメッセージ
LED0 = 1; // LEDを点灯
// ----------- 繰返し -----------
while(1){
while(!pushSW); // SWが離れるのを待つ
__delay_ms(10); // 10mS遅延
while(pushSW); // SWが押されるのを待つ
__delay_ms(10); // 10mS遅延
LED0 = !LED0; // LEDを点滅
TXREG1 = char_data++; // AB・・・と送信
}
}
//-------- Rom 文字列出力
void strOutUSART1(char *str){
while(*str){ //文字列の終わり(00)まで継続
while (!PIR1bits.TX1IF); //送信終了待ち
TXREG1 = *str++; //文字出力しポインタ+1
}
}
USART2使用 TX2をRP17(RC6)に指定しています。
//*********************************************************
// PIC18F26J50 UART2 送信 Program// : MPLAB C18
// 内部クロック4Mhz Baud Rate:9600BPS, 16-bit Baud Rate。
// PushSWを押すと「OK>」を送信、
// その後、押すたびに AB・・・と送信、
// LEDは、PushSWを押すごとに点滅
// LED : RB0
// PushSW : RA5
// UART Output : RP17(RC6)
//*********************************************************
#include <xc.h>
#define _XTAL_FREQ 4000000 // delay_ms(x) のための定義
#define pushSW PORTAbits.RA5
#define LED0 LATBbits.LATB0
//-------------- コンフィグレーション ----------------------
//
#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 strOutUSART2(char *);
//*********************************************************
void main(void){
char char_data = 0x41; // "A"
OSCCON = 0b01100011; // 内部クロック4Mhz
LATB = 0; // PortBのすべてのビットを「0」
TRISB = 0b11111110; // LEDのポートを出力に設定
TRISC = 0b10111111; // TX1のポートを出力に設定
ANCON0 = 0b00011111; // すべてのポートをデジタルに設定
ANCON1 = 0b00011111; //
RPOR17 = 5; // RP17(RC6)をUSART2のTX2出力に指定
// ----------- UART 初期化 -----------
RCSTA2 = 0b10010000; // UART送受信を有効
TXSTA2 = 0b00100100; // 8Bit非同期送受信
BAUDCON2 = 0b00001000; // HI-16Bitボーレート
SPBRGH2 = 0; // 9600
SPBRG2 = 103;
while(pushSW); // RC0が押されるのを待つ
__delay_ms(10); // 10mS遅延
strOutUSART2("Hello OK>"); // 開始のメッセージ
LED0 = 1; // LEDを点灯
// ----------- 繰返し -----------
while(1){
while(!pushSW); // SWが離れるのを待つ
__delay_ms(10); // 10mS遅延
while(pushSW); // SWが押されるのを待つ
__delay_ms(10); // 10mS遅延
LED0 = !LED0; // LEDを点滅
TXREG2 = char_data++; // AB・・・と送信
}
}
//-------- Rom 文字列出力
void strOutUSART2(char *str){
while(*str){ //文字列の終わり(00)まで継続
while (!PIR3bits.TX2IF); //送信終了待ち
TXREG2 = *str++; //文字出力しポインタ+1
}
}
Foscとボーレートの関連