Old PIC(Home) > ソフトウェア資料編 Soft-UART | |
ソフトウェア資料編 Soft-UART (Old PIC) |
RXData (PC → PIC) |
(1)2V/dev 1.00div |
|
|
TXData (PC ← PIC) |
(2)2V/dev -3.00div |
100kS/s 5ms/dev |
Soft-UART(emulate型) 全二重通信可能、割込みの無い機種(10F222)でも使えます |
ここでは全て、アセンブラによるプログラミング例を掲載しています
こだわっている訳では有りません ただ不勉強なだけです (^_^;
強いて理由を挙げるなら PICの小さな機種では機能もシンプルですし
コンパイラよりアセンブラの方がプログラム容量が小さくなるから!
|
|
始めに | エミュレート型の Soft-UART の利点と欠点 | |
| | | |
Soft-UART とは? |
|
ある程度の規模の PICでは、ハードウェアの UARTを搭載しています
しかし、低機能や極小規模な機種の PICでは UARTを搭載していません
それでもパソコンと通信できたらとても便利です
UARTを搭載していても、もう1本 UARTが必要な時もあります
(UARTを2本以上搭載している機種もありますが)
そこで、ソフトウェアで UARTの機能を実現する方法 に付いて紹介します
|
一般に行なわれている方法
参考サイト(picfun.com) |
|
| |
スタートビットの立下がりエッジを捉える | カウンタの割込みを使う |
3/2ビット、1ビットの時間を作る | タイマーの割込みを使う |
利点 | 制約 |
通信速度が速くできる(9600bps位まで) |
スタートビット検出にカウンタ割込を
使用するので RXがRA3に固定される
タイマが占有される(時計などに使えない)
半二重通信のみ (全二重通信は出来ない) |
|
エミュレータ型 ここでは、ハードウェアUART をエミュレートする Soft-UART を紹介します |
|
| |
ハードウェアUART ではビット長の 1/16 or 1/64 間隔で監視しますが、
エミュレータ型ではそれ程高速に出来ませんのでビット長の 1/8 とします |
スタートビットの立下がりエッジを捉える | 1/8 ビット間隔で監視する |
1/2ビット、1ビットの時間を作る | 1/8 ビット周期のクロックを計数する |
利点 | 制約 |
全二重通信ができる
タイマを通信と時計に共用できる
ポートの設定が自由にできる |
通信速度が速くできない
2400bps(8MHz)、4800bps(16MHz) 位まで |
「1/8ビット周期」を作るには、タイマー割込みを使うのが有利ですが
割込みが無い機種(PIC10F222等)でもタイマーだけで作る事ができます
全二重通信や平行処理に付いては別項(未完成)で紹介します
|
| | | |
CPUクロックと割込周期・通信速度 の関係 |
|
割込周期内に Soft-UARTをエミュレートするドライバ部を実行しなければならないため
CPUクロックの値によって通信速度の上限が制約されます
割込周期として、約100命令位を実行する時間が必要です
上記説明では「1/8ビット周期」としていますが、1/4〜1/255 の範囲で設定できます
下表の割込周期は CPUクロック毎に(約100命令実行するために)最小限必要な時間です
CPU クロック |
割込周期 |
1ビットの分割数 |
4 |
8 |
16 |
32 |
64 |
128 |
255 |
| | | | | | | | |
32MHz | 13μs |
19230bps |
9615bps |
4807bps |
2403bps |
1201bps |
600bps |
301bps |
16MHz | 26μs |
9615bps |
4807bps |
2403bps |
1201bps |
600bps |
300bps |
|
8MHz | 52μs |
4807bps |
2403bps |
1201bps |
600bps |
300bps |
| |
4MHz | 104μs |
2403bps |
1201bps |
600bps |
300bps |
| | |
「1ビットの分割数」は スタートビットの立下がりエッジを捉える ために重要な値です
「4」 でも 自クロックや通信相手の通信速度が正確なら通信可能ですが
より安定して確実に通信するためには「8」以上にすると良いでしょう
|
| | | |
規格:調歩同期
(シリアル通信)
参考サイト(picfun.com)
|
|
RS-232C の
シリアルポート
(昔のパソコンでは標準装備)と通信するための規格です
UART (Universal Synchronous Asynchronous Receiver/Transmitter) を介して接続します
現在のパソコンでは USBポートに「USB-シリアルユニット」を介して接続して
専用のドライバーソフトの働きでシリアルポートに接続したのと同様に通信できます
|
|
仕様 |
|
項目 | 仕様値 | 備考 |
通信方式 | 調歩同期(非同期) | Start:1, Data:8, Stop:1 (bit) |
通信速度(CPUクロック) | 1200bps 2400bps(16MHz) | 割込周期:104μS(8MHz) 割込周期:52μS(16MHz) |
PIC 使用ポート | 制限無し | ピンの少ない PICでは入力専用ポートを RXに割り当てると有利です |
以下では、
低スペックの下位機種を想定して「割込周期:104μS(8MHz)」の場合を説明しています
通信速度は、「割込周期」と「1ビットの分割数」で決まりますので
前節の表 の様に、目的により「割込周期」と「1ビットの分割数」を組み合わせます
|
概要(条件、制約) | タイマ、データメモリ、プログラムメモリ | |
| | | | |
条件 | |
| プログラムメモリ | 110 Word (初期化:10、RX:46、TX:37、INT:11) ※割込みを使う場合 |
| | 93 Word (初期化:22、RX:37、TX:34) ※割込みを使わない場合 |
| データメモリ | 8 Byte |
| タイマー(8bit) | TMR0 |
| I/O ポート | RX(IN:1)、TX(OUT:1) 割当ポートの制約無し |
|
制約 | |
| 割込が無い機種 | TMR0 の値を監視して一定時間を作る(PIC10F222など) |
| | メイン処理を、一定時間の繰り返しの中で行なうために、工夫が必要 |
| 割込が有る機種 | TMR0 割込みを使って一定時間を作る(PIC10F222以外ほとんどの機種) |
| | TMR0 をカウンタに使用したい場合は工夫が必要 |
ソフトの基本構造 | 一定間隔の時間(104μS)を作る |
| | | |
104μS にする理由 (104(μS)が正確なら、ビットレート誤差 +0.16%、時計誤差 -0.16%) |
(1) | シリアル通信の基準クロックとする |
|
クロックは通信ビットレートの 1/(2のべき乗) にします
通信ビットレートの時間とその 1/2の時間を作り易いからです(8以上にする理由はこちら)
例えば 1200bps の 1bit の時間は 1(sec)/1200(bps)≒833(μS)
クロックは 833(μS)/8≒104(μS)
|
(2) | 内部時計のクロックとする |
|
20mS と 1Sec (必要なら 1分、1時間も)を作る
104(μS)*192=19968(μS)≒20(mS) (接点入力時のチャター回避用)
104(μS)*192*50=998400(μS)≒1(Sec) (LED点滅用など)
|
|
タイマ割込で 104μSを作る場合 |
(1) | 処理のイメージ TMR0のプリセット値は |
|
PreSet=256-(T*F/P)+O
57=256-(104*2/1)+9
F:2MHz (CPUクロック/4)
T:104uS (目的の時間)
P:1 (プリスケーラ分周比)
O:9 (割込オーバーヘッド)
|
(2) | 概略の処理フロー |
|
; (割込みの初期化は別途事前にしておきます)
; (レジスタ類の退避:不要の機種もある)
; 割込要因解析 タイマーか?
; 次の割込のためにタイマをセットする(104μS)
; UART 処理
; その他の処理(時計など)
; (レジスタ類の復帰:不要の機種もある)
; 割込みから戻る
|
(3) | 割込み処理の制約 (上記の「割込み処理」部) |
| 「その他処理」を含めて、割込み時間を 104μS以内に収める必要が有ります
割込み処理が多くて 104μS以内に終わらない場合は、割込み内で処理せず
フラグを立てるだけにして、処理はフォアグランドで行う様にします
|
|
タイマだけで 104μSを作る場合(割込みが使えない機種:PIC10F222等) |
(1) | 処理のイメージ |
| |
|
(2) | 概略の処理フロー |
|
; タイマーをゼロにセットする
; 必要な処理を行う
; 104μS以内に処理が終わる様にする
; タイマー値が 200(104μS)になったかチェックする
; 200(104μS)になるまで [タイマーチェック] を繰り返す
; 200(104μS)になったら [TMR0=0] へ、ループする
|
|
(3) | メイン処理の制約 (上記の「その他処理」部) |
| ループ時間を確保するため、長時間の処理や時間待ち等は出来ません
時間に関わる処理は、ループ時間(104μS)をカウントして行う必要が有ります
ループ時間内で終わらない処理は、途中の状態や結果をフラグや変数に保存して進めます
|
|
| | | |
|
シリアル通信のフォーマット なぜ 1/8 (104μS) 毎 か? |
(1) | RS-232C信号と TTL信号 (タイミングは同じで極性と電圧が異なる) |
| |
|
| (上図下段の)TTL(正論理)信号では、 |
| |
信号が無い時は +5V です
一般に 1BYTE を送信する場合、
先頭に信号の始まりを示す「スタートビット:0V」を 1ビット(図の S)
データの LSB(bit0) から MSB(bit7)の順に「データ:0V/+5V」を 8ビット
最後に信号の終わりを示す「ストップビット:+5V」を 1ビット(図の P)
の順に送ります
|
| 通信速度 |
| |
RS-232Cの規格の基本は最大通信速度 20kbps 最大通信距離 20mとなっています
| |
300 bps | |
600 bps | |
1200 bps | この(エミュレータ式)ソフト-UARTで通信可能な最高の通信速度 |
| CPUクロック:8MHzでは、これ以上の通信速度にできない |
|
|
|
(2) | スタートビットの立下がりエッジを捉える |
| |
調歩同期式シリアル通信では信号を捉えるために一番重要なポイントはスタートビットの
立下がりのエッジです このエッジで1文字を取り込むタイミングが決まります
この信号のエッジを捉えるには、次の方法が有ります
(a)常時監視する方法 (ハードウェア)UART、エミュレート式のソフトUART
(b)割込みで検出する方法 一般のソフトUART(カウンタの割込機能を使用)
ここではカウンタの割込機能を使わずに、常時監視する方法で行います
常時監視すると言っても、監視に専念していては他の機能(タスク)を実行できません
そこで、出来る限り 短い周期(104μS)で一瞬監視 する方法を、他の機能(タスク)と
同時平行処理的に実行します
下図は、監視周期を通信ビットレートの 1/8 として「立下がりエッジ」を監視する様子です
「ケース1」は最も早く、「ケース2」は最も遅く「立下がりエッジ」を検知した場合です
同様に「ケース3、4」は、監視周期を通信ビットレートの 1/4 とした場合です
|
| | |
|
|
(3) | シリアル−パラレル変換 |
| |
上向きの矢印のポイントでシリアル信号をサンプリングします
立下がりエッジ を検知してから 4×監視周期後に(スタートビットの中央で)
Loレベルを確認します(Hiの場合はノイズとして無視、スタートビットの監視状態に戻る)
その後、8×監視周期毎に bit0 から bit7 まで順番に 1BYTE分を取り込み、
最後にストップビットの Hiを確認します(Loの場合はフレーミングエラーとする)
同様に「ケース3、ケース4」は、監視周期を通信ビットレートの 1/4 とした場合です
監視周期が長くなるとスタートビットの正確なタイミングが得られず
データ取込タイミングが、各ビットの中央からずれてしまいます
CPUクロックの誤差や変動などで、データ取込タイミングが前後のビットまでずれると
データ化けやフレーミングエラーになってしまいます
|
|
実験の結果
安定して通信できる監視周期は、通信ビットレートの 1/8 以下ですが、クロックが正確なら
監視周期を 通信ビットレートの 1/4 にしても安定して通信できる事を確認しました
ちなみに (ハードウェア)UARTでは、監視周期として通信ビットレートの
1/16 or 1/64 のクロックを UART のユニットに与えるのが一般的です
(MC6803内臓UARTの様に 1/8 のクロックを与えるものも有ります)
|
| |
通信ビットレートの 1/16 又は 1/64 周期のクロックを UART のユニットに与えています
|
| | | |
(1) | UART処理で使用するフラグとワーク |
| |
104μS毎の繰返しの 分断した短い時間 で処理を進めるには、現在の処理がどこまで
進んでいるかを保持するために フラグ(1bit) と カウンタ(1BYTE) を使います
ここで使っている フラグ(1bit) (状態を保持)
RXBUSY: RX Busy flag(受信処理中)
RXBFUL: RX Buffer Full flag(受信完了)
RXOVFE: RX Over run or RX Frameing Error flag(受信エラー)
TXBUSY: TX Busy flag(送信処理中)
TXDNST: TX Done/Start flag(送信完了/送信開始指示)
カウンタ(1BYTE)(処理回数を格納)
WRXCC_: RX clk count(受信クロックカウンタ)
WRXBC_: RX bit count(受信ビットカウンタ)
WTXCC_: TX clk count(送信クロックカウンタ)
WTXBC_: TX bit count(送信ビットカウンタ)
バッファ(1BYTE)(データを格納)、ワーク(1BYTE)(処理途中のデータを格納)
WRXDT_: RX data work(受信ワーク)
WRXDTB: RX data buffer(受信バッファ)
WTXDTB: TX data buffer(送信バッファ)
|
| | | |
(2) | 受信処理概略フロー |
| |
受信[104μS毎の繰返し処理]
「受信処理中」の場合は「1ビット取込」処理へ
そうでなければ、スタートビットをチェックする
スタートビットが検出されたら
「スタートビット処理」へ
|
| |
受信[スタートビット処理]
受信完了している場合は オーバーランエラーとする
エラーでも次の文字の取込を開始する
ワークやフラグを初期化する
スタートビットの中央でサンプルするため
クロックカウンタをビットタイムの半分にセットする
受信処理中フラグをセットする
|
| |
[ビット取り込み処理]
クロックカウンタをデクリメントする
クロックカウンタが 0でなければ何もしない
クロックカウンタが 0の時、
次のクロックカウンタ値をセットする
ビットカウンタが 9の時、「1文字取込処理」へ
ビットカウンタが 8以下の時、「1ビット取込」処理
|
| |
[1ビット取込]
「RXポート」をチェックする
Hiの時、キャリーを「1」にする
Loの時、キャリーを「0」にする
右シフトしてキャリーを
受信データワークの MSBに取り込む
|
| |
[1文字取り込み処理]
受信ワークから受信バッファへデータをコピーする
ストップビットをチェックし
Lo の時、フレーミングエラーとする
受信バッファフル・フラグをセットする
受信処理中フラグをリセットする
|
| | | |
(3) | 送信処理概略フロー |
| |
送信[104μS毎の繰返し処理]
「送信完了」の場合は次の処理へ
そうでなければ「送信処理中」かをチェックする
「送信処理中」でなければ
「スタートビット処理」へ
「送信処理中」なら「ビット送出処理」へ
|
| |
送信[スタートビットの処理]
クロックカウンタをセットする
「送信処理中」フラグをセットする
ビットカウンタをクリアする
スタートビットを送出する
ビットカウンタをインクリメントする
|
| |
[ビット送出処理]
クロックカウンタをデクリメントする
クロックカウンタが 0でなければ何もしない
クロックカウンタが 0の時、
次のクロックカウンタ値をセットする
ビットカウンタが 10の時、1文字送出完了処理へ
ビットカウンタが 9の時、ストップビットを送出
ビットカウンタが 8以下の時、1ビット送出処理へ
ビットカウンタをインクリメントする
|
| |
[1ビット送出]
C=1 (MSBからストップビットを入れておく)
「送信データ」を右シフトして LSBをキャリーへ
キャリーが「1」ならHiを送出
キャリーが「0」ならLoを送出
|
| |
[1文字送出完了処理]
Hiレベルを送出する
送信完了フラグをセットする
送信処理中フラグをリセットする
|
| | | |
(1) | タイマ割込によるプログラムリスト例 割込の使える機種(PIC10F222 以外) |
|
| 初期化処理部(タイマ割込) |
|
|
;===============================================================
; Subroutine: INIT Initialize
;===============================================================
; Preset Value
;===============================================================
; ;INTCON Initialize
S_INTC EQU B'10100000' ;TMR0 Onry
; |||||||+------ GPIF
; ||||||+------- INTF
; |||||+-------- T0IF TMR0 Over Flow Flag
; ||||+--------- GPIE 0:Disable
; |||+---------- INTE 0;Enable
; ||+----------- T0IE 1:Enable
; |+------------ PEIE 0:Disable
; +------------- GIE 1:Enable
;---------------------------------------------------------------
;TMR0 Pre Set Value 256-(T*F/P)=ccc F:4MHz, P:2, T:416uS
;S_TMR0 EQU 53 ;0x35 実験値(OK範囲:28〜35〜3C)
;---------------------------------------------------------------
; ;TMR0/WDT Control
;S_OPTF EQU B'00000000' ;Pre Scaler=TMR0:1/2(4MHz)12F675
S_OPTF EQU B'00000001' ;Pre Scaler=TMR0:1/4(8MHz)12F683
;S_OPTF EQU B'00000010' ;Pre Scaler=TMR0:1/n(Test)12F683
; |||||+++------ 1/nn=000:1/1, 001:1/2, 010:1/4
; ||||+--------- Pre Scaler 1:WDT
; |||+---------- T0SE 0:L-->H, H-->L
; ||+----------- T0SC 0:Int Clock
; |+------------ 0=INTEDG:falldown
; +------------- /GPIO Pul Up 0:Enable
;===============================================================
;
;---------------------------------------------------------------
INIT CLRF INTCON
;-------------------------------; Oscillator Control 12F683
; MOVLW B'01010000' ;2MHz
; MOVLW B'01100000' ;4MHz
MOVLW B'01110000' ;8MHz
; ||||||+------;0:FOSC<2:0>
; |||+++-------;(Osc.Status)
; +++----------;111:IRCF<2:0>
;
BSF STATUS,RP0 ;BANK=1
MOVWF OSCCON ;
BCF STATUS,RP0 ;BANK=0
;---------------------------------------------------------------
;-------------------------------; TMR0, WDT Control
; BSF STATUS,RP0
MOVLW S_OPTF ;TMR0 Pre Scaler/WDT Init
MOVWF OPTREG ;OPTION Register
BCF STATUS,RP0
;-------------------------------; Timer count work preset
;WT_02S EQU 0x27 ;Timer count 20mS
;WT_SEC EQU 0x28 ; // // 1 Sec
;WT010S EQU 0x29 ; // // 100mS [2014/06/26]
MOVLW 48
MOVWF WT_02S
MOVLW 50
MOVWF WT_SEC
;---------------------------------------------------------------
; Preset From EEPROM Data
;---------------------------------------------------------------
;-------------------------------; S_TMR0 Timer0 preset data
; DE 0x35 ;0x6F:TMR0 data(S_TMR0)
; ;実験値:0x35=55
; ;OK範囲:0x28〜(0x35)〜0x3C
MOVLW 0x6F ;
BSF STATUS,RP0 ;BANK=1
MOVWF EEADR
BSF EECON1,0 ;RD
MOVF EEDATA,W
BCF STATUS,RP0 ;BANK=0
;
MOVWF S_TMR0
; ;調整範囲(28〜3C)のチェック
SUBLW 0x3C ;0x3C - S_TMR0
BTFSS STATUS,C
GOTO STMRER ; < 3D 以上
; OK ; >= 3C 以下
MOVF S_TMR0,W
SUBLW 0x27 ;0x27 - S_TMR0
BTFSS STATUS,C
GOTO STMROK ; < 28 以上
; ERR ; >= 27 以下
; ;異常値の場合初期値をセット
STMRER MOVLW 0x35 ;Default Val.
MOVWF S_TMR0 ;Temp Set
STMROK
; MOVF S_TMR0,W
; MOVWF TMR0
;
;---------------------------------------------------------------
; Buffer,Work Initialize
;---------------------------------------------------------------
;****** CLRF WRXDT_ ;
CLRF WRXDTB ;
;****** CLRF WRXCC_ ;
;****** CLRF WTRBC_ ;
CLRF WTXDT_ ;
;****** CLRF WTXCC_ ;
CLRF WTRSTS ;
BSF WTRSTS,5 ;TX Done flag set
;---------------------------------------------------------------
;
GOTO MAIN
| |
|
|
|
| UART処理部(タイマ割込) |
|
|
;===============================================================
; Reset Process
;===============================================================
ORG 0x000 ;Reset vector
GOTO INIT ;Initialize
;
ORG 0x004 ;Interrupt vector
;===============================================================
; Interrupt Service
;===============================================================
;---------------------------------------------------------------
; ;save register
;---------------------------------------------------------------
PUSH MOVWF W_WREG ;Save W reg.
SWAPF W_WREG,1
SWAPF STATUS,0 ;Get status
MOVWF W_STAT ;Save it
MOVF FSR,W ;Save SFR
MOVWF W_FSR_
;
;---------------------------------------------------------------
; Interrupt source analize
;---------------------------------------------------------------
BCF STATUS,RP0 ;BANK0
BTFSS INTCON,T0IF ;TMR0 Over Flow ?
GOTO INIINT ;init
;
;---------------------------------------------------------------
; TMR0 Service 416uS 毎割込
;---------------------------------------------------------------
INTRTC
MOVF S_TMR0,W ;TMR0 data (from EEPROM)
;***** MOVLW S_TMR0 ;TMR0 Pre Set
MOVWF TMR0
;
BCF INTCON,T0IF ;clr int flag
;
;---------------------------------------------------------------
; ;RX data input
;---------------------------------------------------------------
; ;RX status _________
; WTRSTS,0 ;RX Busy flag _________ RX Busy ______
; WTRSTS,1 ;RX Done flag ______ ______
; ; (read)____________ Done
;---------------------------------------------------------------
BTFSC WTRSTS,0 ;
GOTO INTRX1 ; RX Busy
; ;not RX Busy
; ;---------- bit 0 process ------
BTFSC GPIO,3 ;RX Start Bit Check
GOTO INTTX0 ; not Start
; ; Start
;---------------------------------------------------------------
BTFSC WTRSTS,1 ;RX Over run Err Check
BSF WTRSTS,2 ;RX Over run Err Flag set
; ;(OverRun)でも次の文字を読む
; GOTO INTRX9 ;(OverRun)では次の文字を読まない
;
; MOVLW 16 ;---------- Start bit process --
MOVLW 8 ;---------- Start bit process --
;****** MOVF C_CLKC,W
MOVWF WRXCC_
BCF STATUS,C
RRF WRXCC_,F ;1/2:half bit time set
MOVLW 0xF0
ANDWF WTRBC_,F ;Clear RX bit count
BSF WTRSTS,0 ;RX Busy set
GOTO INTTX0
;
;INTRX9 BSF WTRSTS,2 ;RX Over run Err Flag set
; BSF WTRSTS,1 ;RX Done Flag set
; BCF WTRSTS,0 ;RX Busy flag reset
; GOTO INTTX0
;
INTRX1 DECFSZ WRXCC_,F ;---------- 1 bit time counter -
GOTO INTTX0 ;WRXCC_><0
; ; =0
; MOVLW 16 ;---------- Start bit process --
MOVLW 8 ;---------- Start bit process --
;****** MOVF C_CLKC,W
MOVWF WRXCC_
; ;---------- bit 0-9 process ----
MOVF WTRBC_,W ;WTRBC_,3:0 RX bit count
ANDLW 0x0F
SUBLW 8 ;8-(W)
BTFSC STATUS,C
GOTO INTRXR ;8 >= count
; ;8(9)< count
; ;1BYTE input conplete
MOVF WRXDT_,W
MOVWF WRXDTB ;set RX buffer
;-------------------------------;[Ctrl-C]check
BCF WTRSTS,3 ;Cancel Flag clear
ANDLW 0x7F
SUBLW 0x03
BTFSC STATUS,Z
BSF WTRSTS,3 ;Receve [Ctrl-C] (Flag set)
BTFSC WTRSTS,3
BCF WTXMST,3
;-------------------------------;
CLRF WRXDT_
;***** BCF WTRSTS,2 ;Over run or Frameing Err
BSF WTRSTS,1 ;RX Done Flag set
BCF WTRSTS,0 ;RX Busy flag reset
MOVLW 0xF0
ANDWF WTRBC_,F ;Clear RX bit count
; ;-------------------------------
BTFSC GPIO,3 ;RX Stop Bit Check
GOTO INTTX0 ;Stop Bit:1 OK
BSF WTRSTS,2 ;Over run or Frameing Err
; ;-------------------------------
GOTO INTTX0
;
INTRXR BSF STATUS,C
BTFSS GPIO,3 ; ---> C
BCF STATUS,C
RRF WRXDT_,F ;C ---> WRXDT_ 1bit input
INCF WTRBC_,F
;
;---------------------------------------------------------------
; ;TX data output
;---------------------------------------------------------------
INTTX0
BTFSC WTRSTS,5
GOTO INTTX9 ;TX Done
; ; Start
BTFSC WTRSTS,4 ;
GOTO INTTXB ;TX Busy
; ; not Busy
; ; =0
; MOVLW 16 ;-------- clk counter set(1st)
MOVLW 8 ;-------- clk counter set(1st)
;****** MOVF C_CLKC,W
MOVWF WTXCC_ ;
; ;---------- Start bit process
BSF WTRSTS,4 ;TX Busy flag set
MOVLW 0x0F
ANDWF WTRBC_,F ;Clear TX bit count
GOTO INTTXL ;0 count [Start Bit ---> Lo]
;
INTTXB DECFSZ WTXCC_,F ;---------- 1 bit time counter
GOTO INTTX9 ;WTXCC_><0
; ; =0
; MOVLW 16 ;---------- clk counter set(1st)
MOVLW 8 ;---------- clk counter set(1st)
;****** MOVF C_CLKC,W
MOVWF WTXCC_
;
SWAPF WTRBC_,W ;WTRBC_,7:4 TX bit count
ANDLW 0x0F
SUBLW 10 ;10-(W)
BTFSS STATUS,Z
GOTO INTTXT ;10><(W)
; ;10= (W)
; ;---------- TX Done ------------
BSF GPIO,1 ;keep Hi
BSF WTRSTS,5 ;TX Done flag set
BCF WTRSTS,4 ;TX Busy flag reset
GOTO INTTX9
;
INTTXT SWAPF WTRBC_,W ;WTRBC_,7:4 TX bit count
ANDLW 0x0F
SUBLW 9 ;9-(W)
BTFSC STATUS,Z
; ;9 count [Stop Bit ---> Hi]
GOTO INTTXH ;---------- Stop bit process ---
; ;9><(W)
BSF STATUS,C
RRF WTXDT_,F ;1 ---> [7]---[0] ---> C
BTFSC STATUS,C
GOTO INTTXH ;Hi
; ;Lo
INTTXL BCF GPIO,1 ;output Lo, [Start Bit]
GOTO INTRTZ
;
INTTXH BSF GPIO,1 ;output Hi, [Stop Bit]
;
INTRTZ MOVLW 0x10
ADDWF WTRBC_,F ;INC TX bit count
INTTX9
;
;---------------------------------------------------------------
; ◆その他の割込み処理◆
;---------------------------------------------------------------
;
GOTO PULL
;---------------------------------------------------------------
; ;Restore register
;---------------------------------------------------------------
INIINT MOVLW S_INTC ;init
MOVWF INTCON
;
PULL MOVF W_FSR_,W ;Restore FSR
MOVWF FSR
SWAPF W_STAT,0 ;Restore status
MOVWF STATUS
SWAPF W_WREG,0 ;Restore W reg.
RETFIE
;---------------------------------------------------------------
; End of Interrupt Service
;---------------------------------------------------------------
| |
|
|
|
(2) | タイマのみによるプログラムリスト例 割込の使えない機種(PIC10F222など) |
|
| 初期化処理部(タイマのみ) |
|
|
;===============================================================
; 定数の設定
;===============================================================
;[104μS タイマの設定] 8 1200bps
; TMR0 割込の場合(初期値→$FF→$00)
; T*F/P=104*2/1=208(-a)=196 ;TMR0 Comper Value
; T=104uS, F=OSC/4=2MHz, P=4(1/4), a=4(実験値)
;
_TMR0 EQU 200 ;
;
;===============================================================
; Work Area (counter/timer/flag/buffer tempolary work)
;===============================================================
WTRSTS EQU 0x09 ;TX, RX status
;-----------------------; _____
RXBUSY EQU 0 ;RX Busy flag __________ Busy_____
RXBFUL EQU 1 ;RX Done flag ______ RX _____
; ; (read)__________ Done
RXOVFE EQU 2 ;RX Over run Err or RX Frameing Err
;***** EQU 3 ; _______
TXBUSY EQU 4 ;TX Busy flag _________ Busy _____
TXDNST EQU 5 ;TX Done/Start _____ TX _____
; ; start___________ Done
;***** EQU 6 ;
STRCNT EQU 7 ;Start control Flag
;---------------------------------------------------------------
WRXDT_ EQU 0x0A ;RX data receive work
WRXDTB EQU 0x0B ;RX data buffer
WRXCC_ EQU 0x0C ;RX clk count
WRXBC_ EQU 0x0D ;RX bit count
WTXDTB EQU 0x0E ;TX data buffer
WTXCC_ EQU 0x0F ;TX clk count
WTXBC_ EQU 0x10 ;TX bit count
;***** EQU 0x11 ;
;***** EQU 0x12 ;
TXBFCT EQU 0x13 ;送信待ちデータ数
; ; 0の時何もしない
; ; 1の時[LF]を送信 0にする
; ; 2の時[CR]を送信 1にする
TXBF_0 EQU 0x14 ; 3の時送信 2にする
TXBF_1 EQU 0x15 ; 4の時送信 3にする
TXBF_2 EQU 0x16 ; 5の時送信 4にする
TXBF_3 EQU 0x17 ; 6の時送信 5にする
;
WADRES EQU 0x18 ;A/D data
WPWMCT EQU 0x19 ;PWM counter
WADRSL EQU 0x1A ;A/D Average work L
WADRSH EQU 0x1B ;A/D Average work H
; EQU 0x1C ;
WXHEXL EQU 0x1D ;HEXL work
WT_02S EQU 0x1E ;Timer count 20 mS 416uSx48=20mS
WT_SEC EQU 0x1F ; // // 1 Sec x50=1Sec
;
;===============================================================
; Reset Process
;===============================================================
;***** ORG 0x1FF ;
;***** MOVLW XX ;int OSC calibration val.
ORG 0x000 ;Reset vector
MOVWF OSCCAL ;oscillator calibration
;
MOVLW B'10011001' ;通信速度変更 (1200bps)
; :::::+++------;PS2:PS0=0001(1/4) 8MHz
; ::::+---------;PSA=0:TMR0 (1:WDT)
; :::+----------;T0SE=1(Hi-->Lo transition)
; ::+-----------;T0CS=0(Internal Fosc/4)
; :+------------;/GPPU=0(Enable) 1(Disabled)
; +-------------:/GPWU=1(Disabled)
OPTION ;Load OPTION Register
;
MOVLW B'00000111' ;GP0:2=Hi
MOVWF GPIO
;
MOVLW B'01000011' ;ADCON0 Set value
; ::--:::+------;0:A/D-OFF, 1:A/D-ON
; :: ::+-------;GO/DONE 1:Start, 0:Done
; :: ++--------;Channel select 00:ch0, ..
; :+------------;ANS0 AN/DIO 1:AN, 0:DIO
; +-------------;ANS1 AN/DIO 1:AN, 0:DIO
MOVWF ADCON0 ;A/D Control Reg.
;
MOVLW B'00001001' ;
; :::+------;GP0=AN (A/D)
; ::+-------;GP1=OUT(LED1)
; :+--------;GP2=OUT(TX)
; +---------;GP3=IN (RX)
TRIS GPIO ;Load TRIS Register
;
;
;-------------------------------;Work init
CLRF WTRSTS
;***** MOVLW 48 ;TM0=416uS
MOVLW 192 ;TM0=104uS
MOVWF WT_02S
; ;Startup timer Value
MOVLW 50 ;50:1Sec, 100:2Sec, ...
MOVWF WT_SEC
;
CLRF WTRSTS ;TX, RX status
CLRF WRXDT_ ;RX data reg.
CLRF WRXDTB ;RX data receive work
CLRF WRXCC_ ;RX clock count
CLRF WRXBC_ ;RX bit count
CLRF WTXDTB ;TX data reg.
CLRF WTXCC_ ;TX clock count
CLRF WTXBC_ ;RX bit count
;
CLRF TXBFCT
| |
|
|
|
| UART処理部(タイマのみ) |
|
|
LOOP CLRF TMR0
;
;===============================================================
; TMR0 Service 104uS 毎処理
;===============================================================
;
;-------------------------------;【DEBUG】
;***** BSF GPIO,GP2 ;【DEBUG】信号発生 GP2:ON
;-------------------------------;【DEBUG】
;
;---------------------------------------------------------------
; ;RX data input
;---------------------------------------------------------------
BTFSC WTRSTS,RXBUSY ;
GOTO RXBITR ;RX Busy -->1 bit Receve
; ;RX not Busy
; ;---------- bit 0 process
BTFSC GPIO,3 ;RX Start Bit Check
GOTO INTTX0 ; not Start
; ; Start
; ;--------------------------
BTFSC WTRSTS,RXBFUL ;OverRun Check(If RX Done)
BSF WTRSTS,RXOVFE ;RX Over run Err Flag set
; ;------- Start bit process
;***** MOVLW 16 ;16clock / 1bit
MOVLW 8 ; 8clock / 1bit
MOVWF WRXCC_
BCF STATUS,C
RRF WRXCC_,F ;clock Count*(1/2)(half bitset)
;
CLRF WRXBC_ ;Clear RX bit count
BSF WTRSTS,RXBUSY ;RX Busy set
GOTO INTTX0
;
RXBITR ;1 bit Receve
DECFSZ WRXCC_,F ;1 bit time counter ?
GOTO INTTX0 ;WRXCC_>>0
; ; =0
; ;-------- Clock count set
;***** MOVLW 16 ;16clock / 1bit
MOVLW 8 ; 8clock / 1bit
MOVWF WRXCC_
; ;-------- bit 0-9 process
MOVLW 9
SUBWF WRXBC_,W ;(WRXBC_)-9 RX bit count check
BTFSC STATUS,C
GOTO RX1BYT ;count >= 9 (-)
; ;count > 9 (+)
; ;get 1 bit
RX1BIT BSF STATUS,C ;C=1
BTFSS GPIO,3
BCF STATUS,C ;GP3=0 C=0
RRF WRXDT_,F ;C ---> WRXDT_ 1bit input
;
INCF WRXBC_,F ;RX bit count
GOTO INTTX0
;
;-------------------------------;1バイト取込完了
RX1BYT
MOVF WRXDT_,W ;1BYTE input conplete
MOVWF WRXDTB ;set RX buffer
CLRF WRXDT_
CLRF WRXBC_ ;Clear RX bit count
;
BTFSS GPIO,3 ;RX Stop Bit Check
BSF WTRSTS,RXOVFE ;Stop=0 Frameing Err
; ;Stop=1 OK
NOP ;avoidance of behavior "Read-modify-write"
BSF WTRSTS,RXBFUL ;RX Done Flag set
NOP ;avoidance of behavior "Read-modify-write"
BCF WTRSTS,RXBUSY ;RX Busy flag reset
;
;---------------------------------------------------------------
; ;TX data output
;---------------------------------------------------------------
INTTX0 BTFSC WTRSTS,TXDNST
GOTO EXRXTX ;TX Done (1)
; ; Start (0)
BTFSC WTRSTS,TXBUSY ;
GOTO INTTXB ;TX Busy (1)
; ;not Busy (0)
; ;-- clock counter set(1st)
;***** MOVLW 16 ;16clock / 1bit
MOVLW 8 ; 8clock / 1bit
MOVWF WTXCC_
; ;------ Start bit process
BSF WTRSTS,TXBUSY ;TX Busy flag set
CLRF WTXBC_ ;Clear TX bit count
GOTO INTTXL ;0 count[Start Bit: Lo]
;
INTTXB DECFSZ WTXCC_,F ;----- 1 bit time counter
GOTO EXRXTX ;WTXCC_>>0
; ; =0
; ;----- clock counter set
;***** MOVLW 16 ;16clock / 1bit
MOVLW 8 ; 8clock / 1bit
MOVWF WTXCC_
;
MOVLW 10
SUBWF WTXBC_,W ;(WTXBC_)-10 TX bit count check
BTFSS STATUS,Z
GOTO INTTXT ;count>>10
; ;count= 10
; ;---------- TX Done
BSF GPIO,GP2 ;keep Hi
BSF WTRSTS,TXDNST ;TX Done flag set
NOP ;avoidance of behavior "Read-modify-write"
BCF WTRSTS,TXBUSY ;TX Busy flag reset
GOTO EXRXTX
;
INTTXT MOVLW 9
SUBWF WTXBC_,W ;(WTXBC_)-10 TX bit count check
BTFSC STATUS,Z
GOTO INTTXH ;count= 9 [Stop Bit: Hi]
; ;count>>9
; ;------ Stop bit process
BSF STATUS,C
RRF WTXDTB,F ;1 ---> [7]---[0] ---> C
BTFSC STATUS,C
GOTO INTTXH ;Hi
; ;Lo
INTTXL BCF GPIO,GP2 ;output Lo, [Start Bit]
GOTO INTRTZ
;
INTTXH BSF GPIO,GP2 ;output Hi, [Stop Bit]
;
INTRTZ INCF WTXBC_,F ;INC TX bit count
;---------------------------------------------------------------
EXRXTX ;Exit RX, TX Process
;---------------------------------------------------------------
; ここにメイン処理を置く
;---------------------------------------------------------------
; TMR0の時間になるまで時間調整する(時間潰し)
;---------------------------------------------------------------
CKTMR0
;-------------------------------;【DEBUG】
;***** BCF GPIO,GP2 ;【DEBUG】
;-------------------------------;【DEBUG】
;
CKTM0L MOVLW _TMR0
SUBWF TMR0,W ;TMR0 - _TMR0
BTFSS STATUS,C
GOTO CKTM0L ;TMR0 > _TMR0
GOTO LOOP ;TMR0 >= _TMR0
;===============================================================
; 以下にサブルーチンを置く(ネスト:2レベル以内)
| |
|
|
【お礼 と お願い】 |
|
・ ホームページで情報公開している方々の貴重な体験を活用させて頂きました |
オリジナルがある場合は参照出来る様に場所を示し詳細は省いています |
・ 内容はありのままを記載していますが、間違いや誤解があるかもしれません |
試す場合は全てご自身の責任で行って下さい |
・ リンクは自由ですが、商用への写真・図の転載等全て禁止します |
|
ご意見、ご感想、間違い指摘 ..... 等は
掲示板(BBS) 又は
<old.and.ordinarygmail.com> へお願いします
|
―Sorry! Japanese only― |
Copyright (c)2000 Old-Ordinary Allrights resrved |
|
古風平凡 |
|
|