RL78マイコン基板(RL78/G10)|TOOL0端子へのシリアル出力を使ったkbhit()関数もどきのコード
前のエントリでブレッドボード上に組んだ書き込み回路(FT232RLと74HC125と抵抗2本の簡単なもの)経由で
秋月電子さんで販売されているRL78/G10 10pin DIP基板のTOOL0端子からPC上にデバッグメッセージを表示
させてみたのですが、そうなると人情としてPC側のキーボード入力をTOOL0端子でRL78/G10に伝えてみたく
なります。何か手は無いものかとRL78/G10のマニュアルを読んだところ、RL78/G10のキー割り込み機能を
使うとキー入力コードを区別することまでは出来ないもののキーが押されたことぐらいは伝えられそうな気が
しました。そこでアセンブラコードを書いて試してみたところ、悪くない感じで動作してくれました。
もともとのキー割り込み機能というのはRL78/G10に接続されたスイッチ(あるいはスイッチマトリックス)の
押下/解放(入力レベルの変化)を検出する為に内蔵されている機能ですが、このうちのチャンネル0がTOOL0
端子の兼用端子機能(こちらの場合の表記はKR0端子)として割り当てられていましたので、TOOL0端子に接続
されたFT232RLからのシリアル出力のスタートビット(立下りエッジ)の検出に使ってみました。(なお、割り
込みを発生させて割り込み処理ルーチンに分岐させるようなことまではしていません。) コードを書いている
最中は以下の点が気になりましたが、実際に動かしてみると問題無く動作してくれました。
(1) FT232RLを2Mbaudに設定しているのでシリアル出力信号の幅が狭いがRL78/G10が検出するかどうか?
→ 検出してくれた
(2) FT232RLとRL78/G10は単線UART(送信線と受信線が兼用)接続しているのでTOOL0端子からのソフト
ウェアシリアル出力にも検出機能が反応してしまうが回避出来るかどうか?
→ ソフトウェアシリアル出力期間中だけ一時的に検出機能を中断させることが出来た
(3) FT232RL出力の単線UART化に使用している74HC125からのLow出力とTOOL0端子からのHigh出力が
衝突する危険性を回避出来るかどうか?
→TOOL0端子からはHi-zかLow出力だけを行うようにしてHigh出力をしないようにした(Hi-z時は外部
1KΩのプルアップによりFT232RL入力から見るとHighとして認識される)
以下は試してみた時の画面なのですが、RL78/G10側でプログラム開始直後はPC側のキーが押下されるのを
待ち、PC側のキーが押されたら表示を開始し、それ以後は、再びPC側のキーが押下されたら表示を中断し、
更にPC側のキーが押されたら表示を再開し、というのを繰り返しているところです。(今回のコードはキー
入力コードは区別出来ませんので、最初は取り敢えずスペースキーで試していましたが、スペースは画面に
エコーバック表示されても見て分かりませんので、そのうち'/'キーで試すことが多くなりました。ちなみに、
単線UART接続ですのでFT232RLの出力は回路的にFT232RLに入力されて自動的にエコーバックされます。)

