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

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

12F1822 には、シリアル通信を行うためのEUSART(Enhanced Universal Synchronous Asynchronous Receiver Transmitter )が組み込まれています。EUSARTには、同期および非同期のシリアル送受信を行う機能がありますが、ここでは、非同期の受信にかかわる機能の説明です。 非同期の受信は、RXDTピンから入力されたデータをRSR レジスタに読み込み、1ワード分の処理が終わると、受信内容を2本のFIFO(受信バッファ)に取り込みます。同時に準備ができたこと(RCIF = 1)で通知します。このとき受信インタラプト(RCIE =1)が許可されているとインタラプトが発生します。 非同期の受信に必要なシフトクロックは、システムクロックを送信と共有のBaud Rate Genaratorで分周して発生させます。非同期の受信に関連するレジスター一覧を下表に示します。

*注意*
RXDTピン(RA1)を有効にするため、該当ピンのTRISを入力「1」にセットする必要があります。さらに、アナログ入力機能を停止させるため、ANSELAの.ANSA1 をデジタルにリセット「0」 します。また、APFCON の RXDTSELビットを「1」にすると、RXDTピン割り当てを RA1 から RA5 に変更可能です。

ボーレート SYNC = 0, BRGH = 1, BRG16 = 1
4M 8M 32M
SPBRG % Error SPBRG % Error SPBRG % Error
2400 416 0.08 832 0.04 3332 0.01
9600 103 0.16 207 0.16 832 0.04
19.2K 51 0.16 103 0.16 416 -0.08

SFoscとボーレートの関連

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
INTCON GIE PEIE TMR0IE INTE IOCIE TMR0IF INTF IOCIF
PIE1 TMR1GIE ADIE RCIE TXIE SSP1IE SSP1IE TMR2IE TMR1IE
PIR1 TMR1GIF ADIF RCIF TXIF SSP1IF SSP1IF TMR2IF TMR1IF
RCSTA SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
TXSTA CSRC TX9 TXEN SYNC SENDB BRGH trMT TX9D
RCREG EUSART Receive Data Register
BAUDCON ABDOVF RCIDL - SCKP BRG16 - WUE ABDEN
SPBRGH BRG<15:8>
SPBRGL RG<7:0>
APFCON RXDTSEL SDOSEL SSSEL T1GSEL TXCKSEL P1BSEL CCP1SEL
TRISA TRISA5 TRISA4 TRISA3 TRISA2 TRISA1 TRISA0
ANSELA       ANSA4   ANSA2 ANSA1 ANSA0
レジスタ BIT 内容 1 0
INTCON 7 GIE 全インタラプトの使用許可 許可
6 PEIE 周辺機能インタラプトの使用許可 許可
PIE1 5 RCIE シリアル送信のインタラプト許可 許可
PIR1 5 RCIF シリアル送信バッファフラグ 使用中
RCSTA 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
TXSTA 4 SYNC 同期モード 同期 非同期
2 BRGH High Baud Rate選択 High Low
BAUDCON 4 SCKP 送信極性 反転出力 正論理
3 BRG16 Baud Rate Generatorのビット長 16bit 8bit
APFCON 7 RXDTSEL RX/DTの機能ピンの割当 RA5 RA1

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

非同期8ビットシリアル、パリティーなし、9600bpsで受信するプログラムを作成しました。 受信したASCII文字データにより、指定された回数LEDを点滅します。

<回路図>

<プログラム>

/*********************************************************************
 *  UARTでデータを受信する。
 *  内部クロック4Mhz   Baud Rate:9600BPS, 16-bit Baud Rate
 *  受信したシリアルデータの内容で以下の動作をする
 *     受信データ  -- LED点滅 --
 *        1       : 点滅 1 回
 *        2       : 点滅 2 回
 *        3       : 点滅 3 回
 *        4       : 点滅 4 回
 *     上記以外   : 短く点滅 2 回
 *
 *      1 VDD         8 VSS
 *   RX 2 RA5         7 RA0
 *      3 RA4         6 RA1
 *      4 MCLR        5 RA2 LED
 *
 * PIC12F1822  MPLAB X IDE with XC8 Ver1.32
 * Copyright (c) 2012 iwamoto All Rights Reserved
 * *******************************************************************/

#define LED        LATA2
#define _XTAL_FREQ 4000000          // delay_ms(x) のための定義

#include <xc.h>

//******************* コンフィグレーション ****************************
#pragma config FOSC = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = ON, CLKOUTEN = OFF, IESO = OFF, FCMEN = OFF
#pragma config WRT = OFF, PLLEN = OFF, STVREN = ON, BORV = LO, LVP = OFF

//******************* プロトタイプ *************************************
void FlashLED(char);
void ErrorInd(void);

// ******************* main ******************************************
void main() {
    char RxData;
    OSCCON = 0b01101010;                 //  内部クロック4Mhz
    PORTA  = 0x00;
    APFCONbits.RXDTSEL = 1;             //RxはRA5を使用する
    TRISA  = 0b11111011;                 //RA2:出力 他は入力
    ANSELA = 0x00;                       //すべてデジタル
    WPUA   = 0b00011111;                 // RA5以外弱プルアップ
    nWPUEN = 0;

    // UART関連レジスタ設定
    RCSTA   = 0b10010000;                // 8 bit 連続受信
    TXSTA   = 0b00000100;                // 非同期受信 High Baud Rate選択
    BAUDCON = 0b00001000;                // 16 bit SPBRG
    SPBRGH  = 0;                         // 9600bps
    SPBRGL  = 103;
    while(1){
        while (!RCIF);                   // 受信するまで待つ
        if(RCSTAbits.OERR){              // Overrunエラーなら
            RCSTAbits.CREN=0;            // エラーをクリア
            RCSTAbits.CREN=1;            // 再起動
            RxData = RCREG;              // 空読み
            continue;                    // 再受信
        }
        RxData = RCREG;                  // 受信データを取り込む
        switch(RxData){                  // データ内容が
            case '1':FlashLED(1);break;  // '1'なら点滅 1 回
            case '2':FlashLED(2);break;  // '2'なら点滅 2 回
            case '3':FlashLED(3);break;  // '3'なら点滅 3 回
            case '4':FlashLED(4);break;  // '4'なら点滅 4 回
            default :ErrorInd() ;break;  // 他は短点滅 2 回
        }
    }
}
// 指定回数 LED を点滅する *******************************************
void FlashLED(char i){
    while(i--){
        LED = 1; __delay_ms(250);
        LED = 0; __delay_ms(250);
    }
}
// エラー表示のため短く 2 回点滅 **************************************
void ErrorInd(void){
    LED = 1; __delay_ms(50);
    LED = 0; __delay_ms(50);
    LED = 1; __delay_ms(50);
    LED = 0; __delay_ms(50);
}