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とは 一般的な方法 エミュレート型2017/10/27
規格と仕様調歩同期 RS-232C 通信速度 PIC使用ポート 
概要(条件、制約)タイマ、データ・プログラムメモリ、割込
ソフトの基本構造 104μS にする理由  タイマ割込  タイマだけで
通信のフォーマット  スタートビット  シリパラ変換
 
UART処理 フラグとワーク  受信処理  送信処理
プログラムリスト タイマ割込による 初期化処理  UART処理 2017/11/10
  タイマのみによる 初期化処理  UART処理 2017/11/10

 [Home]へ


 始めにエミュレート型の 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
32MHz13μs 19230bps 9615bps 4807bps 2403bps 1201bps 600bps 301bps
16MHz26μs 9615bps 4807bps 2403bps 1201bps 600bps 300bps
8MHz52μs 4807bps 2403bps 1201bps 600bps 300bps
4MHz104μ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)内部時計のクロックとする
  20mS1Sec (必要なら 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 のユニットに与えています

 目次へ

 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.ordinary(単価記号)gmail.com> へお願いします
―Sorry! Japanese only― Copyright (c)2000 Old-Ordinary Allrights resrved 古風平凡

 頁の先頭へ

inserted by FC2 system