作成したアセンブラコード(計60バイト)は以下の通りです。(なお、putchar()とkbhit()の2つがありますが、
putchar()の方は前のエントリで作成したアセンブラコードから変更した箇所を赤字にしています。)
; This code is in the public domain. You may use, modify or distribute it freely.
PUBLIC _putchar
_putchar: ;X = data, A = ignored, void putchar( unsigned char )
SET1 PM4.0 ; 2 clk 3 byte always I do for robustness, P40 = TOOL0/KR0
CLR1 P4.0 ; 2 clk 3 byte same as above
MOV1 CY, KRM0.0 ; 1 clk 3 byte for kbhit(), get KR0 detection enable flag
CLR1 KRM0.0 ; 2 clk 3 byte for kbhit(), disable KR0 detection flag
PUSH PSW ; 2 clk 2 byte
_putchar_b: ;begin
ONEB A ; 1 clk 1 byte as a stop bit, shorter than "MOV A, #01H"
ADDW AX, AX ; 2 clk 1 byte for a start bit, shorter than "SHLW AX, 1"
DI ; 4 clk 3 byte
_putchar_l: ;loop (start bit = 0, b0, b1, b2, b3, b4, b5, b6, b7, stop bit = 1)
SHRW AX, 1 ; 2 clk 2 byte
MOV1 PM4.0, CY ; 2 clk 3 byte
CMPW AX, #0000H ; 2 clk 3 byte
BNZ $_putchar_l ; 2/4 clk 2 byte
_putchar_e: ;end
POP PSW ; 4 clk 2 byte
MOV1 KRM0.0, CY ; 2 clk 3 byte for kbhit(), restore KR0 detection enable flag
RET ; 7 clk 1 byte
PUBLIC _kbhit
_kbhit: ;char kbhit( void ), return value : 1=detected / 0=not detected
SET1 PM4.0 ;always I do for robustness, P40 = TOOL0/KR0
SET1 KRM0.0 ;enable KR0 detection flag
SET1 KRCTL.7 ;enable KRx detection flags
MOV A, KRF ;get KRx detection flgas
AND A, #01H ;check KR0 detecion flag
BZ $_kbhit_e ;Z=not detected / NZ=detected
MOV C, #20 ;set loop count (10 clk/bit * 10 bit = 100 clk = 5 clk * 20)
_kbhit_w: ;wait 100 clk (start bit, b0, b1, b2, b3, b4, b5, b6, b7, stop bit)
DEC C ; 1 clk 1 byte
BNZ $_kbhit_w ; 2/4 clk 2 byte
MOV KRF, #0FEH ;clear KR0 detection flag
_kbhit_e:
MOV C, A ;A = KR0 detecion flag (01H=detected / 00H=not detected)
RET ;C = return value (1=detected / 0=not detected)
END
また、動作確認用に作成したCコードは以下の通りです。
void putchar( unsigned char );
char kbhit( void );
途中省略
void main(void)
{
R_MAIN_UserInit();
/* Start user code. Do not edit comment generated here */
while ( !kbhit() )
{
/* wait for a first keyboard hit */
}
putchar('\r');
putchar('\n');
while (1U)
{
unsigned char c;
if ( kbhit() )
{
/* pause because of a keyboard hit */
while ( !kbhit() )
{
/* wait for a keyboard hit to continue */
}
putchar('\r');
putchar('\n');
}
for ( c = '0' ; c <= '9' ; c++ )
{
putchar(c);
}
for ( c = 'A' ; c <= 'Z' ; c++ )
{
putchar(c);
}
for ( c = 'a' ; c <= 'z' ; c++ )
{
putchar(c);
}
putchar('\r');
putchar('\n');
G_LED_DATA = 0b010101010101;
Wait_1sec();
//Wait_1sec();
G_LED_DATA = 0b101010101010;
Wait_1sec();
//Wait_1sec();
}
/* End user code. Do not edit comment generated here */
}

