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

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

12F1822 には、シリアル通信を行うための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」と送信します。非同期の送信に関連するレジスター一覧を下表に示します。

*注意*
APFCON のTXCKSELビットを「1」にすると、TXCKピン割り当てを RA0 から RA4 に変更可能です。

ボーレート 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
TXREG EUSART Transmit 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
レジスタ BIT 内容 1 0
INTCON 7 GIE 全インタラプトの使用許可 許可
6 PEIE 周辺機能インタラプトの使用許可 許可
PIE1 4 TXIE シリアル送信のインタラプト許可 許可
PIR1 4 TXIF シリアル送信バッファフラグ 使用中
ADCON0 0 ADON ADモジュール On/Off ON OFF
RCSTA 7 SPEN 出力ピンのシリアル設定 ON OFF
TXSTA 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
BAUDCON 4 SCKP 送信極性 反転出力 正論理
3 BRG16 Baud Rate Generatorのビット長 16bit 8bit
APFCON 2 TXCKSEL TX/CK機能のピン割り当て RA4 RA0

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

RA5に続されたPushSWを押すと「Hello OK>」を送信、 その後、押すたびに 1234・・・と9600ボーのシリアル送信をするプログラムです。送信に printf を使用しています。
<回路図>

<プログラム>

/*********************************************************************
//  UARTでデータを送信する。
//  SWを押すと開始メッセージ。その後 SWを押すたびに、カウントUP
//         4MHz (内部クロック)
//
 *      1 VDD         8 VSS
 *   SW 2 RA5         7 RA0 TX
 *      3 RA4         6 RA1
 *      4 MCLR        5 RA2
 *
 * PIC12F1822  MPLAB X IDE with XC8 Ver1.32
 * Copyright (c) 2012 iwamoto All Rights Reserved
 * *******************************************************************/
#define pushSW     RA5
#define _XTAL_FREQ 4000000          // delay_ms(x) のための定義

#include <xc.h>
#include <stdio.h>
#include <stdlib.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

// ================= printf関数を使用するための定義 =================
void putch(unsigned char ch) {
    while (!TXIF);               //送信終了待ち
        TXREG = ch;
}

// ******************* main ******************************************
void main() {
    char num = 0;              //

    OSCCON = 0b01101010;       //  内部クロック4Mhz
    PORTA  = 0x00;
    TRISA  = 0b11111111;       //Port すべて入力
    ANSELA = 0x00;             //すべてデジタル
    WPUA   = 0b00100000;       // RA3 弱プルアップ ON
    nWPUEN = 0;

//------------ Initialize UART ---------------------------------------
    RCSTA   = 0b10000000;      // 非同期送信 9600baud
    TXSTA   = 0b00100100;
    BAUDCON = 0b00001000;
    SPBRGH  = 0;
    SPBRG   = 103;

    while(pushSW);             // SWが押されるのを待つ
    printf("¥x01");            // 画面クリア
    printf("Hello OK");        // 開始のメッセージ

    // ----------- 繰返し --------------------------------------------
    while(1){
        while(!pushSW);        // SWが離れるのを待つ
        __delay_ms(10);        // 10mS遅延
        while(pushSW);         // SWが押されるのを待つ
        __delay_ms(10);        // 10mS遅延
        printf("¥x03");        // 下段先頭にカーソル
        printf("%d",num++);    // 0123・・・と送信
    }
}