PIC18F14K50の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
シリアル送信

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

Foscとボーレートの関連

レジスタ 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

シリアルUART出力のプログラム例

シリアル送信の例として、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
    }
}