なお、RL78/G10のマニュアルは以下のウェブページにあります。
RL78/G10 ドキュメント一覧
http://japan.renesas.com/products/mpumcu/rl78/rl78g1x/rl78g10/Documentation.jsp
追記 : メモ
RL78/G10 ユーザーズマニュアル ハードウェア編
Rev.3.00 2014.11
http://documentation.renesas.com/doc/products/mpumcu/doc/rl78/r01uh0384jj0300_rl78g10.pdf
秋月電子さんで販売されているRL78/G10 10pin DIP基板のTOOL0端子からPC上にデバッグメッセージを表示
させてみたのですが、そうなると人情としてPC側のキーボード入力をTOOL0端子でRL78/G10に伝えてみたく
なります。何か手は無いものかとRL78/G10のマニュアルを読んだところ、RL78/G10のキー割り込み機能を
使うとキー入力コードを区別することまでは出来ないもののキーが押されたことぐらいは伝えられそうな気が
しました。そこでアセンブラコードを書いて試してみたところ、悪くない感じで動作してくれました。
もともとのキー割り込み機能というのはRL78/G10に接続されたスイッチ(あるいはスイッチマトリックス)の
押下/解放(入力レベルの変化)を検出する為に内蔵されている機能ですが、このうちのチャンネル0がTOOL0
端子の兼用端子機能(こちらの場合の表記はKR0端子)として割り当てられていましたので、TOOL0端子に接続
されたFT232RLからのシリアル出力のスタートビット(立下りエッジ)の検出に使ってみました。(なお、割り
込みを発生させて割り込み処理ルーチンに分岐させるようなことまではしていません。) コードを書いている
最中は以下の点が気になりましたが、実際に動かしてみると問題無く動作してくれました。
(1) FT232RLを2Mbaudに設定しているのでシリアル出力信号の幅が狭いがRL78/G10が検出するかどうか?
→ 検出してくれた
(2) FT232RLとRL78/G10は単線UART(送信線と受信線が兼用)接続しているのでTOOL0端子からのソフト
ウェアシリアル出力にも検出機能が反応してしまうが回避出来るかどうか?
→ ソフトウェアシリアル出力期間中だけ一時的に検出機能を中断させることが出来た
(3) FT232RL出力の単線UART化に使用している74HC125からのLow出力とTOOL0端子からのHigh出力が
衝突する危険性を回避出来るかどうか?
→TOOL0端子からはHi-zかLow出力だけを行うようにしてHigh出力をしないようにした(Hi-z時は外部
1KΩのプルアップによりFT232RL入力から見るとHighとして認識される)
以下は試してみた時の画面なのですが、RL78/G10側でプログラム開始直後はPC側のキーが押下されるのを
待ち、PC側のキーが押されたら表示を開始し、それ以後は、再びPC側のキーが押下されたら表示を中断し、
更にPC側のキーが押されたら表示を再開し、というのを繰り返しているところです。(今回のコードはキー
入力コードは区別出来ませんので、最初は取り敢えずスペースキーで試していましたが、スペースは画面に
エコーバック表示されても見て分かりませんので、そのうち'/'キーで試すことが多くなりました。ちなみに、
単線UART接続ですのでFT232RLの出力は回路的にFT232RLに入力されて自動的にエコーバックされます。)

作成したアセンブラコード(計60バイト)は以下の通りです。(なお、putchar()とkbhit()の2つがありますが、
putchar()の方は前のエントリで作成したアセンブラコードから変更した箇所を赤字にしています。)
; This code is in the public domain. You may use, modify or distribute it freely.
PUBLIC _putchar
_putchar: ;X = data, A = ignored, void putchar( unsigned char )
SET1 PM4.0 ; 2 clk 3 byte always I do for robustness, P40 = TOOL0/KR0
CLR1 P4.0 ; 2 clk 3 byte same as above
MOV1 CY, KRM0.0 ; 1 clk 3 byte for kbhit(), get KR0 detection enable flag
CLR1 KRM0.0 ; 2 clk 3 byte for kbhit(), disable KR0 detection flag
PUSH PSW ; 2 clk 2 byte
_putchar_b: ;begin
ONEB A ; 1 clk 1 byte as a stop bit, shorter than "MOV A, #01H"
ADDW AX, AX ; 2 clk 1 byte for a start bit, shorter than "SHLW AX, 1"
DI ; 4 clk 3 byte
_putchar_l: ;loop (start bit = 0, b0, b1, b2, b3, b4, b5, b6, b7, stop bit = 1)
SHRW AX, 1 ; 2 clk 2 byte
MOV1 PM4.0, CY ; 2 clk 3 byte
CMPW AX, #0000H ; 2 clk 3 byte
BNZ $_putchar_l ; 2/4 clk 2 byte
_putchar_e: ;end
POP PSW ; 4 clk 2 byte
MOV1 KRM0.0, CY ; 2 clk 3 byte for kbhit(), restore KR0 detection enable flag
RET ; 7 clk 1 byte
PUBLIC _kbhit
_kbhit: ;char kbhit( void ), return value : 1=detected / 0=not detected
SET1 PM4.0 ;always I do for robustness, P40 = TOOL0/KR0
SET1 KRM0.0 ;enable KR0 detection flag
SET1 KRCTL.7 ;enable KRx detection flags
MOV A, KRF ;get KRx detection flgas
AND A, #01H ;check KR0 detecion flag
BZ $_kbhit_e ;Z=not detected / NZ=detected
MOV C, #20 ;set loop count (10 clk/bit * 10 bit = 100 clk = 5 clk * 20)
_kbhit_w: ;wait 100 clk (start bit, b0, b1, b2, b3, b4, b5, b6, b7, stop bit)
DEC C ; 1 clk 1 byte
BNZ $_kbhit_w ; 2/4 clk 2 byte
MOV KRF, #0FEH ;clear KR0 detection flag
_kbhit_e:
MOV C, A ;A = KR0 detecion flag (01H=detected / 00H=not detected)
RET ;C = return value (1=detected / 0=not detected)
END
また、動作確認用に作成したCコードは以下の通りです。
void putchar( unsigned char );
char kbhit( void );
途中省略
void main(void)
{
R_MAIN_UserInit();
/* Start user code. Do not edit comment generated here */
while ( !kbhit() )
{
/* wait for a first keyboard hit */
}
putchar('\r');
putchar('\n');
while (1U)
{
unsigned char c;
if ( kbhit() )
{
/* pause because of a keyboard hit */
while ( !kbhit() )
{
/* wait for a keyboard hit to continue */
}
putchar('\r');
putchar('\n');
}
for ( c = '0' ; c <= '9' ; c++ )
{
putchar(c);
}
for ( c = 'A' ; c <= 'Z' ; c++ )
{
putchar(c);
}
for ( c = 'a' ; c <= 'z' ; c++ )
{
putchar(c);
}
putchar('\r');
putchar('\n');
G_LED_DATA = 0b010101010101;
Wait_1sec();
//Wait_1sec();
G_LED_DATA = 0b101010101010;
Wait_1sec();
//Wait_1sec();
}
/* End user code. Do not edit comment generated here */
}

