USART(非同期)の実験1

〔マイコンのトップに戻る〕


このページでUSART機能(非同期)に関する事を記載して行きます。
USART:Universal Synchronous Asynchronous Receiver Transmitter
USARTはPICに有る機能でシリアル通信を行う事が出来ます、これにより他のPICにArduinoや
モデム・パソコン等とデータの交換が出来る様になります。
本ページではPIC間(PIC16F628A-12F1822)の通信を記載して、次ページ以降でパソコンとの通信記事を書きます。

シリアル通信のイメージ図
イメージ図1

 シリアル通信とは1本の線で配線した伝送路上を1ビットずつ連続的にデータを送受信する通信方式です。
イメージ図の様に文字"H"を送信するとすると2進数では"01001000"です、
これを"1"ならONで"0"ならOFFの電気信号に変えて1ビットずつ送り出す訳です。

シリアル通信はRS232C・イーサネット(LAN)・USBなどの規格で利用されています、
また、PICにはUSARTの他にSPI・I2C機能もシリアル通信となります。
SPIの話はこちらを参照下さい。
I2Cの話はこちらを参照下さい。

シリアル通信の通信書式

通信書式1
送信は[スタート]+[データ]+[パリティ]+[ストップ]
の形で1バイト単位(8ビット)で送られます。
データ8ビットでノンパリティならパリティビットは無しです。
スタートビットは0(LOW:0V)です。
ストップビットは1(HIGH:5V)です。
D0が0ビット(LSB) D7が7ビット(MSB)
0ビット目から順々に送信されます。

通信書式2
この図はキャラクターの”7”で文字を送信(パリティ無)した場合です。
"7"は16進数で"37"で2進数で"00110111"です。
"00110111"をLSBから送信するので"11101100"と送られます。

通信書式3
秋月通商のLCDオシロスコープキットで通信波形を表示させて見ました。
高価なオシロスコープは持てないのでぇ、これ有るとちょっとした時に便利なんですぅ。

この写真は通信速度9600bpsで”7”を送信した時の波形です。
1bpsは1秒間に1ビットの通信速度です。
9600bpsは1秒間に9600ビット送信
なら1ビット当たり、1000000us÷9600=104.16us

また、電圧が5V出力されていないのは、PICはピンからの出力がVDD-0.7Vなのですよぉ、
で5.3V-0.7V=4.6V程が出ている分けです。



シリアル通信の接続概略図
概略図1

 マイコン同士の接続(5V電源同士)ならこの様にすぐ接続出来ますが、 パソコン等や電源電圧レベルが異なる場合は接続する時に電圧レベル合わせが必要になります。
また、シリアル通信の他の規格(RS232C等)で接続する場合は、配線が増えたりします。

PICのUSART受信概要
概要1

 PICはRXピンに入力される信号を監視しています、 入力が有れば、ボーレート(通信速度)に従い読込みを開始してPSRレジスタにデータをセットします。
で、8ビット読込み完了したらRCREGレジスタに転送して、割込みを発生させます。
また、RCREGレジスタは2個持っていて次まで受信データを溜める事が出来ます、 って事は、次の次までに受信データをRCREGレジスタから読み込まないと来たデータは捨てられるって事です。
捨てられた場合は、OERRのオーバランエラーが発生し次以降の受信が出来なくなります。  *1)

PICのUSART送信概要

概要2

 送信はTXREGレジスタにプログラムで書き込めば送信されます。
TXREGレジスタに送信データをセットすると、PICはTXIFフラグをビジー状態(0)として次にTSRレジスタ
が空であればTSRレジスタにデータを転送して、TRMTフラグをビジー状態(0)にしTXIFフラグをレディ状態(1)にします。
次にボーレート(通信速度)に従いデータを1ビットずつ出力して、完了したらTRMTフラグをレディ状態(1)にします。
ってことはぁ、TXREGレジスタに書き込む前にTXIFフラグがレディ(1)なら書き込むと処理する必要が有るって事です。

《USARTの通信テスト》

私の手持ちにUSART機能が有るPICは16F628Aと12F1822ですのでこれで行います。
16F628Aピン図1
PIC16F628Aのピン構成図です。

14番ピン(VDD)に電源5Vを接続して5番ピンにGNDを接続します。
7番ピンがRX/DTの受信を行い、
8番ピンでTX/CKの送信を行います。

尚、下図には記載有りませんが
PIC16F628Aは外部クロック20MHz
での実験となっています。

