【USARTとは?】
USARTとは、Universal Synchronous Asynchronous Receiver Transmitter の
略で、文字通り汎用の同期式と非同期式のシリアル送受信用の機能を持って
います。
ここでは、最も多い使い方である、非同期式(調歩同期式ともいう)での使い方
を説明します。
シリアル通信や調歩同期式の説明は、別ページを参照して下さい。
【USARTの構成】
USART機能の構成ブロックは簡単に示すと下図のようになっています。
この図のように送信と受信がそれぞれ独立しているので、全二重通信が可能
となっています。つまり、いつでも同時に送信と受信が出来るということです。
しかし、これには送受信のプログラム側も対応させなければ可能とはならず、
これを可能とするためには割込みを使う必要があります。
しかし、ここでの説明は割込みを使わず、プログラムでセンスする使い方です
ので、完全な全二重では無く、半二重通信となっています。正確にいうと、
受信は常時可能ですが、連続送信は全二重では出来ません。
【USARTの動作】
上図でUSARTの動作を説明します。
(1)送信動作
送信の場合には、まずTRMTかTXIFのステータスでレディー状態を確認し
送信ビジーでなければ、送信するデータをTXREGレジスタにプログラムで
書き込みます。(MOV命令) 直後にTXIFがビジー状態にされます。
後は自動的にデータがTXREGレジスタからTSRレジスタの転送され、
TSRレジスタからシリアルに変換されてTXピンに順序良く出力されます。
この転送直後にはTXIFがレディとなり、次のデータをTXREGレジスタに
セットすることが可能となりますが、実際に出力されるのは、前に送った
データが出力完了した後となります。
ここで、シリアルで出力する際の出力パルス幅が、SPBRGにセットされた
ボーレートを決める値に従って決定され制御されます。
シリアル出力が完了するとTRMTがレディ状態に戻り、次のデータ送信が
可能となります
(2)受信動作
受信の場合には、RXピンに入力された信号を常時監視し、受信サンプル
で、あらかじめSPBRGにセットされたボーレートに従って入力信号をサン
プリングして、まずスタートビットを検出したら、その後に続くデータをRSR
レジスタに順に詰め込んで行きます。そしてストップビットを検出したら、
RSRレジスタからRXREGレジスタに転送します。
この時点で、RCIFがレディとなり、受信データの準備が出来たことを知らせ
ます。プログラムでは、このRCIFを監視して、レディになったら、RXREG
レジスタからデータを読み込みます。
このRXREGレジスタは2階層のダブルバッファとなっているので、次の次の
データを受信完了するまでにデータを取り出せば正常に連続受信が出来る
ことになります。このダブルバッファのお陰で、受信処理の時間を楽にする
ことが出来ますが、連続受信の時には、1個のデータを受信する間に処理
を完了させることが必要です。
【関連レジスタの設定】
USARTを調歩同期で使う場合の設定は下記のようにします。
まず関連するレジスタの一覧表は下記となります。このレジスタの存在する
バンクが分かれているので注意が必要です。特に送信のTRMTステータス
はバンク1側にあるので注意が必要です。
アドレス
バンク0
バンク1
機能概要
0CH PIR1
送受信完了フラグ 18H RCSTA
TXSTA
ステータスとモード設定 19H TXREG
SPBRG送信レジスタ
ボーレート設定20H RCREG
受信レジスタ
(1) TXSTAレジスタの詳細と設定
送信の動作モードを指定するレジスタがTXSTAレジスタで、内部構造は
下図のようになっています。下図のように普通の調歩同期式の場合には、
8ビット ノンパリティ を使いますので下図のような指定とします。
さらに、プログラムセンス方式で、レディチェックをするときには、TRMT
ステータスを使うと、確実に前のデータの送信が完了してからレディと
なるので、PIR1レジスタ中のTXIFステータスを使うよりは、確実な半二重
通信とすることが出来ます。
(2) RCSTAレジスタの詳細と設定
受信の動作モードを指定するレジスタがRCSTAレジスタで、内部構成は
下図のようになっています。この設定も送信と同じように、調歩同期式の
場合には下図のような設定とします。
受信の場合のレディーチェックはPIR1レジスタ中のRCIFステータスで行い
ます。
(3) SPBRGの設定方法
通信速度を決めるのは、SPBRGレジスタによるボーレートジェネレータが
制御しています。このSPBRGレジスタへに設定する数値とボーレートの
関係は下表のようになります。但し、下表は調歩同期式の場合だけです。
同期式の場合には別の値となりますので、PICのマニュアルを参照して
下さい。
(注)エラーレイトとは、ボーレート周波数のズレの多さを%であらわしたもので
クロック
ボーレート20MHz
16MHz
10MHz
SPBRG
設定値エラー
レイトSPBRG
設定値エラー
レイトSPBRG
設定値エラー
レイト1200
255
1.73
207
0.16
129
0.16
2400
129
0.16
103
0.16
64
0.16
9600
32
-1.36
25
0.16
15
1.73
19.2K
15
1.73
12
0.16
7
1.73
76.8K
3
1.73
----
----
1
1.73
1フレーム内でのズレになりますが、10ビット(スタートストップ合わせて)
のフレームでのエラーマージンは、1/2ビット幅までのズレを許容すると
すれば、50%/10=5%となります。
【USARTの使用例】
実際にUSARTを使った例を説明します。ここでは、パソコンのRS232Cのシリアル
インターフェースとの接続を例にして具体的な使い方を説明します。
まず、このためのPIC側の回路図は下図のようにします。ここでは、必要な部分
のみ示しています。使ったPICはPIC16C73/JPです。
RS232Cのインターフェースに合わせるためのレベル変換には、有名なMAX232
というICを使っています。これには最近は各社から同様な機能のICが発売されて
いるので、どれでもOKです。 パソコン側はDOS/V機であれば、COM2ポートに接続
します。
【プログラム例】
上記回路図で実際の通信をテストするためのプログラム例を説明します。
今回テストに使用したプログラムは、下記のような機能をもっています。
・通信速度は19.2Kbpsとし、8ビット ノンパリティの調歩同期式とする。
・パソコンからのデータ受信を常時監視し、データを受信したらデータメモリ
のバンク1側の96バイトの領域に格納する。
・受信したデータがCRコード(0D)であったら、その時点でデータメモリに格納
していたデータを順次パソコン側に送信する。
・受信データを格納する時点で96バイトを超えたときには、その時点での
データメモリの96バイトの内容を全てパソコンへ送信する。
・データ送信の最後には、常に”End of TX”という固定メッセージを付加して
送信する。
★USARTテストプログラムソースファイル
本プログラム例では、通信処理を行うときのバッファの処理の扱い方も例と
して入れてあります。
・データメモリエリアに格納していく方法
・固定フォーマットのデータを送信する方法
の2種類を例としてあります。
;*********************************************
;
; USART test program using USART module.
; Test condition is below
; Mode : Asyncronous transfer mode only
; Speed: 1200,2400,9600,19Kbps switchable
; Bit : startx1 datax8 stopx1
; Not use interrupt
;
;*********************************************
;
LIST P=PIC16C73A
INCLUDE "P16C73A.INC"
;***********************************
; 変数定義
; バンク1の全部(96バイト)を送受信
; バッファとして使います。
;***********************************
TEMP EQU 020H ;work area
POINT EQU 021H ;pointer of table
BUFFER EQU 020H ;buffer
ORG 0
;***********************************
; 送受信モードの初期化
; バンクの位置に注意
; Baud rate setting is below
; Clock 10MHz 20MHz
; Baud SPBRG SPBRG
; 1200 81H FFH
; 2400 40H 81H
; 9600 0FH 20H
; 19K 07H 0FH
;***********************************
INIT
BSF STATUS,RP0 ;バンク1に切替
MOVLW 081H ;set portc
MOVWF TRISC ;PORTC
;
MOVLW 020H ;Set Async mode
MOVWF TXSTA ;Set TX mode
MOVLW 07H ;Set Baud Rate 19Kbps
MOVWF SPBRG ;Set BRG
BCF STATUS,RP0 ;バンク0に戻す
MOVLW 090H ;Set Async mode
MOVWF RCSTA ;Set RX mode
;****************************************
; Main routine
; データを受信しバッファに格納する。
; もしデータがCRだったらそれまでのデータを
; 送信出力する。
; またバッファが一杯になった時も送信する。
;****************************************
MAIN
;****** Wait Receive data ******
MOVLW 0A0H ;set buffer top address
MOVWF FSR ;間接アドレスポインタ初期化
LPRCV
BCF PORTC,5 ;LED on
;
BTFSS PIR1,RCIF ;check receive end flag
GOTO LPRCV
;
BSF PORTC,5 ;LED off
;**** error check ****
BTFSC RCSTA,FERR ;framing error check
GOTO FRAME
BTFSC RCSTA,OERR ;overrun error
GOTO OVER
;***** get data and save *****
;** 間接アドレッシングでバッファに格納する ***
MOVF RCREG,W ;get received data
MOVWF INDF ;save in buffer
SUBLW 0DH ;CR code?
BTFSC STATUS,Z ;data=CR?
GOTO SEND ;to transfer
;**** if buffer full then end *****
CHKBF
INCF FSR,F ;pointer+1
BTFSS STATUS,Z ;buffer full?
GOTO LPRCV
GOTO SEND ;full then end
;******** ERROR PROCES ******
;**** framing error
FRAME
MOVF RCREG,W ;dumy input & reset FERR
MOVLW '?'
MOVWF INDF ;save ?
BTFSS RCSTA,OERR ;check more error?
GOTO CHKBF ;to next
;***** overrun error
OVER
BCF RCSTA,CREN ;reset OERR
BSF RCSTA,CREN
MOVLW '?'
MOVWF INDF ;save ?
GOTO CHKBF ;to next
;*************************
;****** Send answer ******
SEND
MOVLW 0A0H ;reset pointer
MOVWF FSR
LPSD
BCF PORTC,5 ;LED on
MOVF INDF,W ;get data
CALL TX ;send execute
BSF PORTC,5 ;LED off
MOVF INDF,W ;re-get data
SUBLW 0DH ;CR?
BTFSC STATUS,Z ;end check
GOTO TEXT ;end text send
;**** if buffer end then end *****
INCF FSR,F ;pointer+1
BTFSS STATUS,Z ;buffer end?
GOTO LPSD ;loop
GOTO TEXT ;end
;************ text send process *****
;** 固定データの送信例 ****
TEXT
CLRF POINT ;reset table pointer
LPTEX
MOVF POINT,W ;get pointer offset
ANDLW 0FH ;limit upper
CALL TABLE ;get text data
ADDLW 0 ;test zero?
BTFSC STATUS,Z ;end zero?
GOTO MAIN
CALL TX ;send
INCF POINT,F ;pointer+1
GOTO LPTEX
;***** text data table *****
;** RETLW命令でテーブルを作成 ****
TABLE
ADDWF PCL,F ;PC+offset
DT "End of TX",0,0,0,0,0,0,0,0
;**************************************
; Transmit subroutine
; レディチェックは送信レジスタ空で確認
; つまり、TRMT=1でレディと判定
; TXSTAのあるバンクに注意
;**************************************
TX
MOVWF TEMP ;data save
BSF STATUS,RP0 ;switch to Bank1
LPTX
BTFSS TXSTA,TRMT ;ready check
GOTO LPTX
;
BCF STATUS,RP0 ;return to Bank0
MOVF TEMP,W ;get data
MOVWF TXREG ;start send
RETURN
END