シリアルインターフェイスを使って、データを受信します。
このプログラムは、シリアル通信の本質を説明するため、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