6-8 シリアル通信(受信側)


シリアルインターフェイスを使って、データを受信します。

このプログラムは、シリアル通信の本質を説明するため、SIO割り込みを利用していません。実用的なシリアル通信は、次の「汎用シリアルドライバ」を参照してください。

ローバッテリ自動検出を停止し、シリアルインターフェイスを初期化します。

64行目では、シリアルインターフェイスにデータが(1バイト)溜っているかをチェックしています。もしデータがあれば、受信したデータをput2digitルーチンで10進数に変換しLCDに表示します。

MODEボタンによりプログラムが中断されると、シリアルインターフェイスを規定の値に書き戻し(121行目からのSioEndルーチン)、ローバッテリ自動検出を有効にしてプログラムを終了します。

注意

「シリアル通信(送信側)」では、0.5秒ごとにデータを送信しているので問題にはなりませんが、受信処理が完了していない時点でデータを送信すると、データを取りこぼします。

連続したデータを受信する場合は、SIO割り込みを利用してください。

001	; Tab width = 4
002	
003	;----------------------------------------------------------------------------
004	; ** シリアル通信サンプル2 (データ受信) **
005	;
006	; ・シリアル通信ポートから受信した数値をLCDに表示する
007	;----------------------------------------------------------------------------
008	; 1.01 990208 SEGA Enterprises,LTD.
009	;----------------------------------------------------------------------------
010	
011	chip	LC868700			; チップの種類をアセンブラに指定
012	world	external			; 外部メモリ用プログラム
013	
014	public	main				; ghead.asm から参照されるシンボル
015	
016	extern	_game_end			; アプリケーション終了
017	
018	
019	; **** システム定数の定義 ***************************************************
020	
021								; OCR(発振制御レジスタ)設定値
022	osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
023	osc_xt		equ 0efh		;	システムクロックに水晶発振を指定
024	
025	LowBattChk	equ 06eh		; ローバッテリ検出フラグ(RAMバンク0)
026	
027	
028	; *** データセグメント ******************************************************
029	
030			dseg				; データセグメント開始
031	
032	r0:		ds		1			; 間接アドレッシングレジスタ r0
033	r1:		ds		1			; 間接アドレッシングレジスタ r1
034	r2:		ds		1			; 間接アドレッシングレジスタ r2
035	r3:		ds		1			; 間接アドレッシングレジスタ r3
036			ds		12			; その他のレジスタ
037	
038	counter: ds		1			; カウンタ
039	work1:	ds		1			; 作業用(put2digitで使用)
040	
041	
042	; *** コードセグメント ******************************************************
043	
044			cseg				; コードセグメント開始
045	
046	; *-------------------------------------------------------------------------*
047	; * ユーザープログラム														*
048	; *-------------------------------------------------------------------------*
049	main:
050			call	cls			; LCD表示の消去
051			call	BattChkOff	; ローバッテリ自動検出機能 OFF
052			clr1	P3INT,0		; P3割り込みをマスク
053	cwait:
054			call	SioInit		; シリアル通信の初期化
055			bz		start		; VM が接続されていればスタート
056	
057			ld		P3			; [M]ボタンチェック
058			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
059	
060			jmp		cwait		; VM が接続されるまで待機
061	start:
062	
063	loop0:
064			call	SioRecv1	; 1byte受信する
065			bnz		next4		; 受信データがない場合はnext4へ
066	
067			ld		b			; 受信したデータをaccへ
068			mov		#2,c		; 表示座標(水平)
069			mov		#1,b		; 表示座標(垂直)
070			call	put2digit	; LCDに2桁数値表示
071	
072	next4:						; ** [M](モード)ボタンチェック **
073			ld		P3
074			bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了
075	
076			jmp		loop0		; 繰り返し
077	
078	finish:						; ** アプリケーション終了処理 **
079			call	SioEnd		; シリアル通信終了処理
080			call	BattChkOn	; ローバッテリ自動検出機能 ON
081			jmp		_game_end	; アプリケーション終了		
082	
083	; *-------------------------------------------------------------------------*
084	; * シリアル通信の初期化													*
085	; * 出力: acc = 0   : 正常終了												*
086	; *       acc = 0ffh: VM が接続されていない								*
087	; *-------------------------------------------------------------------------*
088	; シリアル通信の初期化
089	; システムクロックが水晶モードであることを前提としています。
090	SioInit:
091								; **** VM同士の接続を確認 ****
092			ld		P7			; 接続状態の確認
093			and		#%00001101	; P70, P72, P73 をチェック
094			sub		#%00001000	; P70=0, P72=0, P73=1 か判定
095			bz		next3		; 接続されているときnext3へ
096		
097			mov		#0ffh,acc	; 接続されていないとき acc=0ffh として異常終了
098			ret					; SioInit終わり
099	next3:
100	
101								; **** シリアル通信の初期化 ****
102			mov		#0,SCON0	; LSBを先頭に出力するよう指定
103			mov		#0,SCON1	; LSBを先頭に入力するよう指定
104			mov		#088h,SBR	; 転送レートを設定する
105			clr1	P1,0		; P10ラッチをクリア(P10/SO0)
106			clr1	P1,2		; P12ラッチをクリア(P12/SCK0)
107			clr1	P1,3		; P13ラッチをクリア(P13/SO1)
108	
109			mov		#%00000101,P1FCR ; 端子機能設定
110			mov		#%00000101,P1DDR ; 端子機能設定
111	
112			mov		#0,SBUF0	; 転送バッファクリア
113			mov		#0,SBUF1	; 転送バッファクリア
114	
115			ret					; SioInit終わり
116	
117	
118	; *-------------------------------------------------------------------------*
119	; * シリアル通信の終了														*
120	; *-------------------------------------------------------------------------*
121	SioEnd:						; **** シリアル通信終了処理 ****
122	
123			mov		#0,SCON0	; SCON0 = 0
124			mov		#0,	SCON1	; SCON1 = 0
125			mov		#0bfh,P1FCR	; P1FCR = 0bfh
126			mov		#0a4h,P1DDR	; P1DDR = 0a4h
127	
128			ret					; SioEnd終わり
129	
130	
131	; *-------------------------------------------------------------------------*
132	; * シリアルポートから1byte受信する											*
133	; *   出力 b: 受信データ													*
134	; *        acc=0   : 受信データあり											*
135	; *        acc=0ffh: 受信データなし											*
136	; *-------------------------------------------------------------------------*
137	SioRecv1:					; **** 1byte受信する ****
138			ld		SCON1
139			bp		acc,1,next5	; 受信データがあるときnext5へ
140			bp		acc,3,next6 ; 現在転送中ならnext6へ
141			
142			set1	SCON1,3		; 転送開始
143	next6:
144			mov		#0ffh,acc	; acc=0ffh(受信データなし)として返る
145			ret					; SioRecv1終わり		
146	next5:
147			
148			ld		SBUF1		; 受信データを読み込む
149			st		b			; データをbへコピー
150			
151			clr1	SCON1,1		; 転送終了フラグをリセット
152			
153			mov		#0,acc		; acc=0(受信データあり)として返る
154			ret					; SioRecv1終わり
155	
156	
157	; *-------------------------------------------------------------------------*
158	; * 2桁の数値を表示する														*
159	; * 入力 acc : 数値															*
160	; *        c : 文字水平位置												  	*
161	; *        b : 文字垂直位置												  	*
162	; *-------------------------------------------------------------------------*
163	put2digit:
164			push	b			; 座標データを退避
165			push	c			;
166			st		c			; 10の位と1の位の値をそれぞれ計算
167			xor		a			; ( acc = acc/10, work1 = acc mod 10 )
168			mov		#10,b		;
169			div					;
170			ld		b			;
171			st		work1		; 1の位の計算結果をwork1に保存
172			ld		c			;
173			pop		c			; 座標値を(c.b)に復帰
174			pop		b			; 
175			push	b			; また退避
176			push	c			;
177			call	putch		; 10の位を表示
178			ld		work1		; 1の位の値を読み込み
179			pop		c			; 座標値を(c,b)に復帰
180			pop		b			; 
181			inc		c			; 表示座標を右へ
182			call	putch		; 1の位を表示
183	
184			ret					; put2digit終わり
185	
186	
187	; *-------------------------------------------------------------------------*
188	; * LCD表示イメージを消去する												*
189	; *-------------------------------------------------------------------------*
190	cls:
191			push	OCR			; OCR値を退避
192			mov		#osc_rc,OCR ; システムクロックを指定
193	
194			mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
195			call	cls_s		; そのバンク内のデータをクリア
196	
197			mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
198			call	cls_s		; そのバンク内のデータをクリア
199			pop		OCR			; OCR値を復帰
200			
201			ret					; cls終わり
202			
203	cls_s:						; *** 表示用RAM 1BANK分の消去 ***
204			mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
205			mov		#80h,b 		; ループカウンタbにループ数をセット
206	loop3:
207			mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
208			inc		r2			;
209			dbnz	b,loop3		; bが0になるまで繰り返す
210			
211			ret					; cls_s終わり
212			
213	
214	; *-------------------------------------------------------------------------*
215	; * 指定位置に1キャラクタ表示する											*
216	; * 入力 acc : キャラクタコード												*
217	; *        c : 文字水平位置												  	*
218	; *        b : 文字垂直位置												  	*
219	; *-------------------------------------------------------------------------*
220	putch:
221			push	XBNK
222			push	acc
223			call	locate		; 座標から表示RAMのアドレスを計算
224			pop		acc
225			call	put_chara	; 1キャラクタ表示する
226			pop		XBNK
227			
228			ret					; putch終わり
229			
230	
231	locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
232			; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
233			; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク
234	
235								; *** 表示用RAMバンクアドレスの判断 ***
236			ld		b			; b>=2 のとき next1 へ
237			sub		#2			;
238			bn		PSW,7,next1	;
239			
240			mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
241			br		next2
242	next1:
243			st		b
244			mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
245	next2:
246	
247								; *** 表示指定位置のRAMアドレス計算 ***
248			ld		b			; b * 40h + c + 80h
249			rol					;
250			rol					;
251			rol					;
252			rol					;
253			rol					;
254			rol					;
255			add		c			;
256			add		#80h		;
257			st		r2			; RAMアドレスをr2に格納
258					
259			ret					; locate終わり
260	
261	
262	put_chara:
263			push	PSW			; PSW値を退避
264			set1	PSW,1		; データRAMバンク1を選択
265	
266								; *** キャラクタデータアドレスの計算 ***
267			rol					; (TRH,TRL) = acc*8 + fontdata
268			rol					;
269			rol					;	
270			add		#low(fontdata)	;
271			st		TRL				;
272			mov		#0,acc			;
273			addc	#high(fontdata)	;
274			st		TRH			;
275	
276			push	OCR			; OCR値を退避
277			mov		#osc_rc,OCR ; システムクロックを指定
278	
279			mov		#0,b		; キャラクタデータ読み出し用オフセット値
280			mov		#4,c		; ループカウンタ
281	loop1:
282			ld		b			; 1ライン目の表示データを読み出す
283			ldc					;
284			inc		b			; 読み出しデータのオフセットを +1
285			st		@r2			; 表示データを表示用RAMに転送
286			ld		r2			; 表示用RAMアドレス +6
287			add		#6			;
288			st		r2			;
289	
290			ld		b			; 2ライン目の表示データを読み出す
291			ldc					;
292			inc		b			; 読み出しデータのオフセットを +1
293			st		@r2			; 表示データを表示用RAMに転送
294			ld		r2			; 表示用RAMアドレス +10
295			add		#10			;
296			st		r2			;
297			
298			dec		c			; ループカウンタのデクリメント
299			ld		c			; 
300			bnz		loop1		; 8ライン分(4回)繰り返し
301			
302			pop		OCR			; OCR値を復帰
303			pop		PSW			; PSW値を復帰
304	
305			ret					; put_chara終わり
306	
307	
308	; *-------------------------------------------------------------------------*
309	; * キャラクタのビットイメージデータ										*
310	; *-------------------------------------------------------------------------*
311	fontdata:
312			db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
313			db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
314			db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
315			db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
316			db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
317			db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
318			db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
319			db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
320			db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
321			db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09		
322	
323	
324	; *-------------------------------------------------------------------------*
325	; *	ローバッテリ自動検出機能 ON												*
326	; *-------------------------------------------------------------------------*
327	BattChkOn:
328			push	PSW			; PSW値を退避
329	
330			clr1	PSW,1		; データRAMバンク0を選択
331			mov		#0,acc		; ローバッテリ検出をする(0)
332			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
333	
334			pop		PSW			; PSW値を復帰
335			ret					; BattChkOn終わり
336	
337	
338	; *-------------------------------------------------------------------------*
339	; *	ローバッテリ自動検出機能 OFF											*
340	; *-------------------------------------------------------------------------*
341	BattChkOff:
342			push	PSW			; PSW値を退避
343	
344			clr1	PSW,1		; データRAMバンク0を選択
345			mov		#0ffh,acc	; ローバッテリ検出をしない(0ffh)
346			st		LowBattChk	; ローバッテリ自動検出フラグ(RAMバンク0)
347	
348			pop		PSW			; PSW値を復帰
349			ret					; BattChkOff終わり

[]   [INDEX]   []

(C)SEGA ENTERPRISES, LTD., 1998