12F1822ピン図2  PIC12F1822のピン構成図です。

 1番ピン(VDD)に電源5Vを接続して
 8番ピンにGNDを接続します。
 2番と6番がRX/DTの受信ピンです。
 3番と7番がTX/CKの送信ピンです。

どのピンを使用するかプログラムで設定する必要が有ります。
今回は2番(RX/DT)と3番(TX/CK)を使用します。


配線図  この様に配線し、
 12F1822を送信側で16F628Aを受信側とします。
 12F1822からデータを1バイトずつ1秒毎に送信します。
 16F628Aはデータを受信したら1バイト毎にLCDのモニター
 に送ります。
 下の写真が別途作成したモニターです。
 モニターの作成はこちらを参照して下さい。
   モニター写真
尚、RX/DTの該当する受信ピンはデジタル入力にし、TX/CKの送信ピンは出力に設定します。
(自動で設定されるPICも有るようですが、設定した方が確実です。)  *1)

USARTに使用する設定レジスタ

USART関連の設定用レジスタとして、TXSTA,RCSTA,SPBREGの3種類のレジスタが有ります。
以下に「非同期通信(ASYNC)」の設定で説明します。

通常はこの設定でOKですよ。
 TXSTA = 0b00100100 ;   // 送信情報設定:非同期モード 8ビットデータ・ノンパリティ
 RCSTA = 0b10010000 ;   // 受信情報設定

◆TXSTAレジスタの構成
ビット
機能 CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
Bit 7:CSRC  クロックソースの選択ビット
          非同期モードはこのビット設定無意味

Bit 6:TX9   9ビットでの送信モード指定ビット
          1:9ビットデータで送信する(パリティ有りとする)
          0:8ビットデータで送信する(パリティ無しとする)

Bit 5:TXEN  送信を許可するかの指定ビット
          1:許可、送信を行う
          0:禁止、送信は行わない

Bit 4:SYNC  USARTモードの指定ビット
          1:同期モード
          0:非同期モード(通常はこの設定とする)

Bit 3:SENDB ブレーク文字送信指定ビット
          1:ブレーク文字を送信する場合にセットします。
          0:通常は0にセット
          16F628Aにはこの機能は有りません。

Bit 2:BRGH  高速ボーレートの指定ビット
          1:高速に設定(通常はこの設定でOK)
          0:低速に設定

Bit 1:TRMT  送信レジスタ(TSRレジスタ)の状態を得るビット
          1:レジスタは空です
          0:レジスタはまだ未送信

Bit 0:TX9D  9ビット目のデータ用(送信時のパリティビットデータとして使用する)

◆RCSTAレジスタの構成
ビット
機能 SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
Bit 7:SPEN  シリアルピン使用の指定ビット
          1:(RX/TX)のピンはシリアルポートとして使用する
          0:(RX/TX)のピンはI/Oポートとして使用する

Bit 6:RX9   9ビットでの受信モード指定ビット
          1:9ビットデータで受信する(パリティ有)
          0:8ビットデータで受信する(パリティ無)

Bit 5:SREN  シングル受信許可の指定ビット
          非同期モードはこのビット設定無意味

Bit 4:CREN  連続受信許可の指定ビット
          1:連続受信は許可(通常はこの設定でOK)
          0:連続受信は禁止

Bit 3:ADDEN RX9が"1"の時、アドレス検出許可ビットの指定ビット
          1:アドレス検出は許可
          0:アドレス検出は禁止、全バイトを受信(通常はこの設定でOK)

Bit 2:FERR  フレーミングエラーのステータスビット
          1:エラー有り(RCREGレジスタからデータを読出せばクリアされる)
          0:エラー無し

Bit 1:OERR  オーバーランエラーのステータスビット
          1:エラー有り(4ビット目のCRENをクリアすればOERRもクリアされる)
          0:エラー無し

Bit 0:RX9D  9ビット目のデータ用(受信時のパリティビットデータとして使用する)

◆SPBRGレジスタ
このレジスタで通信速度を決めます。
SPBRGレジスタの設定値とボーレートの関係はデータシートを参照して下さい。
PIC12F1822のデータシートはこちらの299-300ページを見て下さい。
SYNC=0、BRGH=1、BRG16=0で8MHzのクロック周波数で速度が9600ボーレートならSPBRG=51です。
PIC16F628Aのデータシートはこちらの78ページを見て下さい。
BRGH=1で20MHzのクロック周波数で速度が9600ボーレートならSPBRG=129です。

12F1822送信側のプログラム

