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

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

16F1619には、シリアル通信を行うためのEUSART(Enhanced Universal Synchronous Asynchronous Receiver Transmitter )が組み込まれています。EUSARTには、同期および非同期のシリアル送受信を行う機能がありますが、このページでは、非同期の送信にかかわる機能だけの説明です。

非同期モードでは、標準の非ゼロ復帰(NRZ)形式を使用してデータを送受信します。データは2つのレベルで表し、「1」を VOHマーク状態といい、「0」は、VOLスペース状態です。NRZは、同じ値の連続して送信されたデータビットが、各ビット送信間でニュートラルレベルに戻ることなく、そのビットの出力レベルに留まることを指します。NRZ送信のアイドルはマーク状態で、各文字送信は、1つのスタートビットとそれに続く8または9つのデータビットで構成され、EUSARTはLSbから送受信します。1つ以上のストップビットで終了します。スタートビットはスペースで、ストップビットはマークで、最も一般的なデータ形式はパリティなしの8ビット長です。オンチップの専用8ビット/ 16ビットボーレートジェネレータを使用して、システムオシレータから標準ボーレートクロックを作りさします。EUSARTのトランスミッターとレシーバーは機能的に独立していますが、同じデータ形式とボーレートを共有しています。

重要;
RXおよびCK入力ピンは、それぞれRXPPSおよびCKPPSレジスタで選択します。TX/CK、および DT出力ピンは、各ピンのRxyPPSレジスタで選択します。同期モードではRX入力がDT出力と結合されるため、同期モードで動作させる場合、ユーザーの責任で、これら両方に同じピンを選択する必要があります。なおEUSART制御ロジックは、データ方向ドライバーを自動的に制御します。

非同期シリアル送信

非同期の送信は、TXIFの内容を読み込みTX1REG(送信バッファ)の準備ができたこと(TXIF = 1)を確認し、送信データをTX1REGに書き込みます。Tx Shift Registor(TSR)の内容が送り出されるとTX1REGの内容が、TSRに移され、TXIFが1になります。このとき送信インタラプト(TXIE =1)が許可されているとインタラプトが発生します。非同期の送信に必要なシフトクロックは、システムクロックをBaud Rate Genaratorで分周して発生させます。非同期の送信に関連するレジスター一覧を下表に示します。

EUSART送信機のブロック図を示します。トランスミッタの中心は、ソフトウェアから直接アクセスできないシリアル送信シフトレジスタ(TSR)です。TSRは、TXxREGレジスタである送信バッファからデータを取得します。

注(1);同期モードでは、DT出力とRX入力のPPS選択で同じピンを指定します。

トランスミッターの有効化

EUSARTトランスミッターは、次の3つの制御ビットを構成することにより、非同期動作が可能になります。他のすべてのEUSART制御ビットは、デフォルト状態にあると仮定します。

TXEN = 1
TXxSTAレジスタのTXENビットを設定すると、EUSARTの送信回路が有効になります。
SYNC = 0
TXxSTAレジスタのSYNCビットをクリアすると、EUSARTが非同期動作に設定されます。
SPEN = 1
RCxSTAレジスタのSPENビットを設定すると、EUSARTが有効になり、TX/CK I/Oピンが自動的に出力に設定されます。TX/CKピンがアナログペリフェラルと共有されている場合、対応するANSELビットをクリアしてアナログ I/O機能を無効にする必要があります。

注:TXENイネーブルビットが設定されると、TXIF送信機割り込みフラグが設定されます。

データの送信

TXxREGレジスタに文字を書き込むと送信が開始されます。これが最初の文字である場合や、前の文字がTSRから完全に送信されていた場合、TXxREGのデータはすぐにTSRレジスタに転送されます。TSRに前の文字のすべてまたは一部がまだ残ってるいる場合、新しい文字データは、前の文字のストップビットが送信されるまでTXxREGに保持されます。TXxREGの保留中の文字は、ストップビット送信の直後の 1 Tcy後にTSRに転送され、その直後にスタートビット、データビット、ストップビットシーケンスが開始されます。

送信データの極性

送信データの極性は、BAUDxCONレジスタのSCKPビットで制御できます。このビットのデフォルト状態は「0」で、正論理の送信アイドルおよびデータビットを出力します。SCKPビットを「1」に設定すると、送信データが反転し、負論理のアイドルとデータビットに設定されます。

