山本ワールド
PIC18F46K22 EUSART1(RS232C)で受信割込みを使用してパリティ付き受信(アセンブラプログラム)
概要
PIC18F46K22のEUSARTモジュールを使用しRS232Cを経由してパソコンと通信するプログラムである。
パソコンからターミナルで文字列を入力するとPICで受信してパリティーの結果をRed LEDに表示する。偶数パリティーでない場合はRed LEDが点灯する。文字を受信するたびにBlue LEDが点滅する。
パソコン側のターミナルソフトはTera Termを使用し、偶数・奇数それぞれのパリティを設定して動作確認をしました。本プログラムは偶数パリティーを対象としていますのでパソコン側を奇数に設定すると1文字送信するたびにRed Ledが点灯状態となります。
秋月電子 PIC18F46K22使用 マイコンボードをベースとし半田付けされている水晶20MHzをH8/3048ボードの16MHzと交換し64MHzで動作可能とした。このボードはICSP端子を備えておりPICKIT 3で書き込みができ、電源はミニUSBで供給可能である。またユニバーサル基板になっているので簡単に回路を追加することができる。
ちなみに水晶が20MHzの場合は、通信速度がかわるので設定を変更しなければならない。
EUSARTの設定値の計算はPIC18 EUSART ボーレート計算を参照してください。
使用メモリは以下のとおりです
プログラムメモリ 184byte使用
回路は次のとおりである。
回路図(PDF)
例えば9600bpsで割り込みを使用しない場合、1文字の受信に1ms近く受信が完了することを示すフラグをチェックし続けなければなりません。
割込みを使用すると受信後の割込みにより受信完了を知ることができますので、他の処理と同時に処理をすることができます。
通信設定
プログラムの説明
初期化
EUSART1の初期化し通信仕様を設定します。ボーレートの設定はBPS1という定数を設定することによりビルド時に自動的に計算して各種レジスタを設定するようにしてみました。
1byte分のデーターを受信するとRCREG1レジスタに受信データーが格納されます。その時、受信データがあることを知らせる割り込みをRC1IEビットで許可します。
上記の割り込みは周辺の割り込みですので有効にするためにPEIEビットをセットします。
割り込みは高位と低位の2種類使用できます。初期値は高位になっていますのでそのままとします。
高位割り込みを許可するためにGIEビットをセットします。
割り込み発生時のジャンプ先は、割込みベクターでROMアドレスに高位が0008h、低位が0018hにジャンプします。通常は、このアドレスにgoto命令を記述して割り込み処理ルーチンへジャンプさせます。
受信データが発生するまで無限ループで待機します。
高位割り込み処理ルーチン inth
受信データが1byte発生するとinthにジャンプします。高位割り込みの場合、Wレジスタ、バンクレジスタ及びPCの値はPIC内の専用レジスタに保存されます。割り込みから復帰する場合は、retfie FAST命令を使用して保存された値によりWレジスタ、バンクレジスタ、PCを復帰します。
複数の割り込み要因を許可していないので、割り込み要因をボーリングする作業をしておりません。
サブルーチンusart1_readにより受信データーをWレジスタに取得し、サブルーチンusart1_writeにより送信します。
usart1p_read
受信データを1byte取得しWレジスタに格納します。パリティーをチェックしRed Ledに結果を反映させます。
受信データーが発生するとRC1IFフラグがセットされますので、セットされるまでボーリングします。
受信データはRCREG1レジスタに格納されているのでWレジスタにコピーします。 スタック上に受信データをプッシュします。
サブルーチンparity2cで受信データのパリティーを計算します。結果はCフラグに反映されます。Cフラグがセット(1)されている場合は受信データの1のビット数が奇数、Cフラグがクリア(0)されている場合は偶数を示します。
キャリーフラグの値に応じてWレジスタを0x00または0xffをセットします。
RCSTA1のRX9Dビットが受信のパリティーの値を示します。
WレジスタとRCSTA1とで排他的論理和(xor)をとりWレジスタに保存します。
排他的論理和は2つの値の同じビット位置の値が同じ場合は0、異なる場合は1が同一ビット位置にセットされます。
RCSTA1の受信のパリティーの値を示すRX9Dの位置でWレジスタのビット値を検査し1の場合はパリティーが一致しないのでRed Ledを点灯させます。
スタックから受信データをポップしてWレジスタにコピーしサブルーチンを終了します。
本サブルーチンは偶数パリティーと見なしてチェックをしております。奇数パリティーにしたい場合は、btfsc STATUS,Cをbtfss STATUS,Cに置き換えると奇数パリティーでない場合にRed Ledを点灯させることができます。
parity2c
PIC18のステーラスレジスターにはパリティーを示すフラグがありません。ちなみにZ80等には存在します。Wレジスタの1のビット数を数え偶数の場合はCフラグを0、奇数の場合は1をセットします。
ビット数を数えるには1ビットずつシフト命令を使用してシフトさせキャリーフラグのチェックを8回か繰り返す方法が一番簡単かと思います。
ここでは、先に上位4bitと下位4bitの排他的論理和をとります。 その後はその結果と右シフトした結果とを排他的論理和をとります。 もう一度、結果と右シフトした結果とを排他的論理和をとると全ビットのパリティーが0ビット目に反映されます。さらに右シフトすると0ビット目がCフラグに反映されます。
計算過程については、PIC18の標準命令セットを参照願います。
ソースファイル
以下のファイルで構成されているeusart4a.asm ・・・ メインプログラム
ソースファイルのダウンロード eusart4ap.zip
; EUSART1受信割り込みによるパリティ付き受信テスト(高位レベル割り込み使用) 2017/08/23 21:00 動作確認
; 慈渓博瑞テクノロジー株式会社 PIC18F46K22 マイコンキット Ver2013.12.08用
; http://akizukidenshi.com/catalog/g/gK-07231/
; 水晶は16MHzに交換してPICを64MHzで駆動
; 19200bps
; ストップビット 1bit
; パリティ 偶数
; ストップ 1bit
; フロー制御 無
; MPLAB X IDE v3.45 Microchip MPASM(v5.70)
; PicKit 3
; RC6:TX1 RS232C
; RC7:RX1 RS232C
; RC2:Blue LED 1文字受信するたびにLEDの点灯状態が反転
; RE2:Red LED パリティエラーが発生すると点灯(初期時は点灯 文字受信後動作)
#INCLUDE <p18f46k22.inc>
; 水晶発振(16MHz) クロック分周無 PLL有効(*4) プライマリクロック有効 ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
CONFIG FOSC = HSHP,PLLCFG=ON,PRICLKEN=ON,WDTEN=OFF,LVP=OFF
STACK_MAX EQU d'32'
bank1 IDATA 060h
stack1 RES STACK_MAX ; スタックエリア
CODE
ORG 0
goto start ; リセット時
org 08h
goto inth ; 高位レベル割り込み
start
BANKSEL ANSELC
lfsr 2,stack1+(STACK_MAX-1)
; USART初期化 300bps?115.2kbps (Xtal 16MHz PLL *4)
FOSC1 EQU d'64000000' ; クロック周波数 Hz
BPS1 EQU d'19200' ; ボーレート設定
SPBRGW1 EQU (FOSC1/(d'16'*BPS1)-1)
bsf BAUDCON1,BRG16 ; BRH16=1
; movlw b'10010000' ; シリアル 8bit
movlw b'11010000' ;TX9=1:9bit
movwf RCSTA1
movlw LOW SPBRGW1
movwf SPBRG1
movlw HIGH SPBRGW1
movwf SPBRGH1
movlw b'00111111'
movwf ANSELC,BANKED
movlw b'11111011' ; RC2をOUT
movwf TRISC
movlw b'00000000' ; RC2=offを出力
movwf PORTC
movlw b'11111011'
movwf ANSELE,BANKED
movlw b'11111011' ; RE2をOUT
movwf TRISE
movlw b'00000000' ; RE2=offを出力
movwf PORTE
bsf LATC,2
bsf LATE,2
bsf PIE1,RC1IE ; 受信割り込み許可
bsf INTCON,PEIE
bsf INTCON,GIE ; 高位レベル割り込み許可
goto $
inth ; 高位割り込み
call usart1p_read
retfie FAST
usart1p_read ; USART1から読み取り
btfss PIR1,RC1IF ; 受信完了
bra usart1p_read
btfsc RCSTA1,FERR ; フレミングエラーがない場合次の命令をスキップ
bra usart1p_ferr
btfsc RCSTA1,OERR ; オーバーランエラーがない場合次の命令をスキップ
bra usart1p_oerr
movf RCREG1,W
movwf POSTDEC2
btg LATC,2
call parity2c ; WREGのパリティチェック キャリーに反映
clrf WREG
btfsc STATUS,C ; 偶数:btfsc STATUS,C 奇数:btfss STATUS,C
comf WREG
xorwf RCSTA1,WREG
bcf LATE,2
btfsc WREG,RX9D
bsf LATE,2 ; パリティが一致しない場合実行(Red LED点灯)
movf PREINC2,w
return
usart1p_ferr ; フレミングエラーが発生
usart1p_oerr ; オーバーフローエラーが発生
return
; パリティ計算をし結果をcに保存 偶数パリティ
; WREG:引数
; FSR2:スタック 最大1byte消費
parity2c
movwf POSTDEC2
swapf WREG
xorwf PREINC2,W
movwf POSTDEC2
rrcf WREG
xorwf PREINC2,W
movwf POSTDEC2
rrcf WREG
rrcf WREG
xorwf PREINC2,W
rrcf WREG
return
END