12F1822はシリアルポートピンを下記の様にして選択します。
 RXDTSEL = 1 ; // 2番ピン(RA5)をRX受信ピンとする
 RXDTSEL = 0 ; // 6番ピン(RA1)をRX受信ピンとする
 TXCKSEL = 1 ; // 3番ピン(RA4)をTX送信ピンとする
 TXCKSEL = 0 ; // 7番ピン(RA0)をTX送信ピンとする

MPLABにてプロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。
次にコンパイルPIC書き込みを実行して下さい。
HI-TECH C Compiler for PIC10/12/16 MCUs(Lite Mode)V9.80コンパイラを使用しています。 *2)
MPLAB(R) XC8 C Compiler Version 1.00コンパイラを使用しています。
---------------------------------------------------------------------
#include <xc.h>

#define _XTAL_FREQ  8000000    // delay用(クロック8MHzで動作時)

// コンフィギュレーション1の設定
// CLKOUTピンをRA4ピンで使用する(CLKOUTEN_OFF):内部クロック使用する(INTIO)
// 外部クロック監視しない(FCMEN_OFF):外部・内部クロックの切替えでの起動はなし(IESO_OFF)
// 電源電圧降下常時監視機能ON(BOREN_ON):電源ONから64ms後にプログラムを開始する(PWRTEN_ON)
// ウオッチドッグタイマー無し(WDTE_OFF):
// 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(MCLRE_OFF)
// プログラムメモリーを保護しない(CP_OFF):データメモリーを保護しない(CPD_OFF)
__CONFIG(CLKOUTEN_OFF & FOSC_INTOSC & FCMEN_OFF & IESO_OFF & BOREN_ON &
         PWRTE_ON & WDTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF) ;
// コンフィギュレーション2の設定
// 動作クロックを32MHzでは動作させない(PLLEN_OFF)
// スタックがオーバフローやアンダーフローしたらリセットをする(STVREN_ON)
// 低電圧プログラミング機能使用しない(LVP_OFF)
// Flashメモリーを保護しない(WRT_OFF):電源電圧降下常時監視電圧(2.5V)設定(BORV_HI)
__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_HI & LVP_OFF);

// 指定した時間(num x 10ms)だけウエイトを行う処理関数
void Wait(unsigned int num)
{
     int i ;

     // numで指定した回数だけ繰り返す
     for (i=0 ; i < num ; i++) {
          __delay_ms(10) ;     // 10msプログラムの一時停止
     }
}
// メインの処理
void main()
{
     char i ;

     OSCCON = 0b01110010 ;     // 内部クロックは8MHzとする
     ANSELA = 0b00000000 ;     // アナログは使用しない(すべてデジタルI/Oに割当てる)
     TRISA  = 0b00001000 ;     // ピンは全て出力に割当てる(RA3は入力専用)
     PORTA  = 0b00000000 ;     // 出力ピンの初期化(全てLOWにする)
     // USART機能の設定を行う
     RXDTSEL = 1 ;             // 2番ピン(RA5)をRX受信ピンとする
     TXCKSEL = 1 ;             // 3番ピン(RA4)をTX送信ピンとする
     TXSTA  = 0b00100100 ;     // 送信情報設定:非同期モード 8ビット・ノンパリティ
     RCSTA  = 0b10010000 ;     // 受信情報設定
     SPBRG  = 51 ;             // ボーレートを9600(高速モード)に設定

     Wait(500) ;               // 5秒後に開始する
     i = 0x30 ;

     while(1) {
          while(TXIF==0) ;     // 送信可能になるまで待つ    *1)
          TXREG = i ;          // 送信する
          // 送信データを作成する(モニターに表示しやすい用に文字データを作成)
          i++ ;
          if (i > 0x7b) i=0x30 ;

          Wait(100) ;          // 1秒後に処理を繰り返す
     }
}
---------------------------------------------------------------------
*1) 送信可能になるまで待つ処理を変更。(連続で続けて送信する場合に不具合が有った為)

16F628A受信側のプログラム

このプログラムにはデバッグモニタープログラム「skMonitorLCD.c」「skMonitorLCD.h」が必要です。
デバッグモニターについてはこちらを参照して下さい。

尚、、LCDモニターの出力はRA1から行っているので「skMonitorLCD.h」を下記の様に変更します。
#define MONITOR_PIN RA1        // モニタ出力するピンの番号を設定する

また、CPUクロックはここでは20MHzで行っているので次の様に変更します。 *2)
#define _XTAL_FREQ 20000000  // 使用するPIC等により動作周波数値を設定する
#define BAUDRATE 129      // 9600bps(8MHz=51)(4MHz=25)(16MHz=103)(20MHz=129)

MPLABにてプロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。
次にコンパイルPIC書き込みを実行して下さい。
HI-TECH C Compiler for PIC10/12/16 MCUs(Lite Mode)V9.80コンパイラを使用しています。 *2)
MPLAB(R) XC8 C Compiler Version 1.00コンパイラを使用しています。
---------------------------------------------------------------------
#include <xc.h>
#include "skMonitorLCD.h"      // これはLCDモニター用です

#define _XTAL_FREQ  20000000   // delay用(クロック20MHzで動作時)

unsigned char RCV_Buff ;       // データ受信バッファ
int Flag ;                     // データ受信フラグ 1:受信した 0:未受信

// 低電圧プログラミング機能使用しない(LVPDIS)
// メモリを保護しない(UNPROTECT):外部リセット信号は使用せずにデジタル入力(RA5)ピンとする(MCLRDIS)
// 電源電圧降下常時監視機能ON(BOREN):電源ONから72ms後にプログラムを開始する(PWRTEN)
// ウオッチドックタイマ無し(WDTDIS):外部クロックを使用する(HS)
__CONFIG(LVPDIS & UNPROTECT & MCLRDIS & BOREN & PWRTEN & WDTDIS & HS) ;

// USART通信の受信割込み処理
void interrupt InterReceiver( void )
{
     if (RCIF == 1) {          // 割込みはUSART通信の受信か?
          RCV_Buff = RCREG ;   // レジスタからデータを受信
          Flag = 1 ;           // データを受信したぞっとぉ
          RCIF = 0 ;           // 割込み受信フラグをリセット
     }
}
// メインの処理
void main()
{
     CMCON  = 0b00000111 ;     // コンパレータは使用しない(RA0-RA4はデジタルピンで使用)
     VRCON  = 0b00000000 ;     // RA2はデジタルピンで使用
     TRISA  = 0b00100000 ;     // 1でINPUT 0でOUTPUT   RA5はINPUT Only
     TRISB  = 0b00001010 ;     // RB3/RB1(RX)はINPUT RB2(TX)とその他は全てOUTPUT
     PORTA  = 0 ;              // A出力ポートの初期化
     PORTB  = 0 ;              // B出力ポートの初期化
     // USART機能の設定を行う
     TXSTA  = 0b00100100 ;     // 送信情報設定:非同期モード 8ビット・ノンパリティ
     RCSTA  = 0b10010000 ;     // 受信情報設定
     SPBRG  = 129 ;            // ボーレートを9600(高速モード)に設定
     RCIF = 0 ;                // USART割込み受信フラグの初期化
     RCIE = 1 ;                // USART割込み受信を有効にする
     PEIE = 1 ;                // 周辺装置割込みを有効にする
     GIE  = 1 ;                // 全割込み処理を許可する
     Flag = 0 ;                // データ受信フラグのリセット

     // LCDモニターを使用する為の初期化処理 *2)
     MonitorInit() ;

     while(1) {
          // USARTからデータが送られてきたら処理する
          if (Flag == 1) {
               // モニターの表示エリアをクリアする
               MonitorPutc(0x11) ;
               MonitorPuts("        ") ;
               MonitorPutc(0x11) ;
               // モニターに受信データを送る
               MonitorPutc(RCV_Buff) ;
               // 受信データは処理したぞっとぉ
               Flag = 0 ;
          }
     }
}
---------------------------------------------------------------------
こんな感じでテストしました。
実験風景

まとめ

 16F628Aは受信したデータをモニターに出力しました、
 この時内蔵発振クロック4MHzで行った場合、モニター
 に表示されたデータが意味不明でした。
 で、外部発振子のクロック20MHzにした所正常に表示
 されたので、この写真は外部発振子が付いています。
 なのでぇ、上のプログラムは外部クロックでの記述です

 PS. *2)
 モニタープログラムをTimer2タイミングに変更している
 ので4MHzでも正常に動作する事を確認はしています。

 USARTの実験2はパソコンとの通信をと思っていますが、何時になることやら、 他のHPサイトいっぱい有るしぃ、詳しいしぃ、んん、どうしましょう。

”FT232RL使用によりUSBをシリアル変換してPICとパソコンを繋ぎます”の記事はこちらを参照。 *1)



記事見直し(*2) 2014/09/23
追記&変更(*1) 2013/01/21


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2014 Shigehiro Kimura All Rights Reserved.