なお、RL78/G10のマニュアルは以下のウェブページにあります。
RL78/G10 ドキュメント一覧
http://japan.renesas.com/products/mpumcu/rl78/rl78g1x/rl78g10/Documentation.jsp
追記 : メモ
RL78/G10 ユーザーズマニュアル ハードウェア編
Rev.3.00 2014.11
http://documentation.renesas.com/doc/products/mpumcu/doc/rl78/r01uh0384jj0300_rl78g10.pdf
- 関連記事
-
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)で内蔵周辺機能シミュレーションを試す (3)
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)で内蔵周辺機能シミュレーションを試す (2)
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)で内蔵周辺機能シミュレーションを試す (1)
- RL78マイコン基板(RL78/G10)|e2studio同梱のPython 2.7.2+pySerial 2.7でシリアルポート操作
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)のPythonコンソール上でシリアルポート操作 (3)
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)のPythonコンソール上でシリアルポート操作 (2)
- RL78マイコン基板(RL78/G10)|CS+(CubeSuite+)のPythonコンソール上でシリアルポート操作 (1)
- RL78マイコン基板(RL78/G10)|TOOL0端子へのシリアル出力を使ったgetch()関数もどきのコード
- RL78マイコン基板(RL78/G10)|TOOL0端子へのシリアル出力を使ったkbhit()関数もどきのコード
- RL78マイコン基板(RL78/G10)|TOOL0端子から2Mbaudでソフトウェアシリアル出力するコード
- RL78マイコン基板(RL78/G10)|Renesas Flash Programmerのコマンドラインでフラッシュ書き込み
- RL78マイコン基板(RL78/G10)|秋月のRL78/G10 10pin DIP基板に自作回路でフラッシュ書き込み (2)
- RL78マイコン基板(RL78/G10)|秋月のRL78/G10 10pin DIP基板に自作回路でフラッシュ書き込み (1)
- RL78マイコン|10ピン0.65mmピッチSSOP→DIP変換基板が見当たらない
- RL78マイコン | 公開されている仕様ではRL78マイコン用GDBSTUBを作ることが出来ない
2015/01/09 blog-entry-547 category: RL78 /* 16bit,8bit CISC */
| h o m e |