送信割り込みフラグ

PUS1レジスタのTXIF割り込みフラグビットは、EUSARTトランスミッタが有効で、TXxREGに送信する文字がロードされていない場合は常にセットされます。つまり、TXIFビットは、TSRが文字でビジー状態で、TXxREGに送信待ちの新しい文字がある場合にのみクリアされます。TXxREGに書き込んでも、TXIFフラグビットはすぐにはクリアされません。TXIFは、書き込み実行から2命令サイクル後でないと有効になりません。TXxREG書き込みの直後にTXIFをポーリングすると、無効な値が返されます。TXIFビットは読み取り専用で、ソフトウェアでセットやクリアすることはできません。

TXIE割り込みを有効にするには、PIE1レジスタのTXIE割り込み有効化ビットをセットします。ただし、TXIEイネーブルビットの状態に関係なく、TXxREGが空の場合は常にTXIFフラグビットがセットされます。

データ送信時に割り込みを使用するには、送信するデータがまだある場合にのみTXIEビットをセットします。送信の最後の文字をTXxREGに書き込んだら、TXIE割り込み有効ビットをクリアします。

TSRステータス

TXxSTAレジスタのTRMTビットは、TSRレジスタのステータスを示します。これは読み取り専用ビットです。TRMTビットは、TSRレジスタが空のときにセットされ、TXxREGからTSRレジスタに文字が転送されるとクリアされます。すべてのビットがTSRレジスタからシフトアウトされるまで、TRMTビットはクリアされたままです。このビットには割り込みロジックが関連付けられていないため、ユーザーはこのビットをポーリングしてTSRステータスを判別する必要があります。

注意;
TSRレジスタはデータメモリにマップされていないため、ユーザーは使用できません。

非同期送信のセットアップ:
  1. SPxBRGH、SPxBRGLレジスタペアとBRGHおよびBRG16ビットを初期化して、目的のボーレートを選択します(セクション25.4「EUSARTボーレートジェネレータ(BRG)」を参照)。
  2. TXピンを指定するため、出力させるピンのRxyPPSレジスタにTX/CK出力番号(18)を設定します。
  3. SYNCビットをクリアし、SPENビットをセットして、非同期シリアルポートを有効にします。
  4. 反転送信が必要な場合は、SCKPビットをセットします。
  5. TXENビットをセットして送信を有効にします。これにより、TXIF割り込みビットがセットされます。
  6. 割り込みが必要な場合は、PIE1レジスタのTXIEをセットします。INTCONレジスタのGIEビットとPEIEビットもセットされている場合、割り込みがすぐに発生します。
  7. 8ビットデータをTXxREGレジスタにロードします。これで送信が始まります。

EUSART非同期受信

非同期モードは通常、RS-232システムで使用されます。レシーバのブロック図を図25-2に示します。データは RX/DTピンで受信され、データ回復ブロックを駆動します。データ回復ブロックは、実際にはボーレートの16倍で動作する高速シフターですが、シリアル受信シフトレジスタ(RSR)はビットレートで動作します。文字の8ビットまたは9ビットすべてがシフトインされると、それらはすぐに2文字の先入れ先出し(FIFO)メモリに転送されます。FIFOバッファリングにより、ソフトウェアがEUSART受信機のサービスを開始する前に、2つの完全な文字の受信と3番目の文字の開始が可能になります。FIFOおよびRSRレジスタは、ソフトウェアから直接アクセスできません。受信データへのアクセスは、RCxREGレジスタを介して行われます。

注(1);同期モードでは、RX入力とDT出力のPPS選択で同じピンを指定します。

レシーバーの有効化

EUSARTレシーバーは、以下の3つの制御ビットを構成することにより、非同期動作が可能になります。
他のすべてのEUSART制御ビットは、デフォルト状態にあると仮定しています。

    CREN = 1
    RCxSTAレジスタの Continuous Receive Enable(CREN)ビットをセットすると、EUSARTの受信回路が有効になります。
    SYNC = 0
    TXxSTAレジスタのSYNCビットをクリアすると、EUSARTが非同期動作に設定されます。
    SPEN = 1
    RCxSTAレジスタのSPENビットをセットすると、EUSARTが有効になります。

注意;
RX/DT I/Oピンの対応するTRISビットをセットし、入力に設定する必要があります。
アナログ併用ピンの場合、対応するANSELビットをクリアし、デジタル入力にする必要があります。

データの受信

レシーバのデータ回復回路は、最初のビットの立ち下がりエッジで文字の受信を開始します。開始ビットとも呼ばれる最初のビットは常にゼロです。データ回復回路は、スタートビットの中央までの半分のビット時間をカウントし、ビットがまだゼロであることを確認します。ゼロでない場合、データ回復回路はエラーを生成せずに文字の受信を中止し、スタートビットの立ち下がりエッジの検索を再開します。スタートビットゼロ検証が成功した場合、データ回復回路は次のビットの中央までのフルビット時間をカウントします。次に、ビットは多数決検出回路によってサンプリングされ、結果の「0」または「1」がRSRにシフトされます。これは、すべてのデータビットがサンプリングされ、RSRにシフトされるまで繰り返されます。最後の1ビット時間を測定し、レベルをサンプリングします。これはストップビットです。これは常に「1」です。データ回復回路がストップビット位置で「0」をサンプリングした場合、この文字にフレーミングエラーが設定されます。それ以外の場合、この文字のフレーミングエラーはクリアされます。フレーミングエラーの詳細は、セクション25.1.2.4「受信フレーミングエラー」を参照してください。

すべてのデータビットとストップビットを受信した直後に、RSR内の文字がEUSART受信FIFOに転送され、PIR1レジスタのRCIF割り込みフラグビットが設定されます。FIFOの先頭文字は、RCxREGレジスタを読み取ることによってFIFOから転送されます。

注意;
受信FIFOがオーバーランしている場合、オーバーラン状態が解消されるまで、追加の文字は受信されません。オーバーランエラーの詳細はセクション25.1.2.5「オーバーランエラーの受信」を参照してください。

受信割り込み

PUS1レジスタのRCIF割り込みフラグビットは、EUSART受信機が有効になっていて、受信FIFOに未読文字がある場合は常に設定されます。RCIF割り込みフラグビットは読み取り専用で、ソフトウェアでセットまたはクリアできません。RCIF割り込みは、次のビットをすべて設定することで有効になります。

受信フレーミングエラー

受信FIFOバッファの各文字には、対応するフレーミングエラーステータスビットがあります。フレーミングエラーは、ストップビットが予期された時間に表示されなかったことを示します。フレーミングエラーステータスは、RCxSTAレジスタのFERRビットを介してアクセスされます。FERRビットは、受信FIFOの先頭の未読文字のステータスを表します。したがって、RCxREGを読み取る前にFERRビットを読み取る必要があります。

FERRビットは読み取り専用であり、受信FIFOの先頭の未読文字にのみ適用されます。フレーミングエラー(FERR = 1)は、追加の文字の受信を妨げません。FERRビットをクリアする必要はありません。FIFOバッファから次の文字を読み取ると、FIFOが次の文字と対応する次のフレーミングエラーに進みます。

EUSARTをリセットするRCxSTAレジスタのSPENビットをクリアすると、FERRビットを強制的にクリアできます。RCxSTAレジスタのCRENビットをクリアしても、FERRビットには影響しません。フレーミングエラー自体は割り込みを生成しません。

受信オーバーランエラー

受信FIFOバッファは2つの文字を保持できます。FIFOにアクセスする前に3番目の文字全体を受信すると、オーバーランエラーが生成されます。これが発生すると、RCxSTAレジスタのOERRビットがセットされます。FIFOバッファに既にある文字を読み取ることはできますが、エラーが解消されるまで追加の文字は受信されません。エラーは、RCxSTAレジスタのCRENビットをクリアするか、RCxSTAレジスタのSPENビットをクリアしてEUSARTをリセットすることによってクリアする必要があります。

非同期受信のセットアップ
  1. SPxBRGH、SPxBRGLレジスタペアとBRGHおよびBRG16ビットを初期化して、目的のボーレートを選択します(セクション25.4「EUSARTボーレートジェネレータ(BRG)」を参照)。
  2. デフォルト(RB5)以外をRX入力ピンに指定するには、RXPPSレジスタにピン番号を設定します。
  3. RXピンのANSELビットをクリアします(該当する場合)。
  4. SPENビットを設定して、シリアルポートを有効にします。SYNCビットをクリアして非同期動作に設定します。
  5. 割り込みが必要な場合は、PIE1レジスタの RCIEとINTCONレジスタのGIE、PEIEビットをセットします。
  6. 9ビット受信が必要な場合は、RX9ビットを設定します。
  7. CRENビットをセットして受信を有効にします。
  8. RCIF割り込みフラグビットは、キャラクターがRSRから受信バッファに転送されるとセットされます。RCIE割り込みイネーブルビットがセットされている場合、割り込みが生成されます。
  9. RCxSTAレジスタを読み取ってエラーフラグを確認処理します。
  10. RCxREGレジスタを読み取ることによって、受信バッファから受信した8ビットデータを取得します。
  11. オーバーランが発生した場合は、CRENレシーバーイネーブルビットをクリアしてOERRフラグをクリアします。

ボーレートジェネレーター(BRG)

ボーレートジェネレーター(BRG)は、非同期と同期の両方のEUSART動作サポート専用の8ビットまたは16ビットのタイマーです。デフォルトでは、BRGは8ビットモードで動作します。BAUDxCONレジスタのBRG16ビットを設定すると、16ビットモードが選択されます。

Configuration Bits Baud Rate Formula
SYNC BRG16 BRGH
0 0 0 FOSC/[64 (n+1)]
0 0 1 FOSC/[16 (n+1)]
0 1 0
0 1 1 FOSC/[4 (n+1)]

SPxBRGH、SPxBRGLレジスタペアは、ボーレートタイマーの周期を決定します。非同期モードでは、ボーレート周期の乗数は、TXxSTAレジスタのBRGHビットとBAUDxCONレジスタのBRG16ビットの両方によって決定されます。

右表に、ボーレートを決定する式を示します。
( n = SPxBRGH, SPxBRGLペアの値)
また、代表的なボーレートとボーレートエラーも示します。

ボーレート SYNC = 0, BRGH = 1, BRG16 = 1
1M 4M 8M 32M
SP1BRG % Error SP1BRG % Error SP1BRG % Error SP1BRG % Error
2400 103 0.16 416 0.08 832 0.04 3332 0.01
9600 25 0.16 103 0.16 207 0.16 832 0.04
19.2K 12 0.16 51 0.16 103 0.16 416 -0.08
115.2K - - 8 -3.55 16 2.12 68 -0.64
レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
INTCON GIE PEIE - - - - - INTEDG
PIE1 TMR1GIE ADIE RCIE TXIE SSP1IE BCL1IE TMR2IE TMR1IE
PIR1 TMR1GIF ADIF RCIF TXIF SSP1IF BCL1IF TMR2IF TMR1IF
RC1STA SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
TX1STA CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
RC1REG EUSART Receive Data Register
TX1REG EUSART Transmit Data Register
BAUD1CON ABDOVF RCIDL SCKP BRG16 WUE ABDEN
SP1BRGH Baud Rate Generator<15:8>
SP1BRGL Baud Rate Generator< 7:0>
レジスタ BIT 内容 1 0
INTCON 7 GIE 全インタラプトの使用許可 許可
6 PEIE 周辺機能インタラプトの使用許可 許可
PIE1 5 RCIE シリアル送信のインタラプト許可 許可
PIE1 4 TXIE シリアル送信のインタラプト許可 許可
PIR1 5 RCIF シリアル送信バッファフラグ 使用中
PIR1 4 TXIF シリアル送信バッファフラグ 使用中
RC1STA 7 SPEN 入出力ピンのシリアル設定 ON OFF
6 RX9 9 ビット受信 9 bit 8 bit
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) 1 0
TX1STA 7 CSRC Clock Source Select (同期モードのみ) - -
6 TX9 9 ビット送信 9 bit 8 bit
5 TXEN 送信許可 許可
4 SYNC 同期モード 同期 非同期
3 SENDB Break文字を送信 送信 完了
2 BRGH High Baud Rate選択 High Low
1 TRMT TSRステイタス(Read Only) 使用中
0 TX9D 9 ビット目送信データ 1 0
BAUD1CON 4 SCKP 送信極性 反転出力 正論理
3 BRG16 Baud Rate Generatorのビット長 16bit 8bit

シリアルUART送受信のプログラム例

非同期8ビットシリアル、パリティーなし、9600bpsで送受信するプログラムを作成しました。

<回路図>

送信部 --------------------------------------
RC4に接続されたPushSWを押すと「SW ON」を送信します。

受信部 --------------------------------------
受信したASCII文字データにより、指定されたLEDを点滅します。

Curiosityデモボードでプログラムの確認をしています。

<プログラム>

/*********************************************************************
*  File name: EUSATR TxRx 9800
*  Notes: 4MHz内部クロック PLLはOFF
*        LED4    RA5       LED6    RA2
*        LED5    RA1       LED7    RC5
*        pushSW  RC4
*        Rx      RB5       Tx      RB7
* PIC16F1619  MPLAB X IDE with XC8
* Copyright (c) 2020 iwamoto All Rights Reserved
* *******************************************************************/
#include <xc.h>

#define _XTAL_FREQ 4000000
#define LED4     LATA5
#define LED5     LATA1
#define LED6     LATA2
#define LED7     LATC5
#define pushSW   RC4

// CONFIG
#pragma config FOSC = INTOSC, PWRTE = OFF, MCLRE = ON, CP = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO = ON, FCMEN = ON
#pragma config WRT = OFF, PPS1WAY = ON, ZCD = OFF, PLLEN = OFF
#pragma config STVREN = ON, BORV = LO, LPBOR = OFF, LVP = ON
#pragma config WDTCPS = WDTCPS1F, WDTE = OFF, WDTCWS = WDTCWSSW, WDTCCS = SWC

void strOutUSART(char *);
void outCRLFT();
/**********************  Main  ***************/
void main(void)
{
    char SWstate = 0;       // SWの状態
    char RxData;
    OSCCON = 0b01101000;    // PLL disabled; 4MHz_HF; FOSC;
    TRISC5 = 0;             // Outputs RC5
    TRISA  = 0b011001;      // Outputs RA5.2,1
    RB7PPS = 0b10010;       // TX/CK Outputs RB7
    LATA = 0; LATC = 0;     // LEDを消灯
    ANSB5 = 0;              // RB5をデジタル入力とする
    RB7PPS = 0b10010;       // TX/CK Outputs RB7
//    RXPPS = 0b01101;      // RB5をRX入力とする デフォルトで設定
// ----------- UART 初期化 -----------
    RC1STA   = 0b10010000;  // 8 bit 連続受信
    TX1STA   = 0b00100100;  // 非同期送受信 High Baud Rate選択
    BAUD1CON = 0b00001000;  // 16 bit SPBRG
    SP1BRG   = 103;

    while(pushSW);             // RC0が押されるのを待つ
    strOutUSART("Hello OK>");  // 開始のメッセージ
    outCRLFT();
    // ----------- 繰返し --------------------------------------------
    while(1){
        // ------ 受信 ------------------------------------------------
        if(RCIF){
            RxData = RC1REG;        // 受信データを取り込む
            switch(RxData){         // データ内容で、On/Off
                case '0': LATA = 0; LATC = 0; break;
                case '4': LED4 = 1; break;
                case '5': LED5 = 1; break;
                case '6': LED6 = 1; break;
                case '7': LED7 = 1; break;
                default: break;
            }
        }
        // ------ 送信 ------------------------------------------------
        if(pushSW != SWstate){          // SWの状態が変化したら
            __delay_ms(10);             // 10mS遅延
            SWstate = pushSW;           // 新しい状態を記録
            if(pushSW == 0){            // SWが押されたのなら
                strOutUSART("SW ON");   // メッセージを送る
                outCRLFT();             // 改行
            }
        }
    }
}
//-------- 文字列出力
void strOutUSART(char *str){
    while(*str){                 //文字列の終わり(00)まで継続
        while (!PIR1bits.TXIF);  //送信終了待ち
        TXREG = *str++;          //文字出力しポインタ+1
    }
}
void outCRLFT(){
    while (!PIR1bits.TXIF);     //送信終了待ち
    TXREG = 0x0D;               //文字出力
    while (!PIR1bits.TXIF);     //送信終了待ち
    TXREG = 0x0A;               //文字出力
}