評価ボード
アセンブラ・C 言語による実践解説テキスト（ＢＦＥ２０４−ＣＡＴ２０３ ｆｏｒ ＬＳＩＣ−８０）

初版 ２００２年 ７月

Rev １．００（２００２／０７／０２）

序

はじめに

この解説書は、できる限り初心者向けに解説をすることを心がけて記述しましたが、細かく書
きすぎますと終わりが見えなくなってしまいます。
どの程度で記述したら良いのか非常に迷いましたが、とりあえず独断と偏見で一方的に決めさせてもらいました。
程度として、マイクロコンピュータ（マイコン）の基礎をだいたい理解しており、アセンブラおよびコンパイラは最低でも１回以上は使用したことのある方を前提にして解説を進めていきた
いと思います。
また私自身も解説書を書くのは始めての経験であり、至らないところもあると思いますが皆様のご意見やご質問をもとに改訂を進め、よりよい解説書にしていきたいと思っておりますので、ご協力のほどよろしくお願いします。

エーワン㈱ 開発部 長谷川正博
URL: http://www.aone.co.jp
mail: hasegawa@aone.co.jp［参考文献］
高速８ビットマイクロコントローラ ＫＬ５Ｃ８０１６ＣＦＰ ハードウェアマニュアル
川崎マイクロエレクトロニクス㈱ＬＳＩＣ−８０（Ｖｅｒ３．６）ユーザーズマニュアル
エル・エス・アイ ジャパン㈱筋書および概説

本書は、評価ボード（ＢＦＥ２０４ エーワン㈱製）と超小型マイコン（ＣＡＴ２０３ エーワ
ン㈱製）とバグファインダー（ＢＦ３０００ エーワン㈱製）の教材を使用しながら、基礎から積み上げてテーマの完成を目指す実践解説書です。
マイコンのソフト開発には、全部ポーリングで済む場合と多種多用な要求に対応するため割り込みを駆使するシステムの２通り考えられます。
最近は、全部ポーリングで済むようなシステムは殆ど無く、生かさず殺さずの状態で割り込みを駆使するシステムばかりです。
（個人的な感情がかなり入っています）
しかし、いきなり割り込み記述が登場しますと敷居が高く感じられてしまいますし、基礎を解説す
るにはチョット複雑になってしまいますので、あえて同じテーマを全ポーリングで作成した場合と、割り込みを使用して作成した場合の２通りを載せることにしました。
同じテーマを割り込み未使用／使用で作成した場合の個性がでるよう工夫をしたつもりですので違いが分かって頂けると幸いです。
最終テーマですが、評価ボードに付いているブザーを使い簡単な曲を奏でる？？装置名“メロディ♪♪”です。
かなり音痴な奴ですが、広く大きな心で我慢して聞いてやってください。
なお、本書での開発用ソフトウェアは、エル・エス・アイ ジャパン㈱製のＬＳＩＣ−８０（Ｖｅｒ３．６）を使用しています。

※ＬＳＩ Ｃ−８０ ｆｏｒ ＢＦ３０００を使用して、本文中のｋｍｍｍａｋｅ．ｅｘｅを実行する場合には、“ｋｍｍａｋｅ −ｆ ＭＡＫＥＤＯＳ”とコマンドを打ってください。

目次

ハード構成およびシステム構成 .....................................................................................................................3
第１章 ハード構成.......................................................................................................................................3
第２章 システム構成 ...................................................................................................................................6
１．システムブロック図（メロディ♪♪）.............................................................................................6
２．ＣＡＴ２０３のプログラムメモリＭＡＰ.........................................................................................7
３．評価ボードのディップ SW の設定とＩ／Ｏマップ表.....................................................................7
４．とにかく動かしてみましょう！！....................................................................................................9
第１部 ポーリング編 ................................................................................................................................. 13
第１章 スタートアップと MMU..............................................................................................................13
１．動かしてみましょう .........................................................................................................................13
２．プログラムリスト.............................................................................................................................14
３．保守ツール（ＭａｋｅＦｉｌｅ）..................................................................................................18
第２章 ＬＳＩＣによるスタートアップとＭＭＵ...................................................................................24
１．動かしてみましょう .........................................................................................................................24
２．プログラムリスト.............................................................................................................................25
３．保守ツール（ＭａｋｅＦｉｌｅ）..................................................................................................40
第３章 ＰＩＯ.............................................................................................................................................42
１．動かしてみましょう .........................................................................................................................42
２．プログラムリスト.............................................................................................................................44
第４章 ＰＩＯの応用（ＬＣＤ）..............................................................................................................53
１．動かしてみましょう .........................................................................................................................53
２．プログラムリスト.............................................................................................................................54
第５章 タイマ／カウンタ..........................................................................................................................66
１．動かしてみましょう .........................................................................................................................67
２．プログラムリスト.............................................................................................................................68
第６章 ＵＳＡＲＴ.....................................................................................................................................79
１．動かしてみましょう .........................................................................................................................79
２．プログラムリスト.............................................................................................................................80
第 7 章 総合デモ（メロディ）..................................................................................................................95
１．動かしてみましょう .........................................................................................................................95
２．プログラムリスト.............................................................................................................................96
第２部 割込み編....................................................................................................................................... 108
第１章 タイマ割込み .............................................................................................................................. 108
１．スタートアップを割り込み用に変更する。................................................................................ 108
２．タイマモジュールを割り込み用に変更する。.............................................................................113
３．メインコントロール部を割り込み用に変更する。.....................................................................117

1

第２章 ＵＳＡＲＴ割込み....................................................................................................................... 127
１．スタートアップを変更する。....................................................................................................... 127
２．ＵＳＡＲＴモジュールを割り込み用に変更する。.................................................................... 131
３．メインコントロール部の割り込みコントローラを変更する。................................................. 137
第３章 割込み総合デモ（メロディ） ................................................................................................... 143
１．総合デモ（メロディ）を割り込み対応にする。........................................................................ 143

2

ハード構成およびシステム構成
第１章 ハード構成
この解説書を進めるにあたり、下記ハード構成の準備をお願いします。

ＣＡＴ２０３変換基板
ＢＦ３０００
専用シリアル線
超小型マイコン
ＣＡＴ２０３

RS232C 線
ＤＯＳ／Ｖ機

評価ボード ＢＦＥ２０４

DC 5V

［接続例］

3

ＢＦＥ２０４とＣＡＴ２０３接続の為の変換基板について
・ＢＦＥ２０４評価基板をＣＡＴ２０３ボードで使用するためには、コネクタ変換基板を作成するする必要があります。
・変換基板作成にあたり以下の部品が必要となります。
４０Ｐ基板取付け用フラットコネクタ メス（ＣＡＴ２０３接続用）
３０Ｐ基板取付け用フラットコネクタ オス（ＢＦＥ２０４接続用）
３４Ｐ基板取付け用フラットコネクタ オス（ＢＦＥ２０４接続用）
ユニバーサル基板
配線材

２ヶ
１ヶ
１ヶ
適量
適量

・次ページの回路図をもとに変換基板を作ってみました。

基板表

基板裏
ＢＦＥ２０４基板に取付けてみたのが、左の写真です。
この上に、ＣＡＴ２０３基板が取付けられます。
※今回作成した変換基板では、基板が電源コネクタを覆い隠してしまうで、電源コネクタが追加されています。

4

CAT203(KL5C80A16)で BFE204 BF3000 評価ボードを使用する場合の変換基板の回路図です。
BFE204 評価ボードコネクタ

CN1
BFMOD 1A
GND 1BLCD D7 2A
LCD D6 2B
LCD D5 3A
LCD D4 3B
LCD D3 4A
LCD D2 4B
LCD D1 5A
LCD D0 5B
6A
6B
7A
7B
8A
8B
9A
9B
10A
10B
11A
11B
12A
12B
13A
13B
14A
14B
15A
15B
16A
16B
LCD E 17A
LCD RS 17B

CAT203 コネクタ
CN1
CN2
1A TXD0
5V 1A
1B RXD0
5V 1B
2A GND
GND 2A
2B GND
GND 2B
3A TXD1
P00 3A
3B RXD1
P01/OUT1 3B
4A BAT+
P02/OUT2 4A
4B GND
P03/OUT4 4B
5A IP40
P04/GATE0/TRXC0 5A
5B IP41
P05/GATE1/TRXC1 5B
6A IP42
P06/GATE2 6A
6B IP43
P07/GATE3 6B
7A IP44
P10/SCK1 7A
7B IP45
P11/RAS 7B
8A IP46
P12/CAS 8A
8B IP47
P13/UASEL 8B
9A OP50
P14/RXRDY1 9A
9B OP51
P15/TXRDY1 9B
10A OP52
P16/DACK1 10A
10B OP53
P17/EXBACK 10B
11A OP54
P20/IR0/IR2 11A
11B OP55
P21/IR1/IR5 11B
12A OP56
P22/IR14 12A
12B OP57
P23/IR15 12B
13A OP60
P24/DREQ0 13A
13B
13B OP61
P25/DREQ1
14A OP62
P26/EXREQ 14A
14B
14B OP63
P27/MNI
15A OP64
P30/DTRI 15A
15B OP65
P31/RTS1 15B
16A
16A OP66
P32/TXD1
16B
16B OP67
P33/TXS1
17A OP70
P34/DSR1 17A
17B OP71
P35/CTS1 17B
18A
18A OP72
P36/RXD118B OP73
P37/RXS1 18B
19A OR74
RXS0 19A
19B OP75
TXS0 19B
20A OP76
CSK0 20A
20B
20B OP77
OUT0

5

CN2
15B 5V15A 5V
14B GND
14A GND
13B RXD
13A TXD
12B LED0(P20)
12A LED1(P21)
11B LED2(P22)
11A LED3(P23)
10B LED4(P24)
10A LED5(P25)
9B LED6(P26)
9A LED7(P27)
8B PushSW0(P30)
8A PushSW1(P31)
7B PushSW2(P32)
7A PushSW3(P33)
6B P006A OUT1
5B OUT2
5A OUT3
4B ﾄｸﾞﾙ SW0(P40)
4A ﾄｸﾞﾙ SW1(P41)
3B ﾄｸﾞﾙ SW2(P42)
3A ﾄｸﾞﾙ SW3(P43)
2B ﾄｸﾞﾙ SW4(P44)
2A ﾄｸﾞﾙ SW5(P45)
1B ﾄｸﾞﾙ SW6(P46)
1A ﾄｸﾞﾙ SW7(P47)

第２章 システム構成
装置名：“メロディ♪♪”のシステムブロック図およびメモリマップとＩ／Ｏ表を記述します。
細かい説明は後の章にまかせ、ここではハードの全体像をつかんで下さい。
［評価ボード回路図］“￥評価ボード￥第３部資料￥評価ボード（ＢＦＥ２０４）図面￥＊．ｐｄｆ”参照［ＣＡＴ２０３回路図］“￥評価ボード￥第３部資料￥超小型マイコン（ＣＡＴ２０３）図面￥＊．ｐｄｆ”参照
１．システムブロック図（メロディ♪♪）

超小型マイコン
ＣＡＴ２０３（エーワン㈱製）
ＫＬ５Ｃ８０１６ベース
CPU クロック 7.3728ＭＨｚ

OP60→OP67
P20：P21

ｷｬﾗｸﾀﾀｲﾌﾟ LCD ﾓｼﾞｭｰﾙ
LCD1
DM1602F

P10→P17

LED1−＞LED８ ８点◎◎◎◎◎◎◎◎

P02/OUT2

RS232C(TXD)
RS232C(RXD)

ブザー１個
ディップ SW１１
DIP-SW11
２点
1…シリアル折り返し
2…未使用

P04→P07

押しボタンスイッチ
P30−＞P33［PB］４点

P30→P37

トグルスイッチ
P40−＞P47［SW］８点

6

２．ＣＡＴ２０３のプログラムメモリＭＡＰ
０番地

基板付フラッシュＲＯＭ

電源ＯＮ時又はリセット時のＰＣ位置（ＳＳＴ３９ＳＦ０１０Ａ）

１２８Ｋバイト
０ｘ１ＦＦＦＦ番地

ＲＡＭ
１２８キロバイト

０ｘＥ００００番地
０ｘＦＦＦＦＦ番地

初期スタックポインタ位置（プログラムで設定します）

３．評価ボードのディップ SW の設定とＩ／Ｏマップ表
ＳＷ１１の設定
ＳＷ１１−１

ＯＮ
シリアルＩ／ＯのTXD,RXD を折り返し

ＳＷ１１−２ＯＦＦ
シリアルＩ／ＯのTXD,RXD 間オープン
未使用

ＬＣＤ関係（ピン番号は CAT203 のコネクタピン番号です。
）
ﾎﾟｰﾄｱﾄﾞﾚｽ

ﾎﾟｰﾄｼﾝﾎﾞﾙ

０ｘ６０
（拡張）

PORTOP6

０ｘ３Ｃ

PORT2

ピン番号
CN1-13A
1-13B
1-14A
1-14B
1-15A
1-15B
1-16A
1-16B
CN2-11A
-11B
-12A
-12B
-13A
-13B
-14A
-14B

ﾋﾟﾝｼﾝﾎﾞﾙ
OP60
OP61
OP62
OP63
OP64
OP65
OP66
OP67
P20
P21
P22
P23
P24
P25
P26
P27

7

方向
出力
出力
出力
出力
出力
出力
出力
出力
出力
出力

信号名
D0 LCD-module
D1
D2
D3
D4
D5
D6
D7
E LCD-module
RS LCD-module
未使用
未使用
未使用
未使用
未使用
未使用

ＬＥＤ関係（ピン番号は CAT203 のコネクタピン番号です。
）
ﾎﾟｰﾄｱﾄﾞﾚｽ

０ｘ３Ａ

ﾎﾟｰﾄｼﾝﾎﾞﾙ

PORT1

ピン番号
CN2-7A
2-7B
2-8A
2-8B
2-9A
2-9B
2-10A
2-10B

ﾋﾟﾝｼﾝﾎﾞﾙ
P10
P11
P12
P13
P14
P15
P16
P17

方向

信号名
LED1
LED2
LED3
LED4
LED5
LED6
LED7
LED8

出力
出力
出力
出力
出力
出力
出力
出力

ブザー関係（ピン番号は CAT203 のコネクタピン番号です。
）
ﾎﾟｰﾄｱﾄﾞﾚｽ
０ｘ３８

ﾎﾟｰﾄｼﾝﾎﾞﾙ
TCNT2

ピン番号
CN2-4Aﾋﾟﾝｼﾝﾎﾞﾙ
OUT2仕様
ＰＷＭモード パルス出力

押しボタンスイッチ関係（ピン番号は CAT203 のコネクタピン番号です。
）
ﾎﾟｰﾄｱﾄﾞﾚｽ

０ｘ３８

ﾎﾟｰﾄｼﾝﾎﾞﾙ

PORT0

ピン番号
CN2-3A
2-3B
2-4A
2-4B
2-5A
2-5B
2-6A
2-6B

ﾋﾟﾝｼﾝﾎﾞﾙ
P00
P01
P02
P03
P04
P05
P06
P07

方向

信号名
未使用
未使用

出力

（ﾌﾞｻﾞｰで使用）
未使用

入力
入力
入力
入力

SW12
SW13
SW14
SW15

PB[P30]PB[P31]
PB[P32]
PB[P33]

トグルスイッチ関係（ピン番号は CAT203 のコネクタピン番号です。
）
ﾎﾟｰﾄｱﾄﾞﾚｽ

０ｘ３Ｅ

ﾎﾟｰﾄｼﾝﾎﾞﾙ

PORT3

ピン番号
CN2-15A
2-15B
2-16A
2-16B
2-17A
2-17B
2-18A
2-18B

ﾋﾟﾝｼﾝﾎﾞﾙ
P30
P31
P32
P33
P34
P35
P36
P37

8

方向
入力
入力
入力
入力
入力
入力
入力
入力

信号名
SW16 SW[P40]
SW17 SW[P41]
SW18 SW[P42]
SW19 SW[P43]
SW20 SW[P44]
SW21 SW[P45]
SW22 SW[P46]
SW23 SW[P47]４．とにかく動かしてみましょう！！
１）パソコン＋ＢＦ３０００＋評価ボードの接続を確認して下さい。
２）ＣＡＴ２０３のディップスイッチＳＷ１−６をＯＮにする。
（バグファインダ Ｂｏｏｔ Ｏｎ Ｒａｍモード）
３）評価ボードの電源をオンにする。
４）ＡＢＣｗｉｎを立ち上げる。
５）ＡＢＣｗｉｎの［オプション］−［環境設定］で環境設定をする。
６）ＡＢＣｗｉｎの［オプション］−［ディップスイッチ］でＢＦ３０００のディップスイッチを確認し、ディップスイッチの設定をする。
ボーレートを１１５２００ｂｐｓにしますと、［ディップスイッチ］全オフ（上側）になります。
７）ＡＢＣｗｉｎの左下Ｓｔａｒｔをクリックする。
これで、パソコンとＢＦ３０００との通信が可能になります。
８）ＡＢＣｗｉｎを使って、ＨＥＸファイルをダウンロードして下さい。
テ ー マ “ メ ロ デ ィ ♪ ♪ ” の Ｈ Ｅ Ｘ フ ァ イ ル は 、“￥評価ボード￥第 2 部割込み編￥第 3 章割込み総合デモ（メロディ）\Cat203i.hex“です。
（ダウンロードの方法は、ＡＢＣｗｉｎのＨＥＬＰを参照）
９）ダウンロードが終了しましたら、プログラムの実行をして下さい。
（ＡＢＣｗｉｎのショートＰＢのＧＯをクリック）

9これで、ＬＥＤが何やらパラパラ表示をして、ＬＣＤに文字が表示されるはずです。
ＣＡＴ２０３＆ＢＦ３０００ ｂｙ
Ｉｎｔｅｒｒｕｐｔ［Ｐ３０］

０−４−１図 オープニング表示

ここで、簡単に“メロディ♪♪”の操作手順を説明します。
ａ．まず、評価ボードにある押しボタンスイッチ（以後ＰＢと表記します）Ｐ３０を１回押してみてください。
ＰＩＯ動作モードＰＩＯ
ＳＷ［Ｐ４７］−＞ＳＷ［Ｐ４０］０−４−２図 ＰＩＯ表示

パラパラ表示していたＬＥＤが消灯します。
トグルスイッチ（以後ＳＷと表記します）Ｐ４７−＞Ｐ４０を上側（ＯＮ）にして見て下さい。
対角線上にＬＥＤが点灯します。
ちょっと寂しい仕様ですが、これがＰＩＯの仕様です。
ｂ．次に、ＰＢ［Ｐ３０］をもう１回押してみて下さい。
Ｔｉｍｅｒ動作モード
Ｔｉｍｅｒ／Ｃｏｕｎｔｅｒ
００００Ｈｚ［＋Ｐ３３−Ｐ３２］

０−４−３図 Ｔｉｍｅｒ表示

ＰＢ［Ｐ３３］でパルス出力の周波数を１００Ｈｚ単位で上げます。
ＰＢ［Ｐ３２］でパルス出力の周波数を１００Ｈｚ単位で下げます。
ＬＣＤに現周波数が表示されます。
ブザーの音で確認ができますが、きっちりと確認したい方は、評価ボードのＣＮ２−５Ｂをオシロで確認してみて下さい。

10

ｃ．再度、ＰＢ［Ｐ３０］をもう一回押してみて下さい。
ＵＳＡＲＴ（ＳＩＯ）動作モード
Ｕｓａｒｔ ８，ｎ，１［Ｐ３１］
０９６００ｂ［＋Ｐ３３−Ｐ３２］

０−４−４図 Ｕｓａｒｔ表示

ＵＳＡＲＴ（ＲＳ２３２Ｃ）調歩同期式シリアル通信のループテストです。
表示上の“８，ｎ，１”は、８ビット、パリティなし、ストップ１ビットの意味で固定になっています。
“０９６００ｂ”は、転送ボーレートです。
ＰＢ［Ｐ３３］で転送ボーレートを上げることができます。
ＰＢ［Ｐ３２］で転送ボーレートを下げることができます。
評価ボードのＳＷ１１−１をＯＮにして下さい。
ＰＢ［Ｐ３１］で送信開始／停止をします。送信データは、“ＩｎｔｅｒｒｕｐｔＳＣ”の文字
列を 1 文字ずつ空けて２回に分けて送信します。
1 回目“Ｉ ｔ ｒ ｕ ｔ Ｃ”

２回目“ ｎ ｅ ｒ ｐ Ｓ ”

受信データは、ＬＣＤの１行目に表示しますので、正常受信していますと重なり合い文字として読み取れるようになっていると思います。
ＳＷ１１−１をＯＦＦにした場合とか、ボーレートを上下させて、色々と操作してみて下さい。

11

ｄ．再度、ＰＢ［Ｐ３０］をもう一回押してみて下さい。
テーマのＭｅｌｏｄｙ（メロディ♪♪）です。
ＭｅｌｏｄｙＰ３１［Ｍ］３３［ス］３２［セ］

０−４−５図 Ｍｅｌｏｄｙ表示

ＰＢ［Ｐ３１］でモード変更出来ます。
（ｏｎトグル）Ｐ３１［Ｍ］：手動演奏モード
ＳＷ［Ｐ４０］−＞ＳＷ［Ｐ４７］をｏｎ／ｏｆｆしてみて下さい。
Ｐ３１［Ａ］：自動動演奏モード
３曲登録してあります。
（ネコフンジャッタ、イヌノオマワリサン、アマリリス）ＰＢ［Ｐ３２］で曲を選択して下さい。
ＰＢ［Ｐ３３］で演奏の開始／停止になっています。
ここまでの説明で、最終目標の“メロディ♪♪”の仕様が理解していただけたでしょうか？
いよいよ、これから基礎から積み上げながら、システム名：“メロディ♪♪”の解説およびソフトウェア
開発を進めていきます。
次で説明する第１部ポーリング編は、システム名：“メロディ♪♪”を割込みを一切使用せずに全ポーリング仕様で書いた場合の説明です。
そして第１部が終了しますと、第２部割込み編として割込み処理を取り入れ、よりスムーズなシステムに変更します。
これが、テーマ“メロディ♪♪”になるわけです。

12

第１部 ポーリング編
第１章 スタートアップと MMU
ここの章では、スタートアップ（電源ＯＮ時もしくはリセット時）の説明をします。
ＫＣ８０の場合、ＭＭＵもスタートアップ時に設定したほうが望ましいので、一緒に説明します。
また、この章のみ全アセンブラーにて、１本のソースで記述しました。
まずは、ＡＢＣｗｉｎのダウンロードで￥評価ボード￥第１部ポーリング編￥第１章スタートアップ MMU￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ１．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
なにかＬＥＤがパラパラ表示しているはずです。
このソフトは単純に２０ｍｓ毎にＬＥＤを１ビット左シフトしながら点灯させているだけのソフトです。
それでは、プログラムリストを見てみましょう！

13

２．プログラムリスト
説明しやすくするため、わざとＥＱＵ等の擬似命令はできる限り使用を制限しました。
file “StartupA.asm”
1: ;/****************************************************************************/
2: ;/* ＜サンプル＞ ポーリング*/
3: ;/**/
4: ;/*＜MOD＞
StartupA.asm*/
5: ;/*＜役割＞
main*/
6: ;/*
＜タブ＞
４タブ編集
*/
7: ;/*
スタートアップ (CAT203-KL5C8016)*/
8: ;/****************************************************************************/
9: ;/****************************************************************************/
10: ;/*
スタートアップ*/
11: ;/****************************************************************************/
12:CSEG
13: StartUp̲:
14:
ORG
0
15:
DI
;* ﾘｾｯﾄで DI になっていますがﾃﾞﾊﾞｯｶｰで"G 0"よう
16:
LD
SP,0xFFFF;* ｽﾀｯｸﾎﾟｲﾝﾀの設定
17: ;/****************************************************************************/
18: ;/*
ＭＭＵの初期設定*/
19: ;/****************************************************************************/
20:
LD
A,0x3e;* 物理 0xFFC00 論理 0xFC00 の設定
21:OUT(0x6),A;* MMU の R4 を使用する
22:
JP
main̲
23: ;/****************************************************************************/
24: ;/*
メイン*/
25: ;/****************************************************************************/
26:
ORG
0x200
27: main̲::
28:
LD
A,0x30;* SCR4
外部ﾒﾓﾘ 0Wait 外部 I/O 1Wait
29:
OUT(0x1F),A
30:
LD
A,0xFF;* PIO P1 全出力設定 LED 点灯のため
31:
OUT(0x3B),A
32:
LD
D,1;* LED
表示パターン33: loop::
34:
LD
A,D
35:
CPL
;* PORT
0=点灯のため
36:
OUT(0x3A),A;* PORT
出力（LED 点灯）
37:
LD
B,20
;* 20ms
Wait
38: wait20ms::
39:
CALL
Wait1ms
40:
DJNZ
wait20ms
41:
RLC
D
42:
JR
loop
14

43: ;/****************************************************************************/
44: ;/*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
45: ;/****************************************************************************/
46: Wait1ms::
47:
PUSH
HL
48:
LD
HL,1228;* 1228*6=7372cyc */49: W01:50:
DEC
HL;* cyc = 1
51:
LD
A,L
;*
= 1
52:
OR
H
;*
= 1
53:
JP
NZ,W01
;*
= 3
54:
POP
HL
;*
+= 6
55:
RET
56: ;
57:
END

15

［リストの説明］
１〜１１行：
コメントです。
１２行：“ＣＳＥＧ”は、リンカにこれからのプログラムはコードセグネントだと教えるための擬似命令です。
１３行：ラベルです。
１４行：“ＯＲＧ ０”は、ここからのオフセットアドレスを指定する擬似命令です。
リンク時に、＃ＣＯＤＥでコードセグネントの先頭アドレスを指定しますので、そのアドレスのオフ
セットアドレスになるわけです。
１５行：
電源ＯＮ時およびリセット時にプログラムはココから実行を始めます。
命令“ＤＩ”の意味は割込み禁止です。このサンプルでは割込み未使用なため不要ですが、プログラ
ムミスでＥＩ（割込み許可状態）になってしまい暴走し、デバッカで“Ｇ ０”などした場合に都合が良いためただ入れてあります。
まあ定石だと思って下さい。
なお電源ＯＮ時およびリセット時は、ＣＰＵ自身“ＤＩ”状態です。
１６行：
スタックポインタ（ＳＰ）の初期値設定です。
これは絶対必要で、通常ＲＡＭの最終番地を指定するのが標準になっています。
ただ、ＳＰ動作は必ず−１して動作するため、この例ですと０ｘＦＦＦＦ番地は使用しないことになります。
フルにＲＡＭを使用したい場合は、“ＬＤ ＳＰ，０”になるわけですが、私個人の意見としては直感的でない数字のためこの方法は使用しないようにしています。
２０，２１行：
ＫＣ８０特有のＭＭＵ設定の部分です。
詳細はハードウェアマニュアルに記載されていますので、ここではこの２行の説明をします。
このサンプルのようにＭＭＵを頻繁に使用せず、初期化１回設定ですむようなシステムの場合は、Ｒ
ＡＭ領域設定にＲ４を使用するのが定石になっています。
なぜかと言いますと、ＭＭＵのＢＲ４は０ｘＦ０固定になっており、物理アドレスベースが０ｘＦ０
０００になりますので都合が良い事になります。
ＣＡＴ２０３の場合、物理アドレスで０ｘＥ００００〜０ｘＦＦＦＦＦ番地がＲＡＭになっています
ので、ＢＢＲ４の論理アドレス境界値の設定のみで済みます。
論理アドレス境界値の最小単位は０ｘ４００ですので、０ｘＦＣ００より０ｘＦＦＦＦが、ＲＡＭとして使用できるようになります。
［アドレス境界値計算式］
論理アドレス境界設定値＝（論理アドレス境界値÷０ｘ４００）−１
０ｘ３ｅ＝（０ｘＦC００÷０ｘ４００）−１
ＢＢＲ４の上位２ビットは、ゼロ固定になっていますので設定値“０ｘ３ｅ”が得られたことになります。
ＢＢＲ４のＩ／Ｏアドレスは、０ｘ６番地ですので、この２行の記述になります。
２２行：“ＪＰ ｍａｉｎ＿”メイン処理へのジャンプ命令になります。
16

ここまでがポーリングで済む場合の、世でいう“スタートアップ”になるわけです。
どうです簡単でしょう！！
２３行目以降は、このサンプルソフトが動作しているかを目で確かめるために用意したソフトです。
ＬＥＤ点灯部分等は、後章ＰＩＯ編で説明しますので、ここでは省略します。

17

３．保守ツール（ＭａｋｅＦｉｌｅ）
コンパイル・アセンブリ・リンケージエディタを管理／制御する保守ツールは、ｋｍｍａｋｅ．ｅｘｅ（ＬＳＩＣ−８０パッケージに添付）を使いました。
“ＭａｋｅＦｉｌｅ”にこのプロジェクト（テーマ）の定義をしておけば、“ｋｍｍａｋｅ”とコマンドを打つだけで、自動で修正したソースだけを探して、コンパイル・アセンブリ・リンクを実行してくれる便利なツールです。
ＭａｋｅＦｉｌｅの仕様は、ＬＳＩＣ−８０のマニュアルに記載されていますが、簡単ではありますが、ここでちょっと説明をしておきます。
１）この章のサンプルで使用したＭａｋｅＦｉｌｅの中身
file “MakeFile”
1: #2: # Makefile for KC80 LSIC-80 by AONE
3: #4: # （kmmake にて実行する）
5: #
6: # ４タブ編集
7: #
8: # 関係拡張子の登録（下記以降での拡張子記述は必ず小文字の事）
9: #10: .SUFFIXES: .sof .asm .asz .psm .psz .mac .c .h .hex
11:
12: # プロジェクト名(SAMPLE.xxx)
13: PROJ = Cat203p1
14:
15: # ライブラリー格納ディレクトリ名
16: LIB= s:\lsij\lsic80\lib
17:
18: # ユザー作成のヘッダーファイル名
19: HEDS =20:
21: # ユザー作成のオブジェクトファイル名
22: OBJS = StartupA.sof
23:
24: # コンパイル／アセンブラ コマンド名
25: CC80 = LCC80
26: ASM80 = rz80
27:
28: # ＬＣＣ８０ コンパイル スイッチ説明
29: #-z80 Ｚ８０で実行可能な命令が生成されます
30: #-r 3 ﾊﾞｲﾄ JMP を２ﾊﾞｲﾄ BRA に変更
31: #-c コンパイル時にリンクは実行しません
32: #-cn コメントのネスト許可
33: #-cv クラスＤＡＴＡに配置された変数を宣言順番に生成します
34: #-g1 行番号情報とグローバル変数情報を生成する
35: #-j1 エラーメッセージを日本語で表示します
1836: #-v1 実行しているコマンドを表示します
37: #-wi 宣言をしていない関数を使用する場合の警告メッセージを抑えます
38: CFLAGS = -z80 -r -c -cn -cv -g1 -j1 -v1 -wi
39:
40: # ｒｚ８０ アセンブリ スイッチ説明
41: #-g 行番号情報を生成する
42: #-ｒ Ｃと同様な数値記述を許す
43: ASMFLAGS = -g -r
44:
45: # リンカーコマンド名
46: LINK = knil
47:
48: # リンカー指定 注意 各行の先頭は、タブ（ＴＡＢ）送りする。
49: $(PROJ).hex : $(OBJS)
50: $(LINK) @${
51:
-v
52:
-tH
53:
-c
54:
$(PROJ).hex
55:#CODE=0000 #DATA=FE00
56:-KC80 -BB4FE00,FFE00
57:$(OBJS)
58:-f$(LIB)\clibz
59:-f$(LIB)\flibz
60:-f$(LIB)\romlibz
61:-f$(LIB)\knjlibz
62:-m$(PROJ).MAP
63:-n$(PROJ).LIN
64:
}
65: #
66: # 各リンカースイッチの説明
67: #68: # -v
# 処理の進行状況を表示します
69: # -tH
# 拡張インテルＨＥＸを指定
70: # -c
# セグメントの重複を検査します
71: # $(PROJ).hex# ＨＥＸファイル名の指定
72: # #CODE=0000# ＣＯＤＥ／ＤＡＴＡセグメントの先頭アドレスの指定
73: # #DATA=FE00
74: # -KC80 -BB4FE00,FFE00
75: ## ＫＣ８０のＭＭＵ初期状態の指定（$$Rx̲init̲value̲を作成）
76: # $(OBJS)# オブジェクト指定（スタートアップは必ずこの位置）
77: # -f$(LIB)\clibz# ライブラリ指定
78: # -f$(LIB)\flibz
79: # -f$(LIB)\romlibz
80: # -f$(LIB)\knjlibz
81: # -m$(PROJ).MAP# マップファイル名の指定
82: # -n$(PROJ).LIN# ラインファイル名の指定
19

83:
84: # 全てのオブジェクト調査
85: # all: $(OBJS)
86:
87: # オブジェクトとヘッダーの調査
88: $(OBJS) : $(HEDS)
89:
90: # コンパイル実行
91: .c.sof:
92: $(CC80) $(CFLAGS) $<93: .asm.sof:
94: $(ASM80) $(ASMFLAGS) $<20

［ＭａｋｅＦｉｌｅの説明］
１〜９行：
コメント（注釈）です。頭に“＃”を付けるとコメントになるルールです。
１０行：“.SUFFIXES”は、中で使用する拡張子の登録です。
注意としては、小文字で登録した場合は、小文字で記述して下さい。
１３行：“PROJ = Cat203p1”は、便宜上プロジェクト（テーマ）名を環境変数“PROJ”に登録しています。
環境変数は予約語と重ならない限り自由に指定できます。
１６行：“LIB = s:\lsij\lsic80\lib”も便宜上、ライブラリーの置いてあるディレクトリ名を環境変数“LIB”に登録しています。
注意としては、当社の開発環境では“ｓ：”ドライブに開発用ソフトウェアをインストールしていますので、“ｓ：￥〜”になっています。
皆様の開発環境は様々だと思います。
（重要！）ここのディレクトリ名は、各自ＬＳＩＣ−８０をインストールした場所に変更して下さい。
１９行：“HEDS =”は、プロジェクトでヘッダーファイル（定義文をまとめた）を作成した場合、便宜上この環境変数に登録しておきます。
後にでてきますが、ヘッダーファイルを変更した場合、再コンパイル／アセンブリが必要ですのでここに登録しておきます。
２２行：“OBJS = StartupA.sof”は、プロジェクトを作成するにあたり、作成したプログラムモジュールのオブジェクト（コンパイル／アセンブリが作成する）名を便宜上この環境変数に登録しておきます。
ＬＳＩＣ−８０では、“＊．ｓｏｆ”になります。
２５行：“CC80 = LCC80”は、コンパイラのコマンド名を登録しています。
２６行：“ASM80 = rz80”は、アセンブラのコマンド名を登録しています。
３８行：“CFLAGS = -z80 -r -c -cn -cv -g1 -j1 -v1 –wi”は、コンパイルを実行する時のスイッチを登録しています。
４３行：“ASMFLAGS = -g –r”は、アセンブラを実行する時のスイッチを登録しています。
４６行：“LINK = knil”は、リンカーコマンド名の登録です。
４９行：“$(PROJ).hex : $(OBJS)”は、前に登録した（プロジェクト名）．ｈｅｘと（オブジェクト名リスト）の作成時期の関係を調べます。
（プロジェクト名）．ｈｅｘのほうが古い（昔にできた）場合、次行のリンクコマンドを実行させるための判定文です。
“このへんが自動で判断してくれるのでヒジョウに便利です。
”
５０行：
リンクコマンドの発行とリンクスイッチのリストです。
“＠”は、ファイルからコマンド行を読み込む指示です。
“＄｛．
．
．
．
．
｝
”は、
“｛”と“｝”の間のリンクスイッチリストを展開後“ｍａｋｅ．ｉ”ファイルに作成されます。
21

注意事項として、各行の先頭は、<TAB>送りをしてください。
そうしないと正しく“ｍａｋｅ．ｉ”が作成されません。
５１〜６３行：
リンクコマンドスイッチを指定しています。
８８行：“$(OBJS):$(HEDS)”は,オブジェクトとヘッダーファイルの作成時期の関係を調べます
オブジェクトのほうが古い（昔にできた）場合、次行のコンパイル又はアセンブリを実行します。
９１行：“.c.sof:”は、Ｃソースファイル“．ｃ”とオブジェクトファイル“．ｓｏｆ”の作成時期の関係を調べます。
この場合は、オブジェクトが古い（昔にできた）場合、次行のコンパイルコマンドを実行します。
９３行：“.asm.sof:”は、Ａｓｍソースファイル“．ａｓｍ”とオブジェクトファイル“．ｓｏｆ”の作成
時期の関係を調べます。
この場合も、オブジェクトが古い（昔にできた）場合、次行のアセンブリコマンドを実行します。
今後、新規プロジェクトを開発することになり、ＭａｋｅＦｉｌｅを作成する必要になった場合、このＭａｋｅＦｉｌｅの１３、１９、２２行の変更で対応することが出来ると思いますので参考にして頂ければ幸いです。

22２）ｋｍｍａｋｅの実行
一度、ｍａｋｅの便利さを実感して見ましょう。
このサンプルでＬＥＤを２０ｍｓ毎にシフト表示しているのを１００ｍｓ毎に変更してみましょう。
“ＳｔａｒｔｕｐＡ．ａｓｍ”をエディタで開き
36:
OUT(0x30),A;* PORT
出力（LED 点灯）
37:
LD
B,20
;* 20ms
Wait
38: wait20ms::
３７行目の“２０”を“１００”に変更してみてください。
37:
LD
B,100
;* 100ms
Wait
変更後、保存終了して下さい。
保存終了が済みましたら、“ｋｍｍａｋｅ”を実行してみて下さい。
このような実行結果が表示されるはずです。

ＭａｋｅＦｉｌｅのご利益により、プロジェクト名：Ｃａｔ２０３ｐ１．ｈｅｘが新しく作成されました。
評価ボードにダウンロードして、実行してみて下さい。
どうです！！ＬＥＤのシフト表示スピードが遅くなりましたので、目で確認できるようになったはずです。
プログラムデバック作業は、簡単に言えばこの繰り返しです。
思ったように動かない場合は、デバッカでブレークをあてたり、メモリの内容を見たり、レジスタの内容を見たりして、間違いを探し、見つかったらソースを修正し“ｋｍｍａｋｅ”を実行して“＊．Ｈｅｘ”ファイルを作成し、ターゲットにダウンロードして、実行させ、再び確認する。
気の遠くなるような作業を何度も何度も繰り返し、仕様どうりのプログラムを完成させるわけです。
簡単ではありますが、プログラム開発の流れはだいたい掴んで頂けたかと思います。
第１章は、ここまでとし、次へのステップとして、Ｃ言語でのプログラム開発方法へと進めていきたいと思います。
23

第２章 ＬＳＩＣによるスタートアップとＭＭＵ
ここの章では、第１章の仕様そのままにして、ｍａｉｎ（）をＣ言語でプログラムした場合どのような仕組みでＨＥＸファイルが作られるのかを解説します。
まずは、ＡＢＣｗｉｎのダウンロードで￥評価ボード￥第１部ポーリング編￥第２章ＬＳＩＣによるスタートアップとＭＭＵ￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ２．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
前章とまったく同じ動作のはずです。
それでは、プログラムリストを見てみましょう！

24

２．プログラムリスト
今後の移植性および役割分割のため、ソースを３ファイルに分割しました。
１）“ＳｔａｒｔｕｐＢ．ａｓｍ”スタートアップは、章が上がっても利用できるよう汎用化しました。
２）“Ｃａｔ２０３ｐ２．ｃ”メイン処理は、この章のメインコントロール部です。章が上がっていきますとこれをベースに追加していきます。
３）“Ｐ＿Ｐｉｏ１．ｃ”ＬＥＤ表示は、このサンプルソフトが動作しているかを目で確かめるために用意したソフトです。
ＬＥＤ点灯部分等は、後の章ＰＩＯ編で説明しますので、ここでの説明は省略します。
Ｃ言語の多モジュル化した場合に、定義文等を他のモジュールでも利用できるようにヘッダーファイル
を３ファイル作成しました。
１）“ＣＡＴ２０３．ｈ”は、ＣＡＴ２０３（超小型マイコン）の使用するＩ／Ｏ番地をシンボル定義でまとめたファイルです。
２）“ＫＣ８０１６ＩＯ．ｈ”は、ＣＡＴ２０３（超小型マイコン）が使用しているＣＰＵ（ＫＬ５Ｃ
８０１６）の内部Ｉ／Ｏをシンボル定義でまとめたファイルです。
“ＣＡＴ２０３．ｈ”
が使用しています。
３）“ＤｅｍｏＣｔｌ．ｈ”は、サンプルプログラムを見やすくするためのシンボル定義集とモジ
ュール別に出来上がった関数のプロトタイプ宣言をまとめたファイルです。
章が上がることに、これをベースに追加していきます。
なお、［リストの説明］で前章と説明がダブル個所は省略します。

25

*１）スタートアップ（プログラム）
今回はリストを読みやすくするためＥＱＵ等の擬似命令を使用しました。
file “StartupB.asm”
1: ;/****************************************************************************/
2: ;/*＜MOD＞
StartupB.asm*/
3: ;/*＜役割＞
スタートアップ (ポーリング専用 CAT203-KL5C80A16)*/
4: ;/*
リンクの都合上、先頭に指定することが絶対条件*/
5: ;/*$$Rx̲init̲value̲は、knil（リンク）で作成されます。
*/
6: ;/*
＜タブ＞
４タブ編集
*/
7: ;/****************************************************************************/
8: STACK
EQU
0xFFFF; ｽﾀｯｸﾎﾞﾄﾑ
9: BBR1
EQU
0x0; KL5C8016(MMU) BBR1
10: BR1
EQU
0x1
;
BR1
11: BBR2
EQU
0x2
;
BBR2
12: BR2
EQU
0x3
;
BR2
13: BBR3
EQU
0x4
;
BBR3
14: BR3
EQU
0x5
;
BR3
15: BBR4
EQU
0x6
;
BBR4
16: BR4
EQU
0x7
;
BR4
17: ;/****************************************************************************/
18: ;/*
スタートアップ*/
19: ;/****************************************************************************/
20:CSEG
21: StartUp̲:
22:
ORG
0
23:
DI
24:
LD
SP,STACK
25: ;/****************************************************************************/
26: ;/*
ＭＭＵの初期設定*/
27: ;/****************************************************************************/28:
LD
A,LOW $$R1̲init̲value̲##29:
OUT(BBR1),A30:
LD
A,HIGH $$R1̲init̲value̲##31:
OUT(BR1),A
32:
LD
A,LOW $$R2̲init̲value̲##33:
OUT(BBR2),A34:
LD
A,HIGH $$R2̲init̲value̲##35:
OUT(BR2),A
36:
LD
A,LOW $$R3̲init̲value̲##37:
OUT(BBR3),A38:
LD
A,HIGH $$R3̲init̲value̲##39:
OUT(BR3),A
40:
LD
A,LOW $$R4̲init̲value̲##41:
OUT(BBR4),A
42:
JP
main̲##
26

43: ;/****************************************************************************/
44: ;/*
終了（C ｿｰｽへのｴﾝﾄﾘｰ）*/
45: ;/****************************************************************************/
46:
ORG
0x200
47:
END

27

［リストの説明］
１〜７行：
コメントです。
４行のコメントに記載してありますが、このモジュールをアセンブリして出来あがったオブジェクト“ＳｔａｒｔｕｐＢ．ｓｏｆ”は、リンク時に必ず１番目で指定して下さい。
８〜１６行：
使用している数値をシンボル化する EQU 定義文です。
前章と比べてみて下さい。
２８〜４１行：
MMU に対する初期設定文です。
文中にでてくる“$$Rn_init_value_”は、リンク（ｋｎｉｌ）の“−Ｂ”スイッチで指定する物理ア
ドレスに対する論理アドレス指定と使用するＲｎの指定で作成されます。
（ｎ＝１〜４）
実際に出力される“$$Rn_init_value_”の数値は、リンクで作成されるファイル“＿ｍｍｕｉｎｉｔ．
ａｓｚ”を読めば確認できます。
なお、“$$Rn_init_value_”の最後に“##”が書いてありますが、これはアセンブラ（ｒｚ８０）の擬似命令で外部参照（ＥＸＴＲＮ）を意味しています。
４２行：
Ｃ言語記述の“ｍａｉｎ（）”へのエントリーです。
“ｍａｉｎ＿”と最後に“＿”（アンダーバー）がついていますが、これは C 言語で宣言したシンボルに対して付加されます。
リンクスイッチで“＿”を取ることもできますが、ＣとＡＳＭの区別のためあったほうが良いかもしれません。
（皆様の自由です）
４６行：“ORG 0x200”は、C 言語記述のオブジェクトを離すためにいれました。
メモリがもったいないと思う方は削除しても構いません。
４７行：“END”は、アセンブラソースの最後を知らせる擬似命令です。
必ず入れて下さい。

28*２）メイン処理（プログラム）
file “Cat203p2.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p2.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
変数宣言*/
17: /****************************************************************************/
18:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/19: /****************************************************************************/
20: /*
main()*/
21: /****************************************************************************/
22: voidmain(void)
23: {
24:
outp(SCR4,0x30);/* SYS
ExtMem 0wait ExtIO 1wait */25:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
26:
MemInitial();/* ﾒﾓﾘ系初期化*/
27:
IoInitial();/* I/O 系初期化*/
28:
while(1) {29:
SoftWait1ms(20);/* 20msWait*/
30:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
31:
SigOutput();/* Signal Output Process(LED 点灯) */
32:
}
33: }
34: /****************************************************************************/
35: /*
Ｍｅｍ初期化*/
36: /****************************************************************************/
37: void
MemInitial(void)
38: {
39:
Shift = 0;/* Led Disp Patan Initial
*/
40:
41:
PioMemInitial();/* PIOMem 初期化*/
42: }
43: /****************************************************************************/
44: /*
Ｉ／Ｏ初期化*/29

45: /****************************************************************************/
46: void
IoInitial(void)
47: {
48:
PioIoInitial();/* PIOI/O 初期化*/
49: }
50: /****************************************************************************/
51: /*
RunRun()
CPU 走行表示*/
52: /****************************************************************************/
53: void
RunRun()54: {55:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
56:
PutOutPort(Shift,'=');
57: }
58: /****************************************************************************/
59: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
60: /****************************************************************************/
61: void
SoftWait1ms(Ushort ms)
62: {
63:
while(ms-- != 0) {64:
Wait1ms();
65:
}
66: }
67: /****************************************************************************/
68: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
69: /****************************************************************************/
70: void
Wait1ms()71: {72:
̲asm̲("\n
PUSH
HL
\n");
73:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */74:̲asm̲("\n W01:
\n");
75:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/76:̲asm̲("\nLDA,L\n"); /*
= 1*/77:
̲asm̲("\nORH\n"); /*
= 1*/78:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3*/79:
̲asm̲("\nPOP
HL\n"); /*
+= 6
*/
80: }

30

［リストの説明］
１〜１０行：
コメントです。
１２行：“#include <machine.H>”は、ＬＳＩＣ標準添付のヘッダーファイルを使用することをコンパイラに教えるステートメントです。
ポートの入出力関数（inp()､outp()等）を使用する場合、記述します。
１３〜１４行：
後で説明しますが、このテーマで使用する定義文をまとめた、ヘッダーファイルを使用することをコンパイラに教えるステートメントです。
１８行：
内部使用する変数の宣言文です。
“Uchar”は、“Cat203.h”でマクロ宣言してあるため、“unsigned char”と同じ意味を持ちます。
長い文章を入力したく無い場合よく使います。
（キー入力が苦手な日本人特有かも？）
変数名“Shift”の用途は、ＬＥＤ表示バッファーとして使用します。
２２行：“main()”関数の先頭を意味する宣言文です。
前に説明した“スタートアップ”から、ここにジャンプして来ます。
２４行：
ＣＰＵ（ＫＬ５Ｃ８０１６以後“ＫＣ８０”と略す）特有の手続き（ポート出力）です。
外部バス・ウェイト・コントロールの設定が目的です。図［２−２−１］参照
ＣＡＴ２０３は、外部メモリ（０〜７ＦＦＦＦ）＝０ｗａｉｔ、外部メモリ（８００００〜ＦＦＦＦ
Ｆ）＝０ｗａｉｔ、外部Ｉ／Ｏ＝１ｗａｉｔの設定ですので、“００１１”になり、設定値“０ｘ３０”となります。ＫＣ８０を使用する場合、必要です。
outp(SCR4,0x30);/* SYS
ExtMem 0wait ExtIO 1wait */（ＳＣＲ４＝ＣＡＴ２０３．ＨでＩ／Ｏアドレスのシンボル宣言済みです）
つまり、この行までのプログラムはデフォルトの１ｗａｉｔの状態で動作し、この行以降から０ｗａｉｔ状態で動作します。

31

システムコントロールレジスタ（ＳＣＲ４）
ﾋﾞｯﾄ

名称

７
６

外部Ｉ／Ｏ・
ウェイトコントロール

５４

外部メモリ・
ウェイトコントロール

機能
００： １ウェイト（３ｃｌｏｃｋ／バスサイクル）
０１： ２ウェイト（６ｃｌｏｃｋ／バスサイクル）
１０： ３ウェイト（５ｃｌｏｃｋ／バスサイクル）
１１： ４ウェイト（６ｃｌｏｃｋ／バスサイクル）
４ウェイトの時、EIORD̲/EIOWR̲の開始エッジが 1/2clock 遅れます。
外部メモリ（０〜７ＦＦＦＦ）

外部メモリ（８００００〜ＦＦＤＦＦ）

０Ｘ： １ウェイト
１ウェイト＊
１０： １ウェイト
０ウェイト＊
１１： ０ウェイト
０ウェイト＊＊ＤＲＡＭ使用時は、この指定には従いません。
３
−
０固定
２
端子出力切替
０：端子７６をＰ３３76･99
端子９９をＰ１０ として使用
１：端子７６をクロック同期シリアルＩ／ＯのＴＸＳ１
端子９９をクロック同期シリアルＩ／ＯのＳＣＫ１ として使用
１
端子出力切替００：端子２０をＰ０３
０
20･21･22
端子２１をＰ０２
端子２２をＰ０１ として使用
０１：端子２０をＰ０３
端子２１をＰ０２
端子２２をタイマのＯＵＴ１ として使用
１０：端子２０をＰ０３
端子２１をタイマのＯＵＴ２
端子２２をタイマのＯＵＴ１ として使用
１１：端子２０をタイマのＯＵＴ３
端子２１をタイマのＯＵＴ２
端子２２をタイマのＯＵＴ１ として使用
図[２-２-１] システムコントロールレジスタ４
２５行：
電源ＯＮ時に周辺Ｉ／Ｏが安定するまで待つソフトタイマーです。
ＣＡＴ２０３ボードを使用する場合は不要ですが、私めの定石／癖になっています。
無視して下さい。
２６行：
このテーマで使用する変数の初期化をまとめた関数です。
章が上がっていく度に追加されていきます。
電源ＯＮ時に使用ＲＡＭエリアをオールゼロにする関数をアセンブラで組む方法もありますが、今回は使用する変数一個一個を初期化する方法にしています。
２７行：
このテーマで使用するＩ／Ｏの初期化をまとめた関数です。
２８行：
電源ＯＦＦするまで無限ループをする先頭を意味するステートメントです。
“while(1) {---------}”までが無限ループ内になります。

32

２９行：
２０ｍｓ毎にＬＥＤをシフト表示させるための２０ｍｓのソフトタイマーです。
この関数を抜けて来るまで他の処理は一切しません。
（もったいないことです）
３０行：
呼ばれる毎に変数“Shift”を１ビット左シフトし、ＬＥＤ表示のため、ｏｕｔバッファーにセットする関数を呼んでいます。
３１行：ｏｕｔバッファーをポート出力する関数を呼んでいます。
３２行：
前に説明した“while(1)”の終わりを示す記号です。
３３行：“main()”関数の終わりを示す記号です。
この２３行目から始まり、３３行目で終わる集まりを“関数”または“サブルーチン”と呼んでいます。
Ｃ言語で記述した場合は、この関数の集合体でプロジェクトを完成させています。
３７〜４２行：
メモリ初期化の関数です。
４６〜４９行：
Ｉ／Ｏ初期化の関数です。
５３〜５７行：
動作表示モニタ用バッファを１ビット左シフトして、出力バッファにセットしています。
６１〜６６行：
ｍｓｅｃ単位で指定するソフトタイマ関数です。
７０〜８０行：
約１ｍｅｃのソフトタイマです。
ＣＰＵクロック＝７３７２８００Ｈｚですので、１０００Ｈｚ（１ｍｓ）で割りますとマシンサイク
ル＝７３７２サイクルになります。
１ループ６サイクルですので、７３７２÷６＝１２２８ループになります。
前章ではアセンブラで作成してありましたが、参考にして頂くためインラインアセンブラでの記述してみました。

33*３）ＰＩＯ関係（プログラム）
file “P_Pio1.c” LED 表示（動作目視用）
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Pio1.c*/
6: /* ＜役割＞
PIO 関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
変数宣言*/
17: /****************************************************************************/
18:
Uchar
OutPort;/* Out Port Buffer*/
19: /****************************************************************************/
20: /*
Ｍｅｍ初期化*/
21: /****************************************************************************/
22: void
PioMemInitial(void)
23: {
24:
OutPort = 0;/* OUT Port 初期化*/
25: }26: /****************************************************************************/
27: /*
Ｉ／Ｏ初期化*/
28: /****************************************************************************/
29: void
PioIoInitial(void)
30: {
31:
outp(PORT1,0);/* PIO P0 D0〜D3=出力未使用/D4〜D7=入力未使用 */32:
outp(PDIR1,0xFF);/*
P1 全出力 LED0〜LED7
*/
33:
/*
P2 未使用 全入力
*/
34:
/*
P3 未使用 全入力*/
35: }36: /****************************************************************************/
37: /*
SigOutput Signal Output Process(LED 出力)*/
38: /****************************************************************************/
39: void
SigOutput()
40: {
41:
outp(PORT1,~OutPort);/* 0=点灯 1=消灯 のため*/
42: }
43: /****************************************************************************/
44: /*
OutPortPut 出力バッファーにセット*/
34

45: /****************************************************************************/
46: void
PutOutPort(Uchar patan,Uchar log)
47: {
48:
if (log == '=')
OutPort = patan;
49:
else if (log == '|') OutPort |= patan;
50:
else if (log == '&') OutPort &= patan;
51: }［リストの説明］ＰＩＯについては後章で説明しますので、ここでは省略します。

35*１）ヘッダーファイル（１）file “CAT203.h”
1: /****************************************************************************/
2: /*
マクロ宣言
*/
3: /****************************************************************************/
4: #define Uchar unsigned char
5: #define Ushort unsigned short
6: #define Ulong unsigned long7:
8: /****************************************************************************/
9: /*ＫＬ５Ｃ８０Ａ１６内部（Ｉ／Ｏ番地）*/
10: /****************************************************************************/
11: #include "KC8016IO.h"12:
13: /****************************************************************************/
14: /*
ＣＡＴ−２０３（拡張Ｉ／Ｏ番地）*/
15: /****************************************************************************/
16: #define PORTIP4 0x40/* IP4 入力 PORT*/
17: #define PORTOP5 0x50/* OP5 出力 PORT*/
18: #define PORTOP6 0x60/* OP6 出力 PORT*/
19: #define PORTOP7 0x70/* OP7 出力 PORT*/
［リストの説明］
４〜６行：“unsigned”長い予約語のため、このように予約語をマクロ宣言して使用しています。
使用したくないかたは、使用しなくてもかまいません。
ただし、サンプルソースは全部修正が必要になります。
１１行：別に用意したＫＬ５Ｃ８０１６の内部Ｉ／Ｏをシンボル化したヘッダファイルをインクルードします。
１６〜１７行：
ＣＡＴ２０３の拡張Ｉ／Ｏアドレスをシンボル化しました。

36*２）ヘッダーファイル（２）file “KC8016IO.h”
1: /****************************************************************************/
2: /*ＫＬ５Ｃ８０Ａ１６内部（Ｉ／Ｏ番地）*/
3: /****************************************************************************/
4: #define BBR1
0x0/* MMU 1 境界*/
5: #define BR1
0x1
/*
ベース
*/
6: #define BBR2
0x2
/*
2 境界
*/
7: #define BR2
0x3
/*
ベース
*/
8: #define BBR3
0x4
/*
3 境界
*/
9: #define BR3
0x5
/*
ベース
*/
10: #define BBR4
0x6
/*
4 境界
*/
11: #define BR4
0x7
/*
ベース
*/
12: #define PAR0
0x10/* DMAC CH0 B-PAR C-PAR*/
13: #define SAR0
0x11/*
B-SAR C-SAR*/
14: #define BAR0
0x12/*
B-BAR C-BAR*/
15: #define CRSR0
0x13
/*
CR
SR
*/
16: #define PAR1
0x14/*
CH1 B-PAR C-PAR*/
17: #define SAR1
0x15/*
B-SAR C-SAR*/
18: #define BAR1
0x16/*
B-BAR C-BAR*/
19: #define CRSR1
0x13
/*
CR
SR
*/
20: #define SCR0
0x1B/* SYS 0 SCR0*/
21: #define SCR1
0x1C/*
1 SCR1*/
22: #define SCR2
0x1D/*
2 SCR2*/
23: #define SCR3
0x1E/*
3 SCR3*/
24: #define SCR4
0x1F/*
4 SCR4*/25: #define TCNT0
0x20/* TIM 0 CNT*/
26: #define TCWD0
0x21/*
0 CWORD/STAT*/
27: #define TCNT1
0x22
/*
1 CNT
*/
28: #define TCWD1
0x23/*
1 CWORD/STAT*/
29: #define TCNT2
0x24
/*
2 CNT
*/
30: #define TCWD2
0x25/*
2 CWORD/STAT*/
31: #define TCNT3
0x26
/*
3 CNT
*/
32: #define TCWD3
0x27/*
3 CWORD/STAT*/
33: #define K51RATE 0x28/* USART RATE*/
34: #define K51DAT0 0x2A/*
0 TXD
/RXD ･EX.STATA*/
35: #define K51COM0 0x2B/*
0 MODE･CMD/STAT･EX.STATB*/
36: #define K51DAT1 0x2C/*
1 TXD
/RXD ･EX.STATA*/
37: #define K51COM1 0x2D/*
1 MODE･CMD/STAT･EX.STATB*/
38: #define CLKDAT0 0x30/* CLKsync 0 TXD/RXD*/
39: #define CLKCOM0 0x31/*
0 MODE/STAT*/
40: #define CLKDAT1 0x32/*
1 TXD/RXD*/
41: #define CLKCOM1 0x33/*
1 MODE/STAT*/
42: #define LERL
0x34/* 割込 X LERL*/
43: #define LERH
0x35/*
X LERH*/
44: #define PGRLLERL/*X PGRL
*/37

45: #define PGRH
46: #define ISRL
47: #define ISRH
48: #define IMRL
49: #define IMRH
50: #define IVR
51: #define PORT0
52: #define PDIRX
53: #define PORT1
54: #define PDIR1
55: #define PORT2
56: #define PDIR2
57: #define PORT3
58: #define PDIR3

LERH
LERL
LERH
0x36
0x37
IMRH
0x38
0x39
0x3A
0x3B
0x3C
0x3D
0x3E
0x3F

/*
/*
/*
/*
/*
/*
/* PIO
/*
/*
/*
/*
/*
/*
/*

X PGRHX ISRLX ISRHX IMRLX IMRH
X IVR
0 PORT
ﾋﾞｯﾄ操作/方向
1 PORT
1 方向
2 PORT
2 方向
3 PORT
3 方向［リストの説明］
ＫＬ５Ｃ８０Ａ１６内部のＩ／Ｏアドレスをシンボル化しました。

38

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

*３）ヘッダーファイル（３）file “DemoCtl.h”
1: /****************************************************************************/
2: /**/
3: /* ＜役割＞
サンプルソフト特有の宣言*/
4: /* ＜TAB＞
４タブ編集
*/
5: /*
*/
6: /****************************************************************************/
8: /*
マクロ
*/
9: /****************************************************************************/
10: #define ON
0xaa/* ﾌﾗｸﾞ内部 ON ﾌﾗｸﾞ*/
11: #define OFF
0
/*
" OFF
*/
12: /****************************************************************************/
13: /*
プロトタイプ宣言*/
14: /****************************************************************************/
15: /*
Cat203p.c*/
16: void
MemInitial(void);
17: void
IoInitial(void);
18: void
RunRun();
19: void
SoftWait1ms(Ushort ms);
20: void
Wait1ms();
21: /*P̲Pio1.c*/
22: void
PioMemInitial();
23: void
PioIoInitial();
24: void
SigOutput();
25: void
PutOutPort(Uchar patan,Uchar log);39

［リストの説明］
１０〜１１行：
内部で使用するフラグ数値をシンボル化しました。
直接数字を記述しますと、数字の意味が不明になるため、シンボル化しておくと便利です。
１５〜２１行：
各モジュールで作成した関数をまとめてプロトタイプ宣言をしておきます。
特にＬＳＩＣの場合はプロトタイプ宣言が重要です。
なぜかと言いますと関数の第１引数は、データサイズによりレジスタが変わるからです。
プロトタイプ宣言をせずに、他モジュールの関数を使用した場合、第１引数はデフォルトで“ｉｎｔ”（２バイト）と判断され、コンパイラは、ＨＬレジに引数をセットします。
もとの関数の第１引数が“ｃｈａｒ”系で宣言をしてあった場合、その関数はＡレジを見ていますので、正しく動作しません。
このようなトラブルを避けるためにもプロトタイプ宣言を必ずすることをお勧めします。
第１引数
第２引数
１バイト（ｃｈａｒ）
Ａ
Ｅ
２バイト（ｓｈｏｒｔ）
ＨＬ
ＤＥ
図［２−２−２］ ＬＳＩＣにおける引数とレジスタの関係

第３引数
Ｃ
ＢＣ

なお、これから章が上がるたびに関数が増えていきますので、当然プロトファイル宣言も比例して増えていき、このヘッダーファイルの内容も追加されていきますが、わざわざファイル名を変えて説明する必要も無いと思いますので、説明はこの章だけとさせてもらいます。
３．保守ツール（ＭａｋｅＦｉｌｅ）
１）第１章のＭａｋｅＦｉｌｅとの違いを見る
12: # プロジェクト名(SAMPLE.xxx)
13: PROJ = Cat203p2
・
18: # ユザー作成のヘッダーファイル名
19: HEDS = CAT203.h KC8016IO.h DemoCtl.h・
21: # ユザー作成のオブジェクトファイル名
22: OBJS = StartupB.sof Cat203p2.sof P_Pio1.sof
どうです前章で説明したように、１３，１９，２２行を変更しただけです。
くどいようですが１６行目のライブラリー格納ディレクトリ名は、各自環境に変更して下さい。
２）ｋｍｍａｋｅの実行
前章と同じように、２０ｍｓ毎にシフト表示しているのを、１００ｍｓ毎に変更してみましょう“Ｃａｔ２０３ｐ２．ｃ”をエディタで開き
28:
while(1) {29:
SoftWait1ms(20);30:
RunRun();/* 20msWait/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

40

*/
*/

２９行目の“２０”を“１００”に変更してみてください。
29:
SoftWait1ms(100);/* 100msWait*/

変更後、保存終了して下さい。
保存終了が済みましたら、“ｋｍｍａｋｅ”を実行してみて下さい。
ｋｍｍａｋｅで新しく出来た“Ｃａｔ２０３ｐ２．ｈｅｘ”を評価ボードにダウンロードして、実行してみて下さい。
ＬＥＤのシフト表示スピードが遅くなりましたので、シフトしていく状況が目視で確認できるようになったはずです。
ここまで来ますと、Ｃ言語で開発する土台が出来あがりました。
次章は、評価ボードに付いている、トグルスイッチと押しボタンスイッチを使えるようにすることと、いままで使用していたＬＥＤ表示についての解説をします。

41

第３章 ＰＩＯ
ここの章では、ＰＩＯイニシャルとＰＩＯ使用サンプルの解説を主におきたいと思います。
ＰＩＯの応用例として、入力（８点のトグルスイッチ、４点の押しボタンスイッチ）と出力（８点のＬ
ＥＤ、ＬＣＤ表示［第４章で説明します］）です。
まずは、ＡＢＣｗｉｎのダウンロードで￥評価ボード￥第１部ポーリング編￥第３章ＰＩＯ￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
後の説明進行のため、評価ボード下のトグルスイッチ（８点）を全部を下（オフ）にしておいて下さい。
移動したディレクトリの中に、“Ｃａｔ２０３ｐ３．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
最初は、いままで通りの動作ですが、チョット仕様追加してあります。
評価ボードの右下の押しボタン（以後ＰＢと称します）Ｐ３０を押してみて下さい。
どうです？ＬＥＤ表示が消えたはずです。
ここで、評価ボード下のトグルスイッチ（以後ＳＷと称します）Ｐ４０を上（オン）にしてみて下さい。
どうです？ＬＥＤ［Ｐ２７］が点灯したはずです。

42つまり、ＳＷをオンすると対角線上のＬＥＤを点灯させる仕様になっています。
とりあえず、全ＳＷをオン／オフしてみて下さい。
どうです？ＬＥＤが対角線上で点灯したはずです。
ここでもう１回、ＰＢ［Ｐ３０］を押してみて下さい。
最初に戻ってＬＥＤがパラパラ表示しているはずです。
これだけの仕様ですが、下記の機能が追加されています。
１）ＰＩＯのイニシャル
２）ＳＷ，ＰＢの取りこみ（チャタリング取り付き）
３）ＳＷ入力処理
４）（ＬＥＤ表示処理）＜−すでに使用していますが、未解説です。
５）モード制御機能の開始／停止をコントロールする部分が必要になってきましたので作成しました。
動作はいたってシンプルですが、上記のプログラムを追加しなければ機能しないところが、マイコンプ
ログラムの世話のかかるところです。
それでは、プログラムリストに沿って説明していきます。

43

２．プログラムリスト
このサンプルは、３ファイルの構成になっています。
“ＳｔａｒｔｕｐＢ．ａｓｍ” 前章のまま使用したので解説を省略します。
“Ｐ＿Ｐｉｏ２．ｃ”
ＰＩＯ関係をまとめました。
“Ｃａｔ２０３ｐ３．ｃ”
メインコントロール部です。
１）ＰＩＯ関係
file “P_Pio2.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Pio2.c*/
6: /* ＜役割＞
PIO 関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
変数宣言*/
17: /****************************************************************************/
18:
Uchar
InPort[2];/* IN Port 現 Buffer
*/
19:
Uchar
UpPort[2];/* IN Port 立上り Buffer
*/
20:
Uchar
InBack[2];/* IN Port 一ヶ前 Buffer
*/
21:
Uchar
In20ms[2];/* IN Port 20ms 前 Buffe
*/
22:
Uchar
InNows[2];/* IN Port 生 Buffer
*/
23:
Uchar
OutPort;/* Out Port Buffer*/
24: /****************************************************************************/
25: /*
Ｍｅｍ初期化*/
26: /****************************************************************************/
27: void
PioMemInitial(void)
28: {
29:
OutPort = 0;/* OUT Port 初期化*/
30:
memset(InPort, 0,sizeof(InPort)); /* IN Port 現 Buffer*/
31:
memset(UpPort, 0,sizeof(UpPort)); /* IN Port 立上り Buffer*/
32:
memset(InBack, 0,sizeof(InBack)); /* IN Port 一ヶ前 Buffer*/
33:
memset(In20ms, 0,sizeof(In20ms)); /* IN Port 20ms 前 Buffe*/
34:
memset(InNows, 0,sizeof(InNows)); /* IN Port 生 Buffer*/
35: }
36: /****************************************************************************/
37: /*
Ｉ／Ｏ初期化*/44

38: /****************************************************************************/
39: void
PioIoInitial(void)
40: {
41:
outp(PORT0,0);/* PIO P0 D0〜D3=出力未使用/D4〜D7=入力 PushSW */42:outp(PORT1,0);/*
P1 全出力 LED0〜LED7*/43:
outp(PDIR1,0xFF);
44:
outp(PORT2,0);/* PIO P2 使用 D0=LCD-E 出力 他未使用*/
45:
outp(PDIR2,0x3);/*
D1=LCD-RSE 出力*/46:outp(PDIR3,0);/*
P3 全入力 ﾄｸﾞﾙ SW0〜7 入力
*/
47:
48:
/* ＣＡＴ−２０３（拡張Ｉ／Ｏ） */49:
outp(PORTOP5,0);/* OP5 未使用*/
50:
outp(PORTOP6,0);/* OP6 LCD Data*/51:
outp(PORTOP7,0);/* OP6 未使用
*/
52:
53:
outp(K51COM0,0);/* UAR0 ﾀﾞﾐｰ*/
54:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
55:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
56:
outp(K51COM0,0x40);/* UART ｿﾌﾄﾘｾｯﾄ*/
57:
outp(K51COM0,0x02);/*
Mode Set*/
58:
outp(K51COM0,0x20);/*
RTS ON(Ext Out Enable)*/
59: }
60: /****************************************************************************/
61: /*SigInput Signal Input Process(チャタ取り+状態検出+立上り検出)*/
62: /****************************************************************************/
63: void
SigInput()
64: {
65:
InNows[0] = ~inp(PORT3);/* IN 生 負論理
SW[P40->P47] */66:
InNows[1] = (~inp(PORT0) & 0xf0); /* ""PB[P30->P33] */67:
InPort[0] = In20ms[0] & InNows[0]; /* チャタ取り+状態検出 [P40->P47] */68:
InPort[1] = In20ms[1] & InNows[1]; /*"[P30->P33] */69:
UpPort[0] = (InPort[0] ^ InBack[0]) & InPort[0]; /* 立上検出 [P40->P47] */70:
UpPort[1] = (InPort[1] ^ InBack[1]) & InPort[1]; /*"[P30->P33] */71:
In20ms[0] = InNows[0];/* 20ms 前 Buffe 記憶[P40->P47] */72:
In20ms[1] = InNows[1];/*"[P30->P33] */73:
InBack[0] = InPort[0];/* １ヶ前記憶[P40->P47] */74:
InBack[1] = InPort[1];/*"[P30->P33] */75: }76: /****************************************************************************/
77: /*
PioDemo() ＰＩＯデモ*/
78: /****************************************************************************/
79: void
PioDemo()80: {81:
if (InPort[0] & 0x1) OutPort = OutPort | 0x80;/* SW[P40] */82:
else
OutPort = OutPort & ~(0x80);
83:
if (InPort[0] & 0x2) OutPort = OutPort | 0x40;/* SW[P41] */84:
else
OutPort = OutPort & ~(0x40);
45

85:
if (InPort[0] & 0x4) OutPort = OutPort | 0x20;/* SW[P42] */86:
else
OutPort = OutPort & ~(0x20);
87:
if (InPort[0] & 0x8) OutPort = OutPort | 0x10;/* SW[P43] */88:
else
OutPort = OutPort & ~(0x10);89:
if (InPort[0] & 0x10) OutPort = OutPort | 0x8;/* SW[P44] */90:
else
OutPort = OutPort & ~(0x8);
91:
if (InPort[0] & 0x20) OutPort = OutPort | 0x4;/* SW[P45] */92:
else
OutPort = OutPort & ~(0x4);
93:
if (InPort[0] & 0x40) OutPort = OutPort | 0x2;/* SW[P46] */94:
else
OutPort = OutPort & ~(0x2);
95:
if (InPort[0] & 0x80) OutPort = OutPort | 0x1;/* SW[P47] */96:
else
OutPort = OutPort & ~(0x1);
97: }
98: /****************************************************************************/
99: /*
GetInPort() InPort[x]の読み取り*/
100: /****************************************************************************/
101: Uchar GetInPort(Uchar port)
102: {
103:
return(InPort[port]);104: }
105: /****************************************************************************/
106: /*
GetUpPort() UpPort[x]の読み取り*/
107: /****************************************************************************/
108: Uchar GetUpPort(Uchar port)
109: {
110:
return(UpPort[port]);111: }
112: /****************************************************************************/
113: /*
SigOutput Signal Output Process(LED 出力)*/114: /****************************************************************************/
115: void
SigOutput()
116: {
117:
outp(PORT1,~OutPort);/* 0=点灯 1=消灯 のため*/
118: }
119: /****************************************************************************/
120: /*
OutPortPut 出力バッファーにセット*/
121: /****************************************************************************/
122: void
PutOutPort(Uchar patan,Uchar log)
123: {
124:
if (log == '=')
OutPort = patan;
125:
else if (log == '|') OutPort |= patan;
126:
else if (log == '&') OutPort &= patan;
127: }

46

［リストの説明］
１８〜２３行：
このモジュールで使用する変数宣言です。
役割は、コメント参照して下さい。
２７〜３５行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
３９〜５９行：
ＰＩＯの初期化関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ＰＩＯを使用するためには、まず入出力の方向を設定する必要があります。

ﾋﾞｯﾄ

７
６
５
４
３

名称

ポート方向制御レジスタ（ＰＤＩＲｎ）
ポート方向制御
ビット操作コマンド
機能
機能

ＰｎＥＮ「７」 １：ポートｎのビット７を出力に設定
０：ポートｎのビット７を入力に設定
ＰｎＥＮ［６］ １：ポートｎのビット６を出力に設定
０：ポートｎのビット６を入力に設定
ＰｎＥＮ［５］ １：ポートｎのビット５を出力に設定
０：ポートｎのビット５を入力に設定
ＰｎＥＮ［４］ １：ポートｎのビット４を出力に設定
０：ポートｎのビット４を入力に設定
ＰｎＥＮ［３］ １：ポートｎのビット３を出力に設定
０：ポートｎのビット３を入力に設定

２

ＰｎＥＮ［２］ １：ポートｎのビット２を出力に設定
０：ポートｎのビット２を入力に設定

１

ＰｎＥＮ［１］ １：ポートｎのビット１を出力に設定
０：ポートｎのビット１を入力に設定

０

ＰｎＥＮ［０］ １：ポートｎのビット０を出力に設定
０：ポートｎのビット０を入力に設定

0 固定
0 固定
００：ポート０指定
０１：ポート１指定
１０：ポート２指定
１１：ポート３指定
セット／リセット対象指定
０００：Ｐｘ０指定
１００：Ｐｘ４指定
００１：Ｐｘ１指定
１０１：Ｐｘ５指定
０１０：Ｐｘ２指定
１１０：Ｐｘ６指定
０１１：Ｐｘ３指定
１１１：Ｐｘ７指定（ｘ＝ポート０，１，２，３）
１：セット
０：リセット

図［３−２−１］ ポート方向設定レジスタ ｎ＝０，１，２，３※但し、ポート０は上位４ビット入力・下位４ビット出力で固定され書き込み時には、ビット操作コマンドとして使用されます。
Ｉ／Ｏアドレス
ライト時
リード時
３８Ｈ
ポート０
ポート０
３９Ｈ
ビット操作コマンド
ポート０の方向制御レジスタ
３ＡＨ
ポート１
ポート１
３ＢＨ
ポート１の方向制御レジスタ ポート１の方向制御レジスタ
３ＣＨ
ポート２
ポート２
３ＤＨ
ポート２の方向制御レジスタ ポート２の方向制御レジスタ
３ＥＨ
ポート３
ポート３
３ＦＨ
ポート３の方向制御レジスタ ポート３の方向制御レジスタ図［３−２−２］ パラレルポートのＩ／Ｏマップ

47

シンボル
ＰＯＲＴ０
ＰＤＩＲ０
ＰＯＲＴ１
ＰＤＩＲ１
ＰＯＲＴ２
ＰＤＩＲ２
ＰＯＲＴ３
ＰＤＩＲ３

［４１〜４６行］パラレルポートのＰｏｒｔ０は、上位４ビットが入力ですので、ＰＢに使用します。未使用の下位４ビットの出力をゼロ（Ｌｏｗ）にしておきます。
パラレルポートのＰｏｒｔ１は、全ビットをＬＥＤに使用しますので、出力に指定
し、Ｐｏｒｔ１をゼロ（Ｌｏｗ）にしておきます。
パラレルポートのＰｏｒｔ２は、ＬＣＤで使用しますので、下位の２ビットを出力に指定し、出力をゼロ（Ｌｏｗ）にしておきます。
（Ｄ０＝Ｅ，Ｄ１＝ＲＳで使用します。
）
パラレルポートのＰｏｒｔ３は、全ビットをトグルＳＷの入力に使用しますので、
全ビット入力に指定します。
ＣＡＴ２０３ボードの拡張Ｉ／Ｏを設定します。
Ｉ／Ｏアドレス
機能
注記
シンボル
４０Ｈ
入力８ビット（リード専用） 41-4FH,80-8FH,C0-CFH ｲﾒｰｼﾞが出ます ＰＯＲＴＩＰ４
５０Ｈ
出力８ビット（ライト専用） 51-5FH,90-9FH,D0-DFH ｲﾒｰｼﾞが出ます ＰＯＲＴＯＰ５
６０Ｈ
出力８ビット（ライト専用） 61-6FH,A0-AFH,E0-EFH ｲﾒｰｼﾞが出ます ＰＯＲＴＯＰ６
７０Ｈ
出力８ビット（ライト専用） 71-7FH,B0-BFH,F0-FFH ｲﾒｰｼﾞが出ます ＰＯＲＴＯＰ７
図［３−２−３］ ＣＡＴ２０３拡張Ｉ／Ｏマップ※リセット時に出力は全てハイインピーダンスになります。
出力を有効にするには、ＳＩＯ ＣＨ０のコマンドレジスタＡの
Ｄ５（ＲＴＳ）を１にセットしてください。
［４９〜５１行］拡張Ｉ／Ｏの出力を全てゼロ（Ｌｏｗ）にしておきます。
［５３〜５８行］拡張Ｉ／Ｏの出力を有効にする為ＳＩＯのＣＨ０のＲＴＳ＿を出力します。

５０〜６２行：
ＳＷおよびＰＢのチャタ取り＋状態検出＋立上り検出付きの入力関数です。
メインで２０ｍｓ毎に呼ばれます。
タイミングチャートで説明します。
０ｍｓ

２０ｍｓ

４０ｍｓ

時間軸

ハーﾄﾞ信号

ソフト状態信号ソフト立上信号

48

６０ｍｓ

８０ｍｓ

１００ｍｓ

ハード信号＝ＩｎＮｏｗｓ［ｎ］
ソフト状態信号＝ＩｎＰｏｒｔ［ｎ］
ソフト立上信号＝ＵｐＰｏｒｔ［ｎ］
２０ｍｓ前のハード信号＝Ｉｎ２０ｍｓ［ｎ］
２０ｍｓ前のソフト状態信号＝ＩｎＢａｃｋ［ｎ］

ｎ＝０ ＳＷ［Ｐ４７−＞Ｐ４０］
ｎ＝１ ＰＢ［Ｐ３３−＞Ｐ３０］の構成になっています。
ロジックを文章で説明するのは困難ですので、リストとタイミングチャートで解釈してみて下さい。
６６〜８４行：
ＳＷ［Ｐ４０−＞Ｐ４７］のスイッチをオンすると、ＬＥＤ［Ｐ２０−＞Ｐ２７］を対角線上に点灯させるデモ関数です。
８８〜９１行：
ＳＷおよびＰＢのソフト状態信号を取得する関数です。
９５〜９８行：
ＳＷおよびＰＢのソフト立ち上がり信号を取得する関数です。
１０２〜１０５行：
出力バッファ“OutPort”をポート出力する関数です。
ハード的に、０＝点灯 １＝消灯のため、ここでＮＯＴにしています。
１０９〜１１４行：
出力信号を出力バッファにセットする関数です。
２）メインコントロール
file “Cat203p3.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p3.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
変数宣言*/
17: /****************************************************************************/
18:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
19:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/20: /****************************************************************************/
21: /*
main()*/
22: /****************************************************************************/
23: voidmain(void)
24: {
49

25:
outp(SCR4,0x30);/* SYS
ExtMem 0wait ExtIO 1wait */26:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
27:
MemInitial();/* ﾒﾓﾘ系初期化*/
28:
IoInitial();/* I/O 系初期化*/
29:
while(1) {30:
SigInput();/* Signal Input Process*/
31:
SoftWait1ms(20);/*
ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り*/
32:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
33:
SigOutput();/* Signal Output Process(LED 点灯) */
34:
}
35: }
36: /****************************************************************************/
37: /*
Ｍｅｍ初期化*/
38: /****************************************************************************/
39: void
MemInitial(void)
40: {
41:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/
42:
Shift = 0;/* Led Disp Patan Initial
*/
43:
44:
PioMemInitial();/* PIOMem 初期化*/
45: }
46: /****************************************************************************/
47: /*
Ｉ／Ｏ初期化*/
48: /****************************************************************************/
49: void
IoInitial(void)
50: {
51:
PioIoInitial();/* PIOI/O 初期化*/
52: }53: /****************************************************************************/
54: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
55: /****************************************************************************/
56: void
ModeCntrol()
57: {
58:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/59:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST
*/
60:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ
*/
61:
}
62:
switch(ModeStep) {63:
case 0:64:
ModeStep++;
65:
break;
66:
case 1:
67:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/68:
break;
69:
case 10:/* PIO TEST*/70:
ModeStep++;
71:
break;
50

72:
case 11:73:
PioDemo();74:
break;
75:
}
76: }
77:
78: /****************************************************************************/
79: /*
RunRun()
CPU 走行表示*/
80: /****************************************************************************/
81: void
RunRun()82: {83:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
84:
PutOutPort(Shift,'=');
85: }
86: /****************************************************************************/
87: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
88: /****************************************************************************/
89: void
SoftWait1ms(Ushort ms)
90: {
91:
while(ms-- != 0) {92:
Wait1ms();
93:
}
94: }
95: /****************************************************************************/
96: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
97: /****************************************************************************/
98: void
Wait1ms()
99: {
100:
̲asm̲("\n
PUSH
HL
\n");
101:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */102:
̲asm̲("\n W01:
\n");
103:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
104:̲asm̲("\nLDA,L\n"); /*
= 1
*/
105:
̲asm̲("\nORH\n"); /*
= 1
*/
106:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
107:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
108: }

51

［リストの説明］
前章のメインコントロールから追加された部分だけ解説します。
１８行：
モード制御用に使用するコントロールステップ変数の宣言です。
３０行：“Ｐ＿Ｐｉｏ２．ｃ”で作成した、ＳＷとＰＢの入力関数を呼んでいます。
３２行：
モード制御する関数を呼んでいます。
４１行：
モード制御用に使用するコントロールステップ変数を初期化しています。
４４行：“Ｐ＿Ｐｉｏ２．ｃ”で使用する変数を初期化する関数を呼んでいます。
５１行：
ＰＩＯのＩ／Ｏ初期化する関数を呼んでいます。
５６〜７６行：
モード制御の関数です。
ＰＢ［Ｐ３０］をオンしたら、ＰＩＯのデモ関数を呼ぶ仕組みになっています。
保守ツールについては、もうご理解したと思いますので、この章以降説明は省略します。
このサンプルで変更したい部分がありましたら各自変更をし、“ｋｍｍａｋｅ”を実行してみて下さい。

52

第４章 ＰＩＯの応用（ＬＣＤ）
ここの章では、ＰＩＯの応用としてＬＣＤの表示関数を作成してみました。
表示機能を追加しますと、いろいろとしゃべることができますので表現が豊かになります。
この章は、応用例ですので各自リストを読み、何をやっているのかを理解していただくことが目的です。
まずは、ＡＢＣｗｉｎのダウンロードで￥評価ボード￥第１部ポーリング編￥第４章ＰＩＯの応用（ＬＣＤ）￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ４．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
どうです？ ＬＣＤにオープニングメッセージがでましたか？
仕様は、前章と同じですので、ＰＢ［Ｐ３０］を押してみて下さい。
表現が豊かになったと思います。
どのような仕組みでＬＣＤに表示させているか説明するためにプログラムリストに沿って説明をします。

53

２．プログラムリスト
このサンプルは、前章に１モジュール追加して、４ファイルの構成になっています。
“ＳｔａｒｔｕｐＢ．ａｓｍ” 前章のまま使用したので解説を省略します。
“Ｐ＿Ｐｉｏ２．ｃ”
前章のまま使用したので解説を省略します。
“Ｐ＿Ｌｃｄ．ｃ”
追加したＬＣＤコントロールのモジュールです。
“Ｃａｔ２０３ｐ４．ｃ”
メインコントロール部です。
表示方法の仕組みを説明します。
ＬＣＤに表示したい場合、ＣＰＵ内部の表示バッファー“LcdBuf[2][16]”に表示データーを“LcdReq”に表示要求フラグをセットします。
そして、メインの１ループ毎で要求フラグを監視し、フラグが立っていた場合、メインより直接ＬＣＤに表示データを送る方式です。
１）ＬＣＤコントロール関係
file “P_Lcd.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Lcd.c*/
6: /* ＜役割＞
LCD 関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
ＬＣＤ関係のマクロ*/
17: /****************************************************************************/
18: #define CLRCD
0x1/* LCD ｺﾏﾝﾄﾞ Disp Clear*/
19: #define EMDCD
0x6/*
ｴﾝﾄﾘｰﾓｰﾄﾞｾｯﾄ*/
20: #define FUKCD
0x38/*
ﾌｧﾝｸｼｮﾝｾｯﾄ
*/21: #define DISON
0xc
/*
表示ｵﾝ
*/
22: #define DISOFF
0x8
/*
表示ｵﾌ
*/
23: /****************************************************************************/
24: /*
変数宣言*/
25: /****************************************************************************/
26:
Uchar
LcdBuf[2][16];/* LCD 表示 Buffer
*/
27:
Uchar
LcdReq;/*
表示 要求ﾌﾗｸﾞ*/
28: /****************************************************************************/
29: /*
Ｍｅｍ初期化*/
30: /****************************************************************************/
54

31: void
LcdMemInitial(void)
32: {
33:
memset(LcdBuf[0],0x20,16);/* LCD 表示 Buffer*/
34:
memset(LcdBuf[1],0x20,16);35:
LcdReq = ON;/*
表示 要求ﾌﾗｸﾞ*/36: }37: /****************************************************************************/
38: /*
LcdInitial()
LCD イニシャル*/
39: /****************************************************************************/
40: void
LcdIoInitial()
41: {
42:
SoftWait1ms(45);/* Power On Wait 45ms*/
43:
LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(1)*/44:SoftWait1ms(5);/*5ms Wait*/
45:
LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(2)*/46:SoftWait10us(10);/*100us Wait*/
47:
LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(3)*/48:
LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(4)*/49:
LcdDispOn();/* LCD
表示ｵﾝ*/50:
LcdDispClear();/* LCD
表示ｸﾘｱ*/
51:
LcdCmd(EMDCD);/* LCD ｺﾏﾝﾄﾞ ｴﾝﾄﾘｰﾓｰﾄﾞｾｯﾄ*/
52:
SoftWait10us(4);/*40us Wait*/
53: }54: /****************************************************************************/
55: /*AllLcdDisp()
全画面表示*/
56: /****************************************************************************/
57: void
AllLcdDisp()
58: {
59:
if (LcdReq == ON) {/* 表示要求*/60:
LcdReq = OFF;/*"OFF にするのはココだけ */61:
LcdDispOff();
62:
GotoxyDisp(0,0,LcdBuf[0]);/* 1 行目*/
63:
GotoxyDisp(0,1,LcdBuf[1]);/* 2 行目*/
64:
LcdDispOn();
65:
}
66: }
67: /****************************************************************************/
68: /*
GotoxyMemSet()
画面表示バッファーにセット*/
69: /****************************************************************************/
70: void
GotoxyMemSet(Uchar x,Uchar y,Uchar *str)
71: {
72:
Uchar *ptr;
73:
74:
ptr = &LcdBuf[y][x];75:while(*str != 0) {*ptr++ = *str++;}76:
LcdReq = ON;/* 表示要求 ON にするのはココだけ
*/
77: }
55

78: /****************************************************************************/
79: /*
GotoxyDisp()
カーソル移動＋表示*/
80: /****************************************************************************/
81: void
GotoxyDisp(Uchar x,Uchar y,Uchar *str)
82: {
83:
Gotoxy(x,y);/* カーソル移動*/
84:
while(*str != 0) {85:
LcdPutch(*str++);/* １文字表示
*/
86:
}
87: }
88: /****************************************************************************/
89: /*
Gotoxy()カーソル移動*/90: /****************************************************************************/
91: void
Gotoxy(Uchar x,Uchar y)
92: {
93:
Uchar ramadr;
94:
95:
if (y == 0) ramadr = 0;/* DDRAM ｱﾄﾞﾚｽ計算
*/
96:
else
ramadr = 0x40;
97:
ramadr += x;98:
LcdCmd(ramadr | 0x80);/* LCD ｺﾏﾝﾄﾞ DDRAM ｱﾄﾞﾚｽｾｯﾄ*/
99:
SoftWait10us(4);/*40us Wait*/
100: }
101: /****************************************************************************/
102: /*
LcdDispOn/Off()
表示オン/オフ コントロール*/
103: /****************************************************************************/
104: void
LcdDispOn()
105: {
106:
LcdCmd(DISON);/* LCD ｺﾏﾝﾄﾞ 表示ｵﾝ*/
107:
SoftWait10us(4);/*40us Wait*/
108: }
109: void
LcdDispOff()110: {
111:
LcdCmd(DISOFF);/* LCD ｺﾏﾝﾄﾞ 表示ｵﾌ*/
112:
SoftWait10us(4);/*40us Wait*/
113: }
114: /****************************************************************************/
115: /*
LcdDispClear()
表示クリア コントロール*/
116: /****************************************************************************/
117: void
LcdDispClear()
118: {
119:
LcdCmd(CLRCD);/* LCD ｺﾏﾝﾄﾞ Disp Clear*/
120:
SoftWait10us(164);/*1.64ms Wait*/
121: }
122: /****************************************************************************/
123: /*
LcdPutch() LCD DDRAM Char Data Write*/
124: /****************************************************************************/
56

125: void
LcdPutch(Uchar data)
126: {
127:
outp(PORT2,inp(PORT2) | 0x02);/* LCD RS
ON
*/
128:
if (data < 0x20) data = 0x20;
129:
LcdCmd(data);130:
outp(PORT2,inp(PORT2) & ~(0x02)); /* LCD RS
OFF
*/
131:
SoftWait10us(4);/*40us Wait*/
132: }
133: /****************************************************************************/
134: /*
LcdCmd()LCD command OUT*/
135: /****************************************************************************/
136: void
LcdCmd(Uchar cmd)
137: {
138:
outp(PORTOP6,cmd);/* LCD Data*/139:
outp(PORT2,inp(PORT2) | 0x01);
/*
E
ON
*/
140:
outp(PORT2,inp(PORT2) & ~(0x01)); /*EOFF*/
141: }

57

リストの説明に入る前に、ＬＣＤコントローラ関係資料を添付します。
信号名

機能

Ｄ０−Ｄ７

入出力

８本のデータバス。トライステート双方向性
この線を通してデータ・コマンドのやり取りをします。
動作起動信号。データの書き込みおよび読み出しの起動をかけます。

Ｅ

入力

Ｒ／Ｗ

入力

ＲＳ

入力

ＶＯ

電源

ＶＤ

電源

読み出し（Ｒ）／書き込み（Ｗ）の選択信号“１”：読み出し “０”：書きこみ
レジスタを選択する信号。
“０”：インストラクションレジスタ（Ｗ）
ビジィフラグ、アドレスカウンタ（Ｒ）“１”：データレジスタ
液晶表示駆動用電源、ＶＯを変えることにより画面の濃淡を変化させることができます
＋５Ｖ

ＶＳ

電源

グランド端子：０Ｖ

図［４−２−１］ 端子機能

ＲＳ

Ｔａｓ
：Ｍｉｎ
ＰＷｅｈ ：Ｍｉｎ
Ｔｄｓｗ ：Ｍｉｎ
ＴｃｙｃＥ：Ｍｉｎ

Tas
Ｒ／Ｗ
Pweh
Ｅ
Tdsw
Ｄ０−Ｄ７

有効データ
TcycE

図［４−２−２］ 書込みタイミング

58

４０ｎｓ
２３０ｎｓ
８０ｎｓ
５００ｎｓ

ＤＤ ＲＡＭアドレスと表示桁の対応関係
1
１行目
２行目

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F

図［４−２−３］ ＤＤ ＲＡＭアドレスマップ

インストラクション

RS

R/W

D7

D6

コード
D5 D4

０

０

0

0

0

0

D3

D2

D1

D0

機能

0

0

0

1

全表示クリア後、カーソル
をホーム位置へ戻します。

表示クリア
０

０

0

0

0

0

0

0

1

*

カーソルホーム
0

0

0

0

0

1

I/D

S

０

０

0

0

0

0

1

D

C

B

０

０

0

0

0

1

S/C

R/L

*

*

DD RAM の内容を変えずに、
カーソルの移動と、表示シフトをします。

40us

０

０

0

0

1

D L

N

F

*

*

ｲﾝﾀｰﾌｪｰｽﾃﾞｰﾀ長（ＤＬ）
ﾃﾞュｰﾃｨ（Ｎ）、
文字ﾌｫﾝﾄ（Ｆ）を設定します。

40us

０

０

１

ＤＤ ＲＡＭのアドレスをセットします。
以後のデータはＤＤＲＡＭのデータになります。

40us

カーソル／
表示シフト
ファンクション
セット―――ＡＤＤ―――

ＤＤ ＲＡＭ
アドレスセット
Ｉ／Ｄ＝１：インクリメント

Ｃ＝０：デクリメント＝１：表示シフトする＝０：しない＝１：表示オン＝０：表示オフ

1.64ms０

表示オン／オフ
コントロールＤ

1.64ms０
エントリーモード
セット

Ｓ

カーソルをホーム位置へ戻します、シフトしていた表示も戻ります。DDRAM の内容は変化しません
データの書き込みおよび読
み出し時に、カーソルの進
む方向、表示をシフトかの設定をする。
全表示オン／オフ（Ｄ）
カーソルのｵﾝ/ｵﾌ（Ｃ）
ｶｰｿﾙ位置のﾌﾞﾘﾝｸ（Ｂ）

実行時間
(max)

Ｂ

＝１：カーソルオン

Ｒ／Ｌ＝１：右シフト＝０：カーソルオフ＝０：左シフト＝１：ブリンクオン

ＤＬ ＝１：８ビット＝０：ブリンクオフ
Ｓ／Ｃ＝１：表示シフト＝０：４ビットＮ＝０：カーソル移動

Ｆ

59

40us

＝１：５ｘ１０ドット＝０：５ｘ７ドット＊＝無効ﾋﾞｯﾄＡＤＤ＝ＤＤＲＡＭアドレス＝１：１／１６デューティ＝０：１／８、１／１１

図［４−２−４］ インストラクション一覧

40us

電源オン

ＶDD が４．５Ｖに達してから４５ｍｓ以上待つ
ファンクションセット

４．１ｍｓ以上待つ

ファンクションセット

１００ｕｓ以上待つ

ファンクションセット

ファンクションセット

表示オフ

表示クリア

エントリーモードセット

初期設定終了図［４−２−５］ ＬＣＤ初期設定手順60

［リストの説明］
１８〜２２行：
ＬＣＤインストラクションコードのシンボル宣言です。
２６行：
ＣＰＵ内部のＬＣＤバッファーの宣言です。
２７行：
ＬＣＤ表示要求フラグの宣言です。
３１〜３６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
４０〜５３行：
ＬＣＤ初期設定する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
図［４−２−５］を参照して下さい。
５７〜６６行：
ＬＣＤ表示要求フラグが立っていた場合、直接ＬＣＤに表示データを全画面転送する関数です。
常にメインループ１回に１回呼ばれます。
７０〜７７行：
ＬＣＤ表示バッファーにセットする関数です。
ここで表示要求フラグを立てています。
８１〜８７行：
ＬＣＤに直接、文字列転送する関数です。
９１〜１００行：
ＬＣＤのカーソルを移動させる関数です。
１０４〜１１３行：
ＬＣＤの表示をオン／オフさせる関数です。
１１７〜１２１行：
ＬＣＤ全画面をクリアする関数です。
１２５〜１３２行：
ＬＣＤのＤＤ ＲＡＭに１バイト転送する関数です。
１３６〜１４１行：
ＬＣＤのインストラクションコードを発行する関数です。

61３）メインコントロール
file “Cat203p4.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p4.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
変数宣言*/
17: /****************************************************************************/
18:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
19:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/20: /****************************************************************************/
21: /*
main()*/
22: /****************************************************************************/
23: voidmain(void)
24: {
25:
outp(SCR4,0x30);/* SYS
ExtMem 0wait ExtIO 1wait */26:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
27:
MemInitial();/* ﾒﾓﾘ系初期化*/
28:
IoInitial();/* I/O 系初期化*/
29:
while(1) {30:
SigInput();/* Signal Input Process*/
31:
SoftWait1ms(20);/*
ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り*/
32:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
33:
AllLcdDisp();/* LCD
全画面表示*/
34:
SigOutput();/* Signal Output Process(LED 点灯) */
35:
}
36: }
37: /****************************************************************************/
38: /*
Ｍｅｍ初期化*/
39: /****************************************************************************/
40: void
MemInitial(void)
41: {
42:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/
43:
Shift = 0;/* Led Disp Patan Initial
*/
44:
62

45:
PioMemInitial();/* PIOMem 初期化*/
46:
LcdMemInitial();/* LCDMem 初期化*/
47: }
48: /****************************************************************************/
49: /*
Ｉ／Ｏ初期化*/
50: /****************************************************************************/
51: void
IoInitial(void)
52: {
53:
PioIoInitial();/* PIOI/O 初期化*/
54:
LcdIoInitial();/* LCDI/O 初期化*/
55: }
56: /****************************************************************************/
57: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
58: /****************************************************************************/
59: void
ModeCntrol()
60: {
61:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/62:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST
*/
63:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ
*/
64:
}
65:
switch(ModeStep) {66:
case 0:67:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
68:
GotoxyMemSet(0,1," Polling [P30]");69:
ModeStep++;
70:
break;
71:
case 1:
72:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/73:
break;
74:
case 10:/* PIO TEST*/
75:
GotoxyMemSet(0,0,"PIO");
76:
GotoxyMemSet(0,1,"SW[P40]->SW[P47]");
77:
ModeStep++;
78:
break;
79:
case 11:80:
PioDemo();81:
break;
82:
}
83: }
84:
85: /****************************************************************************/
86: /*
RunRun()
CPU 走行表示*/
87: /****************************************************************************/
88: void
RunRun()89: {90:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
91:
PutOutPort(Shift,'=');
63

92: }
93: /****************************************************************************/
94: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
95: /****************************************************************************/
96: void
SoftWait1ms(Ushort ms)
97: {
98:
while(ms-- != 0) {99:
Wait1ms();
100:}
101: }
102: /****************************************************************************/
103: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
104: /****************************************************************************/
105: void
Wait1ms()
106: {
107:̲asm̲("\n
PUSH
HL
\n");
108:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */109:
̲asm̲("\n W01:
\n");
110:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
111:
̲asm̲("\nLDA,L\n"); /*
= 1
*/
112:
̲asm̲("\nORH\n"); /*
= 1
*/
113:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
114:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
115: }
116: /****************************************************************************/
117: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
118: /****************************************************************************/
119: void
SoftWait10us(Ushort us)
120: {
121:
while(us-- != 0) {122:
Wait10us();123:}124: }
125: /****************************************************************************/
126: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
127: /****************************************************************************/
128: void
Wait10us()
129: {
130:̲asm̲("\n
PUSH
HL
\n");
131:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
132:̲asm̲("\n W02:
\n");
133:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/134:̲asm̲("\nLDA,L\n"); /*
= 1
*/
135:
̲asm̲("\nORH\n"); /*
= 1
*/
136:
̲asm̲("\nJP
NZ,W02\n"); /*
= 3
*/
137:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
138: }
64

［リストの説明］
前章のメインコントロールから追加された部分だけ解説します。
３３行：
ＬＣＤ全画面表示関数を呼んでいます。
４６行：“Ｐ＿Ｌｃｄ．ｃ”で使用する変数を初期化する関数を呼んでいます。
５４行：
ＬＣＤの初期設定をする関数を呼んでいます。
６７〜６８行：
ＬＣＤにオープニングメッセージを表示させるための関数を呼んでいます。
７５〜７６行：
ＬＣＤにＰＩＯモードメッセージを表示させるための関数を呼んでいます。
これで、この章のリスト説明は終わりです。
ご理解いただけたでしょうか？ プログラム記述は個性がヒジョウにでるもので、なれない記述だと読
みにくいと思います。
私自身も、他人の書いたプログラムを読むには、かなりのエネルギーが必要です。
しかし、プログラム記述の標準仕様ができない限り、この問題はプログラマに付きまといます。
根気に読み続けて頂き理解してもらいたいと思います。
次は、タイマ／カウンタ使用例の解説へと進みます。

65

第５章 タイマ／カウンタ
ここの章では、タイマ／カウンタのイニシャルとタイマ使用サンプルの解説を主におき、応用例として評価ボードに付いているブザーを利用したいと思います。
評価ボードの図面を見ますと、ＣＮ２−５Ｂ（Ｐ３６／ＯＵＴＢＰ０）にブザーが接続されています。
タイマーのＰＷＭモードを利用し、指定周波数のパルス出力をしますとブザーを色々な音階で鳴らすことができますので、この仕組みを使ったサンプルを作成していきたいと思います。
まずは、ＡＢＣｗｉｎのダウンロードで￥評価ボード￥第１部ポーリング編￥第５章タイマ／カウンタ￥にディレクトリの移動をしておいて下さい。

66

１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ５．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
どうです？ ＬＣＤにオープニングメッセージがでましたか？
仕様は、前章に追加したかたちになります。ＰＢ［Ｐ３０］を押してみて下さい。
どうです？ ＬＣＤ表示の左上に“ＰＩＯ”と表示したはずです。
ここでもう 1 回、ＰＢ［Ｐ３０］を押してみて下さい。
どうです？ ＬＣＤ表示の左上に“Ｔｉｍｅｒ／Ｃｏｕｎｔｅｒ”と表示したはずです。
ここが、この章の追加サンプルプログラム部分です。
ここで、ＰＢ［Ｐ３３］を押してみて下さい。
どうです？ ブザーが鳴り、ＬＣＤ表示の左下に“２００Ｈｚ”と表示したはずです。
ここで、数回ＰＢ［Ｐ３３］を押してみて下さい。
どうです？ ブザーの音が高くなり、ＬＣＤに周波数を表示しているはずです。
ここで、ＰＢ［Ｐ３２］を押してみて下さい。周波数が下がったはずです。
ここでの操作仕様は、ＰＢ［Ｐ３０］ モード開始／終了
ＰＢ［Ｐ３３］ 周波数を１００Ｈｚ上げます（ＭＡＸ １１００Ｈｚ）
ＰＢ［Ｐ３２］ 周波数を１００Ｈｚ下げます（ＭＩＮ ２００Ｈｚ）
です。
ブザーを鳴らすだけでなく、ＣＮ２−５Ｂの信号をシンクロで見るのも面白いかもしれません。
それでは、プログラムリストを見てみましょう！

67

２．プログラムリスト
このサンプルは、前章に２モジュール追加して、６ファイルの構成になっています。
“ＳｔａｒｔｕｐＢ．ａｓｍ”“Ｐ＿Ｐｉｏ２．ｃ”“Ｐ＿Ｌｃｄ．ｃ”“Ｐ＿Ｔｉｍｅ．ｃ”“ＣａｔＳｕｂ．ｃ”“Ｃａｔ２０３ｐ５．ｃ”

前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
Ｔｉｍｅｒコントロールのモジュールです。
共通サブルーチンのモジュールです。
メインコントロール部です。

１）Ｔｉｍｅｒコントロール関係
file “P_Time.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Time.c*/
6: /* ＜役割＞
タイマ関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
ブザー（タイマ）関係のマクロ*/
17: /****************************************************************************/
18: #define BZMIN
200/* Buzzer Min 200Hz*/
19: #define BZMAX
1000/*
Max 1000Hz*/
20: /****************************************************************************/
21: /*
変数宣言*/
22: /****************************************************************************/
23:
short
BuzzerHz;/* Buzzer Hz*/
24: /****************************************************************************/
25: /*
Ｍｅｍ初期化*/
26: /****************************************************************************/
27: void
TimMemInitial(void)
28: {
29:
BuzzerHz = 0;/* Buzzer Hz*/
30: }31: /****************************************************************************/
32: /*
Ｉ／Ｏ初期化*/
33: /****************************************************************************/
6834: void
TimIoInitial(void)
35: {
36:
outp(TCWD0,0);/* TM0 未使用*/
37:
outp(TCWD1,0);/* TM1 未使用*/
38:
outp(TCWD2,0);/* TM2 使用 Buzzer*/
39:
outp(TCWD3,0);/* TM3 未使用*/
40: }41: /****************************************************************************/
42: /*
Buzzer Timer B ﾁｬﾝﾈﾙ 0 OUTBP0 出力に Buzzer 接続*/
43: /****************************************************************************/
44: void
Buzzer(Ushort hz)
45: {
46:
Uchar cyc;47:
48:
if ((hz >= BZMIN) && (hz <= BZMAX)) { /* Buzzer ON*/
49:
outp(TCWD2,0x1c);/* outH+PWM+sys/256=28800Hz*/
50:
cyc = 28800 / hz;/* 周期の計算*/
51:
outp(TCNT2,cyc-1);/* 周期設定*/
52:
outp(TCNT2,(cyc/2)-1);/* 巾設定*/53:}
54:else {/* Buzzer OFF*/
55:
outp(TCWD2,0);56:
outp(TCNT2,0);57:
outp(TCNT2,0);
58:
}
59: }
60: /****************************************************************************/
61: /*
TimerDemo Timer デモ*/
62: /****************************************************************************/
63: void
TimerDemo()
64: {
65:
Uchar port;
66:
Uchar dec[4+1];
67:
68:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/69:
if (port & 0xc0) {/* PB[P32] | PB[P33] ON ?
*/70:
if (port & 0x40) {/* PB[-P32] ON-立上り*/
71:
BuzzerHz -= 100;
72:
}
73:
else if (port & 0x80) {/* PB[+P33] ON-立上り*/
74:
BuzzerHz += 100;
75:
}
76:
if (BuzzerHz < BZMIN) BuzzerHz = BZMIN;
77:
if (BuzzerHz > BZMAX) BuzzerHz = BZMAX;
78:
Buzzer(BuzzerHz);
79:
Bin2AdecN(dec,BuzzerHz,4);/* 表示用データ作成*/
80:
GotoxyMemSet(0,1,dec);
69

81:
82: }

}

リストの説明に入る前に、タイマ関係資料を添付します。
アドレス
ブロック名
ライト時
チャネル０カウンタ
２０Ｈ
チャネル０コントロールワード
２１Ｈ
チャネル１カウンタ
２２Ｈ
タイマ／
チャネル１コントロールワード
２３Ｈ
カウンタ
チャネル２カウンタ
２４Ｈ
チャネル２コントロールワード
２５Ｈ
チャネル３カウンタ
２６Ｈ
チャネル３コントロールワード
２７Ｈ
図［５−２−１］ タイマのＩ／Ｏマップ

リード時
チャネル０カウンタ
チャネル０ステータス
チャネル１カウンタ
チャネル１ステータス
チャネル２カウンタ
チャネル２ステータス
チャネル３カウンタ
チャネル３ステータス

シンボル
ＴＣＮＴ０
ＴＣＷＤ０
ＴＣＮＴ１
ＴＣＷＤ１
ＴＣＮＴ２
ＴＣＷＤ２
ＴＣＮＴ３
ＴＣＷＤ３

チャネルｎコントロールワード（ＴＣＷＤｎ）
ﾋﾞｯﾄ

名称

７

−

０

６

−

０

５

ＣＯＵＮＴＣＬＫ

４ＴＯＧＧＬＥ

３
２

ＣＯＵＮＴＭＯＤＥ

１０

ＣＯＵＮＴＣＬＫ機能

カウンタクロックの設定を参照
１：ＯＵＴＰ端子の初期出力を“Ｈ”にする
０：ＯＵＴＰ端子の初期出力を“Ｌ”にする
１１：ＰＷＭモード
１０：ＷＤＴモード
０１：連続カウントモード
００：単発カウントモード
カウンタクロックの設定
D5 D1 D0

０ １１：システムクロックの４分周（ＧＡＴＥ機能有）
０ １０：システムクロックの４分周（ＧＡＴＥ機能無）０ ０１：システムクロックの１６分周（ＧＡＴＥ機能無）０ ００：システムクロックの２５６分周（ＧＡＴＥ機能無）１ ０１：ＧＡＴＥ入力の立ち下がりでカウント
１ ００：ＧＡＴＥ入力の立ち上がりでカウント
図［５−２−２］ タイマのモード設定 ｎ＝０，１，２，３70

［リストの説明］
１８行：
出力周波数の最小値の定義です。
１９行：
出力周波数の最大値の定義です。
２３行：
出力周波数を記憶しておく変数の宣言です。
２７〜３０行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
３４〜４０行：
タイマ／カウンタを初期化する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ただし、ここでは全タイマー未動作状態で初期化します。
ここのサンプルでは、タイマのチャネル２のみ使用します。
４４〜５９行：
指定周波数のパルスを出力する関数です。
指定周波数が、範囲外だった場合、パルスを止める仕組みになっています。
指定周波数が、範囲内だった場合は、指定周波数になるように周期計算をし、デューティ５０％になるように、カウンタ／モード設定します。
タイマのチャネル２をモード設定します。図［５−２−２］参照
分周レート：２５６ ＰＷＭモード ＯＵＴＰ端子の初期を“Ｈ”にする［周期計算式］（システムクロック÷分周レート）÷指定周波数＝周期
周期÷２＝周期巾（デューティ５０％）
システムクロック＝７．３７２８ＭＨｚ
７．３７２８ＭＨｚ÷２５６＝２８８００Ｈｚ
２８８００÷指定周波数＝周期になります。
６３〜８２行：
ＰＢ［Ｐ３２］，ＰＢ［Ｐ３３］で出力周波数を指定させる操作をコントロールする関数です。
ここで、指定周波数のタイマ出力をさせ、その周波数の表示をしています。

71２）汎用サブルーチン関係
file “CatSub.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプルプログラム＞
*/
4: /*
*/
5: /* ＜MOD＞
CatSub.c*/
6: /* ＜役割＞
汎用ｻﾌﾞﾙｰﾁﾝ関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<CTYPE.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
ＢＩＮー＞アスキーＤＥＣ変換 桁指定 asc[keta]=NULL 付き*/
17: /****************************************************************************/
18: void
Bin2AdecN(char *asc,Ushort bin,Uchar keta)
19: {
20:
asc[keta] = 0;21:while(keta--) {22:
asc[keta] = bin % 10;
23:bin /= 10;24:
asc[keta] |= '0';
25:
}
26: }
27: /****************************************************************************/
28: /*
ＢＩＮー＞アスキーＨＥＸ変換 桁指定 asc[keta]=NULL 付き*/
29: /****************************************************************************/
30: void
Bin2AhexN(char *asc,Ushort bin,Uchar keta)
31: {
32:
Uchar dt;33:
34:
asc[keta] = 0;35:while(keta--) {36:
dt = (bin & 0xf);
37:
if (dt >= 0xa) dt = (dt + 0x37);
38:
else
dt = (dt + 0x30);
39:
asc[keta] = dt;
40:
bin >>= 4;
41:
}
42: }
43: /****************************************************************************/
44: /*
アスキーＤＥＣ−＞ＢＩＮ変換 桁指定*/72

45: /****************************************************************************/
46: char * Adec2binN(Ushort *bin,char *ptr,Uchar keta)
47: {
48:
char dt;
49:
50:*bin = 0;51:while(keta--) {52:
dt = (char)(*ptr - 0x30);
53:*bin = (*bin * 10) + dt;
54:
ptr++;
55:}
56:
return(ptr);
57: }
58: /****************************************************************************/
59: /*
アスキーＨＥＸー＞ＢＩＮ変換 桁指定*/
60: /****************************************************************************/
61: char * Ahex2binN(Ushort *bin,char *ptr,Uchar keta)
62: {
63:
Uchar dt;
64:
Uchar c;65:
66:
*bin = 0;67:while(keta--) {68:
c = (Uchar)toupper(*ptr);
69:
if (c >= 'A') dt = c - 0x37;70:else
dt = c - 0x30;
71:*bin = (*bin << 4) | dt;
72:
ptr++;
73:}
74:
return(ptr);
75: }
76: /****************************************************************************/
77: /*
ストリングＣｏｐｙ(WORD)*/
78: /****************************************************************************/
79: Ushort * ̲strcpyW(Ushort *dst,Ushort *src)
80: {
81:
while(*src != 0) {82:
*dst++ = *src++;
83:
}
84:
*dst = 0;85:
return(dst);
86: }

73

［リストの説明］
１８〜２６行：Ｕｓｈｏｒｔのバイナリを指定桁の１０進アスキー変換をする関数です。
３０〜４２行：Ｕｓｈｏｒｔのバイナリを指定桁の１６進アスキー変換をする関数です。
４６〜５７行：
１０進アスキーデータの指定桁分をＵｓｈｏｒｔのバイナリに変換をする関数です。
６１〜７５行：
１６進アスキーデータの指定桁分をＵｓｈｏｒｔのバイナリに変換をする関数です。
７９〜８６行：
Ｗｏｒｄデータを元から先へゼロ（０）までコピーする関数です。
以後、この共通サブルーチンを各所で使用します。

74３）メインコントロール
file “Cat203p5.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p5.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
外部変数使用
*/17: /****************************************************************************/
18: extern short
BuzzerHz;/* TIMER Buzzer Hz*/
19: /****************************************************************************/
20: /*
変数宣言*/
21: /****************************************************************************/
22:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
23:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/
24: /****************************************************************************/
25: /*
main()*/
26: /****************************************************************************/
27: voidmain(void)
28: {
29:
outp(SCR4,0x33);/* SYS ExtMem 0wait ExtIO 1wait
*/
30:
/*
PO1->OUT1, PO2->OUT2, PO3->OUT3*/31:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
32:
MemInitial();/* ﾒﾓﾘ系初期化*/
33:
IoInitial();/* I/O 系初期化*/
34:
while(1) {35:
SigInput();/* Signal Input Process*/
36:
SoftWait1ms(20);/*
ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り*/
37:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
38:
AllLcdDisp();/* LCD
全画面表示*/
39:
SigOutput();/* Signal Output Process(LED 点灯) */
40:
}
41: }
42: /****************************************************************************/
43: /*
Ｍｅｍ初期化*/
44: /****************************************************************************/
75

45: void
MemInitial(void)
46: {
47:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/48:
Shift = 0;/* Led Disp Patan Initial
*/
49:
50:
PioMemInitial();/* PIOMem 初期化*/
51:
LcdMemInitial();/* LCDMem 初期化*/
52:
TimMemInitial();/* TIM
Mem 初期化*/
53: }
54: /****************************************************************************/
55: /*
Ｉ／Ｏ初期化*/56: /****************************************************************************/
57: void
IoInitial(void)
58: {
59:
PioIoInitial();/* PIOI/O 初期化*/
60:
LcdIoInitial();/* LCDI/O 初期化*/
61:
TimIoInitial();/* TIMI/O 初期化*/
62: }
63: /****************************************************************************/
64: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
65: /****************************************************************************/
66: void
ModeCntrol()
67: {
68:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/69:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST*/
70:
else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST
*/
71:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
72:
Buzzer(0);/* 強制 OFF
*/
73:
}
74:
switch(ModeStep) {75:
case 0:76:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
77:
GotoxyMemSet(0,1,"Polling[P30]");
78:
ModeStep++;
79:
break;
80:
case 1:
81:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/82:
break;
83:
case 10:/* PIO TEST*/
84:
GotoxyMemSet(0,0,"PIO");
85:
GotoxyMemSet(0,1,"SW[P47]->SW[P40]");86:
ModeStep++;
87:
break;
88:case 11:89:
PioDemo();90:
break;
91:
case 20:/* Timer TEST
*/
76

92:
GotoxyMemSet(0,0,"Timer/Counter ");93:
GotoxyMemSet(0,1,"0000Hz[+P33-P32]");
94:
BuzzerHz = 0;/* Buzzer Hz*/
95:
ModeStep++;
96:
break;
97:
case 21:98:
TimerDemo();99:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
100:
break;
101:}
102: }
103: /****************************************************************************/
104: /*
RunRun()
CPU 走行表示*/
105: /****************************************************************************/
106: void
RunRun()107: {
108:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
109:
PutOutPort(Shift,'=');
110: }
111: /****************************************************************************/
112: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
113: /****************************************************************************/
114: void
SoftWait1ms(Ushort ms)
115: {
116:
while(ms-- != 0) {117:
Wait1ms();118:}
119: }
120: /****************************************************************************/
121: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
122: /****************************************************************************/
123: void
Wait1ms()
124: {
125:
̲asm̲("\n
PUSH
HL
\n");
126:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */127:̲asm̲("\n W01:
\n");
128:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
129:̲asm̲("\nLDA,L\n"); /*
= 1
*/
130:
̲asm̲("\nORH\n"); /*
= 1
*/
131:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
132:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
133: }
134: /****************************************************************************/
135: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
136: /****************************************************************************/
137: void
SoftWait10us(Ushort us)
138: {
77

139:
while(us-- != 0) {140:
Wait10us();141:}
142: }
143: /****************************************************************************/
144: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
145: /****************************************************************************/
146: void
Wait10us()147: {
148:
̲asm̲("\n
PUSH
HL
\n");
149:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
150:̲asm̲("\n W02:
\n");
151:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
152:̲asm̲("\nLDA,L\n"); /*
= 1
*/
153:
̲asm̲("\nORH\n"); /*
= 1
*/
154:
̲asm̲("\nJP
NZ,W02\n"); /*
= 3
*/
155:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
156: }［リストの説明］ 前章のメインコントロールから追加された部分だけ解説します。
タイマーを使用することになりましたので、システムコントロールレジスタの設定が必要になりました。
１８行：
このモジュールで使用する外部変数宣言です。
３０行：
システムコントロールレジスタ（ＳＣＲ４）のＤ１・Ｄ０（端子２０〜２２の機能）を
ＯＵＴ１，ＯＵＴ２，ＯＵＴ３として機能するようにする。
図［２−２−１］を参照
５２行：“Ｐ＿Ｔｉｍｅ．ｃ”で使用する変数の初期化関数を呼んでいます。
６１行：
タイマレジスタを初期化する関数を呼んでいます。
９１〜１００行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

これで、この章のリスト説明は終わりです。
ご理解いただけたでしょうか？
周波数を１００Ｈｚごとの変化でなく、もっと細かくしたい場合は、どこを修正すれば良いか、わかって頂けたでしょうか？（Ｐ＿Ｔｉｍｅ．ｃのどこか）興味のあるかたは、修正して“ｋｍｍａｋｅ”を実行してチャレンジしてみて下さい。
次は、ＵＳＡＲＴ使用例の解説へと進みます。

78

第６章 ＵＳＡＲＴ
ここの章では、ＵＳＡＲＴのイニシャルとＵＳＡＲＴ使用サンプルの解説をします。
ＵＳＡＲＴ使用サンプルは、ポーリング送／受信の１バイトのループバック通信です。
まずは、ＡＢＣｗｉｎのダウンロードで、￥評価ボード￥第１部ポーリング編￥第６章ＵＳＡＲＴ￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ６．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
どうです？ ＬＣＤにオープニングメッセージがでましたか？
もう馴れたと思いますので、ＬＣＤ表示の左上に“Ｕｓａｒｔ”と表示がでるまで、
ＰＢ［Ｐ３０］を押して下さい。
ここで、評価ボード上のＳＷ１１−１をオン（ＴＸＤ，ＲＸＤを折り返す）にして下さい。
ＰＢ［Ｐ３１］が、送受信開始／停止になっていますので、押してみて下さい。
これで、ＰＢ［Ｐ３１］停止を押されるまで、送受信を繰り返します。
ＬＣＤ画面
ＵｓａｒｔＴｘｘＲｘｘ［Ｐ３１］と“ｘｘ”の部分は、送信するごとに＋１する送受信データです。
送受信停止中に、ＰＢ［Ｐ３２］、ＰＢ［Ｐ３３］を押しますと、ボーレートの変更ができます。
それでは、どのような仕組みでプログラムされているかプログラムリストを見てみましょう！

79２．プログラムリスト
このサンプルは、前章に１モジュール追加して、７ファイルの構成になっています。
“ＳｔａｒｔｕｐＢ．ａｓｍ”“Ｐ＿Ｐｉｏ２．ｃ”“Ｐ＿Ｌｃｄ．ｃ”“Ｐ＿Ｔｉｍｅ．ｃ”“ＣａｔＳｕｂ．ｃ”“Ｐ＿Ｕｓａｒｔ．ｃ”“Ｃａｔ２０３ｐ５．ｃ”

前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
ＵＳＡＲＴコントロールのモジュールです。
メインコントロール部です。

１）ＵＳＡＲＴコントロール関係
file “P_Usart.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Usart.c*/
6: /* ＜役割＞
USART(SIO) 関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
ETC*/
17: /****************************************************************************/
18: #define NON
0/* ﾊﾟﾘﾃｨ
NON*/
19: #define EVEN
1
/*
EVEN
*/
20: #define ODD
2
/*
ODD
*/
21: /****************************************************************************/
22: /*
変数宣言*/
23: /****************************************************************************/
24:
Uchar
K51Step;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ
*/
25:
Uchar
K51Select;/* ﾎﾞｰﾚｰﾄ選択
*/
26:
Uchar
TxDat;/* 送信ﾃﾞｰﾀ
*/
27:
Uchar
RxDat;/* 受信ﾃﾞｰﾀ*/
28: const Ushort
BpsTbl[] =
29: {
30:
1200,
31:
2400,
32:
4800,
80

33:
9600,
34:
19200,
35:
38400,
36:0,37: };
38: /****************************************************************************/
39: /*
Ｍｅｍ初期化*/
40: /****************************************************************************/
41: void
K51MemInitial(void)
42: {
43:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
44:
K51Select = 3;/* 9600BPS*/
45: }46: /****************************************************************************/
47: /*
Ｉ／Ｏ初期化*/
48: /****************************************************************************/
49: void
K51IoInitial(void)
50: {
51:
RsOpen(9600,8,NON);
52: }53: /****************************************************************************/
54: /*
RS232C Open bps= ﾎﾞﾚｰﾄ[1200,2400,4800,*9600,19200,38400]*/
55: /*ch= ｷｬﾗｸﾀ[7,*8]*/
56: /*
pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/
57: /**= ﾃﾞﾌｫﾙﾄ
*/58: /*
固定 = STOP=1bit*/
59: /*
ﾎﾞｰﾚｰﾄ = 内臓ﾎﾞｰﾚｰﾄジェネレータを使用*/
60: /****************************************************************************/
61: void
RsOpen(Ushort bps,Uchar ch,Uchar pty)
62: {
63:
Uchar cyc;64:
Uchar mode;65:
66:
outp(K51RATE,2);/* UART ｸﾛｯｸｼﾞｪﾈﾚｰﾄ
*/67:/* 7,372,800/((2+1)*(2^(BCK+1)))/16 */68:
cyc = 0xE1;/* Cmd B ﾎﾞｰﾚｰﾄ(ﾃﾞﾌｫﾙﾄ) 9600bps
*/
69:
if
(bps == 1200) cyc = 0xE7; /*BCK<6> 1200bps*/
70:else if (bps == 2400) cyc = 0xE6; /*BCK<5> 2400bps*/
71:else if (bps == 4800) cyc = 0xE5; /*BCK<4> 4800bps*/
72:
else if (bps == 9600) cyc = 0xE4; /*BCK<3> 9600bps*/
73:
else if (bps == 19200) cyc = 0xE3; /*BCK<2> 19200bps*/
74:
else if (bps == 38400) cyc = 0xE2; /*BCK<1> 38400bps
*/
75:
/*
BCK<0> 76800bps Unused*/
76:
mode = 0x0e;/* Mode Stop=1 NON 8bit
*/
77:
if
(pty == EVEN) mode |= 0x30; /*ﾊﾟﾘﾃｨ=EVEN*/
78:
else if (pty == ODD) mode |= 0x20; /*ﾊﾟﾘﾃｨ=ODD*/
79:
if (ch == 7) mode &= ~(0x4);/*
ｷｬﾗｸﾀ 7
*/
81

80:
81:
outp(K51COM0,0);/* KP51 ﾀﾞﾐｰ*/
82:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
83:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
84:
outp(K51COM0,0x40);/*
ｿﾌﾄﾘｾｯﾄ*/85:
outp(K51COM0,mode);/* Mode Set*/
86:outp(K51COM0,0x37);/* Cmd A Set RTS ERR RX=EI DTR TX=EI*/
87:
outp(K51COM0,cyc);/* Cmd B Set ﾎﾞｰﾚｰﾄ*/
88: }
89: /****************************************************************************/
90: /*
RsPutchRS232C 送信*/
91: /****************************************************************************/
92: void
RsPutch(Uchar tx)
93: {
94:
while((inp(K51COM0) & 0x4) == 0) {} /* TXEMPTY 待ち*/
95:
outp(K51DAT0,tx);
96: }97: /****************************************************************************/
98: /*
RsGetchRS232C 受信*/
99: /****************************************************************************/
100: short
RsGetch()101: {
102:
Ushort time;
103:
Uchar dt;
104:
105:
time = 0;106:while((inp(K51COM0) & 0x3a) == 0) { /* FE+OE+PE+RXRDY ON ?
*/107:
SoftWait1ms(1);/* 1ms*/108:
if (++time >= 20) return(-1); /* Error
*/
109:
}
110:
dt = inp(K51DAT0);111:
if ((inp(K51COM0) & 0x38) != 0 ) { /* FE+OE+PE ON ?
*/112:
outp(K51COM0,0x37);/* ErrReset RTS ERR RX=EI DTR TX=EI */113:
return(-1);
114:
}
115:
return(dt);116: }
117: /****************************************************************************/
118: /*
UsartDemo()
ＵＳＡＲＴデモ*/
119: /****************************************************************************/
120: void
K51Demo()121: {
122:
Uchar dec[2+1];
123:
short stat;
124:
125:
K51Sequence();/* Usart 操作ｺﾝﾄﾛｰﾙ*/
126:
switch(K51Step) {
82

127:
case 0:128:
break;
129:
case 1:
130:
RsOpen(BpsTbl[K51Select],8,NON);/* RS232C Open*/131:
GotoxyMemSet(5,0,"TxxRxx");
132:
TxDat = 0;
133:
K51Step++;
134:
break;
135:
case 2:136:
Bin2AhexN(dec,TxDat,2);/* 表示用送信データ作成*/
137:
GotoxyMemSet(6,0,dec);
138:
RsPutch(TxDat++);
/* 送信
*/
139:
K51Step++;
140:
break;
141:
case 3:142:
stat = RsGetch();143:
if (stat == -1) GotoxyMemSet(9,0,"ee");/* Error*/144:
else {
145:
RxDat = stat;146:
Bin2AhexN(dec,RxDat,2);/* 表示用受信データ作成*/
147:
GotoxyMemSet(9,0,dec);
148:
}
149:
K51Step = 2;
150:
break;
151:}
152: }
153: /****************************************************************************/
154: /*K51Sequence() Usart 操作ｺﾝﾄﾛｰﾙ*/
155: /****************************************************************************/
156: void
K51Sequence()
157: {
158:
Uchar port;
159:
Uchar dec[5+1];
160:
161:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/162:
if (port & 0xe0) {/* PB[P31]->PB[P33] ON(立上) ?
*/163:
if (port & 0x20) {/* PB[P31] ON ? 送信ｽﾀｰﾄ/ｽﾄｯﾌﾟ*/
164:
if (K51Step == 0) K51Step = 1;
165:
else
K51Step = 0;
166:
}
167:
if (K51Step == 0) {/* 停止中のみ受け付ける*/
168:
if (port & 0x40) {/* PB[P32] ON ? ﾎﾞﾚｰﾄ下げ?
*/169:
if (K51Select != 0) --K51Select;
170:
}
171:
else if (port & 0x80) {/* PB[P33] ON ? ﾎﾞﾚｰﾄ上げ?
*/
172:
if (BpsTbl[K51Select+1] != 0) ++K51Select;
173:
}
83

174:
175:
176:
177:
178: }

Bin2AdecN(dec,BpsTbl[K51Select],5); /* 表示用データ作成
GotoxyMemSet(0,1,dec);
}
}

84

*/

リストの説明に入る前に、ＵＳＡＲＴ関係資料を添付します。
アドレス
２８Ｈ
２ＡＨ
２ＢＨ
２ＣＨ
２ＤＨ

ブロック名
USART

ﾎﾞｰﾚｰﾄｼﾞｪﾈﾚｰﾀ
チャンネル０
チャンネル１

ライト時
ＲＡＴＥ設定送信データ
モード／コントロール
送信データ
モード／コントロール

リード時

シンボル

ＲＡＴＥ設定受信データ／拡張ステータスＡ
ステータス／拡張ステータスＢ
受信データ／拡張ステータスＡ
ステータス／拡張ステータスＢ

K51RATEK51DAT0
K51COM0
K51DAT1
K51COM1

図［６−２−１］ ＵＳＡＲＴのＩ／Ｏマップ

ﾋﾞｯﾄ

名称

７
６
５
４
３
２
１
０

動作設定
動作定数

ＲＡＴＥ設定レジスタ（Ｋ５１ＲＡＴＥ） ＲＥＡＤ／ＷＲＩＴＥ
機能
動作設定により送受信クロックの計算が切換られます。
動作設定０：
Ｆｓｙｓｃｌｋ１
×（ｎ＋１）×２（ｉ＋１） １６
動作設定１：Ｆｓｙｓｃｌｋ×（ｎ＋１２８） １×
２５６×２（ｉ＋１）
１６Ｆｓｙｓｃｌｋ＝システムクロック周波数ｎ＝動作定数ｉ＝ＢＣＫ＜ｉ＞
図［６−２−２］ ＲＡＴＥ設定
モードレジスタ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＷＲＩＴＥ
ﾋﾞｯﾄ
名称
機能
ストップビット
７
０：１ビット
１：２ビット−６Ｘ
パリティビット５
１：偶数（ＥＶＥＮ）
０：奇数（ＯＤＤ）
パリティイネーブル
４
１：イネーブル
０：ディセーブル
キャラクタ長
０Ｘ：９ビット３
１０：７ビット２
１１：８ビット―１１０−０
図［６−２−３］ モード設定

85

コマンドレジスタＡ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＷＲＩＴＥ
名称
機能
−
７
０
ＳＲＥＳ
６
１：ソフトウェアリセット（内部初期化）
ＲＴＳ
５
１：ＲＴＳ＿“Ｌ”出力（ＯＮ）
０：ＲＴＳ＿“Ｈ”出力（ＯＦＦ）
ＥＲＲ
４
１：エラーリセット（ＰＥ＋ＯＥ＋ＦＥ）
ＳＢＲＫ
１：ブレーク信号送信（ＴＸＤ＝“Ｌ”
）
３
０：通常
ＲＸＥＮ
２
１：受信イネーブル
０：受信ディセーブルＤＴＲ
１：ＤＴＲ＿は“Ｌ”出力（ＯＮ）
１
０：ＤＴＲ＿は“Ｈ”出力（ＯＦＦ）
ＴＸＥＮ
０
１：送信イネーブル
０：送信ディセーブル
図［６−２−４］ コマンドレジスタＡ
ﾋﾞｯﾄ

コマンドレジスタＢ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＷＲＩＴＥ
名称
機能
−
７
１
−
６
１
−
５
１
４
−
０
−
３
０
ＢＣＫ＜ｉ＞
２
０００：外部クロック(from TRXC PIN)
１
００１：ＢＣＫ＜０＞００１０：ＢＣＫ＜１＞
０１１：ＢＣＫ＜２＞
１００：ＢＣＫ＜３＞
１０１：ＢＣＫ＜４＞
１１０：ＢＣＫ＜５＞
１１１：ＢＣＫ＜６＞図［６−２−５］ コマンドレジスタＢ

ﾋﾞｯﾄ

コマンドレジスタＣ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＷＲＩＴＥ
名称
機能
−
７
１
−
６
１
−
５
０
−
４
０
−
３
０
−
２
０
ＳＬＥＥＰ
１
１：設定
０：解除
０
１：送信データビット８（キャラクタ長９ビット時のみ有効）
図［６−２−６］ コマンドレジスタＣ

ﾋﾞｯﾄ

86

レジスタ切替コマンド（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＷＲＩＴＥ
名称
機能
−
７
１
−
６
０
−
５
０
−
４
０
−
３
０
−
２
０
−
１
０
０
１：レジスタ切替Ｆ／Ｆセット
０：レジスタ切替Ｆ／Ｆクリア
図［６−２−６］ レジスタ切替コマンド

ﾋﾞｯﾄ

ステータスレジスタ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＲＥＡＤ
ﾋﾞｯﾄ

名称

７

ＤＳＲ

機能
０：ＤＳＲ＿は“Ｈ”入力（ＯＦＦ）
１：ＤＳＲ＿は“Ｌ”入力（ＯＮ）
ＢＤＥＴ
６
０：通常
１：ブレーク信号検出
ＦＥ
５
０：通常
１：フレミングエラー検出
ＯＥ
４
０：通常
１：オーバーランエラー検出
ＰＥ
３
０：通常
１：パリティエラー検出
ＴＸＥＭＰ
２
１：送信データバッファと送信シフトレジスタのどちらにも送信デー
タ無しの状態、送信ディセーブル状態、あるいはＣＴＳ＿＝“Ｈ”
の時
ＲＸＲＤＹ
１
０：受信データ無し
１：受信データ有り（１キャラクタ）ＴＸＲＤＹ
００：送信データバッファに送信データセット不可
１：送信データバッファに送信データセット可図［６−２−７］ ステータスレジスタ87

拡張ステータスレジスタＡ（Ｋ５１ＤＡＴ０・Ｋ５１ＤＡＴ１） ＲＥＡＤ
名称
機能
−
７
０
−
６
０
−
５
０
４
−
０
−
３
テスト用ビット（予約）値不定
ＢＣＫ＜ｉ＞
２
０００：外部クロック(from TRXC PIN)
１
００１：ＢＣＫ＜０＞００１０：ＢＣＫ＜１＞
０１１：ＢＣＫ＜２＞
１００：ＢＣＫ＜３＞
１０１：ＢＣＫ＜４＞
１１０：ＢＣＫ＜５＞
１１１：ＢＣＫ＜６＞図［６−２−８］ 拡張ステータスレジスタＡﾋﾞｯﾄ

拡張ステータスレジスタＢ（Ｋ５１ＣＯＭ０・Ｋ５１ＣＯＭ１） ＲＥＡＤ
名称
機能
ストップビット
７
０：１ビット
１：２ビットＣＴＳ
６
０：ＣＴＳ＿は“Ｈ”入力（ＯＦＦ）
１：ＣＴＳ＿は“Ｌ”入力（ＯＮ）
パリティチェック
５
１：偶数（ＥＶＥＮ）
０：奇数（ＯＤＤ）
パリティイ
４
１：有
０：無
キャラクタ長
０Ｘ：９ビット３
１０：７ビット２
１１：８ビット
スリープモード
１
１：有効
０：無効
０
受信データビット８（キャラクタ長９ビット時のみ有効）
図［６−２−９］ 拡張ステータスレジスタＢ
ﾋﾞｯﾄ

88

［リストの説明］
２４行：
送受信をコントロールする変数宣言です。
２５行：
ボーレートを選択する変数宣言です。
２６行：
送信データを記憶する変数宣言です。
２７行：
受信データを記憶する変数宣言です。
２８〜３７行：
選択できるボーレートテーブルの変数宣言です。
４１〜４５行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
４９〜５２行：
ＵＳＡＲＴを初期化する関数“ＲｓＯｐｅｎ”を呼んでいます。
デフォルトで、９６００ｂｐｓ、８ビット、パリティＮＯＮの仕様にしています。
メインのＩ／Ｏ初期化の時に呼ばれます。
６１〜８８行：
ＵＳＡＲＴを初期化する関数です。
この関数は、３個の引数を持っています。
第１引数は、ボーレート［１２００，２４００，４８００，９６００，１９２００，３８４００］
第２引数は、キャラクタ長［７，８］モードでは、９も設定できますがここでは無視します。
第３引数は、パリティ［０＝ＮＯＮ（ディセーブル） １＝偶数 ２＝奇数］
ストップビットは、１ビット固定とします。
［６６行］
ボーレートジェネレータを設定します。
［６８〜８６行］
ＵＳＡＲＴ（ＫＰ５１）を初期化します。
どのような状態でも、ＵＳＡＲＴのモード設定ができるように、“０”を３回セットしてから、ソフ
トウェアリセットコマンドを発行しています。
あとは、指定引数にもとずきモード・コマンドの順に設定します。
９２〜９６行：
１バイトデータを送信する関数です。
１００〜１１６行：
１バイトデータを受信する関数です。
ＲＸＲＤＹ（受信あり）か、受信エラーが発生するまで待つループには、２０ｍｓのソフトタイマーが入れてあります。
受信エラーが発生した場合は、エラーリセットコマンドを発行後、ｓｈｏｒｔ（−１）を返しています。
正常受信した場合は、受信データを呼び先へ返します。
１２０〜１５２行：
ＵＳＡＲＴの動作確認をするための関数です。
ＵＳＡＲＴの設定、１バイト送信、１バイト受信、送受信データの表示等を処理しています。
１５６〜１７３行：
ＵＳＡＲＴの動作確認をする場合、ＰＢ操作のコントロールを管理する関数です。
89２）メインコントロール
file “Cat203p6.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p6.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
外部変数使用
*/17: /****************************************************************************/
18: extern short
BuzzerHz;/* TIMER Buzzer Hz*/
19: extern Uchar
K51Step;/* USART ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
20: extern Uchar
K51Select;/*
ﾎﾞｰﾚｰﾄ選択*/
21: /****************************************************************************/
22: /*
変数宣言*/
23: /****************************************************************************/
24:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
25:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/
26: /****************************************************************************/
27: /*
main()*/
28: /****************************************************************************/
29: voidmain(void)
30: {
31:
outp(SCR4,0x33);/* SYS ExtMem 0wait ExtIO 1wait
*/
32:
/*
P01->OUT1,P02->OUT2,P03->OUT3*/33:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
34:
MemInitial();/* ﾒﾓﾘ系初期化*/
35:
IoInitial();/* I/O 系初期化*/
36:
while(1) {37:
SigInput();/* Signal Input Process*/
38:
SoftWait1ms(20);/*
ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り*/
39:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
40:
AllLcdDisp();/* LCD
全画面表示*/
41:
SigOutput();/* Signal Output Process(LED 点灯) */
42:
}
43: }
44: /****************************************************************************/
90

45: /*
Ｍｅｍ初期化*/
46: /****************************************************************************/
47: void
MemInitial(void)
48: {
49:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/50:
Shift = 0;/* Led Disp Patan Initial
*/
51:
52:
PioMemInitial();/* PIOMem 初期化*/
53:
LcdMemInitial();/* LCDMem 初期化*/
54:
TimMemInitial();/* TIM
Mem 初期化*/
55:
K51MemInitial();/* SIOMem 初期化*/
56: }
57: /****************************************************************************/
58: /*
Ｉ／Ｏ初期化*/
59: /****************************************************************************/
60: void
IoInitial(void)
61: {
62:
PioIoInitial();/* PIOI/O 初期化*/
63:
LcdIoInitial();/* LCDI/O 初期化*/
64:
TimIoInitial();/* TIMI/O 初期化*/
65:
K51IoInitial();/* SIOI/O 初期化*/
66: }
67: /****************************************************************************/
68: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
69: /****************************************************************************/
70: void
ModeCntrol()
71: {
72:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/73:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST*/
74:
else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST*/
75:
else if (ModeStep < 30) ModeStep = 30;/* USART Goto TEST
*/
76:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
77:
Buzzer(0);/* 強制 OFF
*/
78:
}
79:
switch(ModeStep) {80:
case 0:81:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
82:
GotoxyMemSet(0,1,"Polling[P30]");
83:
ModeStep++;
84:
break;
85:
case 1:
86:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/87:
break;
88:case 10:/* PIO TEST*/
89:
GotoxyMemSet(0,0,"PIO");
90:
GotoxyMemSet(0,1,"SW[P47]->SW[P40]");91:
ModeStep++;91

92:
break;
93:
case 11:94:
PioDemo();95:
break;
96:
case 20:/* Timer TEST*/
97:
GotoxyMemSet(0,0,"Timer/Counter ");98:
GotoxyMemSet(0,1,"0000Hz[+P33-P32]");99:
BuzzerHz = 0;/* Buzzer Hz*/
100:
ModeStep++;101:
break;
102:
case 21:103:
TimerDemo();
104:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
105:
break;
106:
case 30:/* USART TEST*/
107:
GotoxyMemSet(0,0,"Usart 8,n,1[P31]");
108:
GotoxyMemSet(0,1,"09600b[+P33-P32]");
109:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
110:
K51Select = 3;/* 9600BPS*/
111:
ModeStep++;
112:
break;
113:
case 31:114:
K51Demo();
115:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
116:
break;
117:}
118: }
119:
120: /****************************************************************************/
121: /*
RunRun()
CPU 走行表示*/
122: /****************************************************************************/
123: void
RunRun()124: {
125:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
126:
PutOutPort(Shift,'=');
127: }
128: /****************************************************************************/
129: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
130: /****************************************************************************/
131: void
SoftWait1ms(Ushort ms)
132: {
133:
while(ms-- != 0) {134:
Wait1ms();
135:}
136: }
137: /****************************************************************************/
138: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
92

139: /****************************************************************************/
140: void
Wait1ms()
141: {
142:̲asm̲("\n
PUSH
HL
\n");
143:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */144:̲asm̲("\n W01:
\n");
145:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
146:̲asm̲("\nLDA,L\n"); /*
= 1
*/
147:
̲asm̲("\nORH\n"); /*
= 1
*/
148:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
149:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
150: }
151: /****************************************************************************/
152: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
153: /****************************************************************************/
154: void
SoftWait10us(Ushort us)
155: {
156:
while(us-- != 0) {157:
Wait10us();158:}
159: }
160: /****************************************************************************/
161: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
162: /****************************************************************************/
163: void
Wait10us()
164: {
165:
̲asm̲("\n
PUSH
HL
\n");
166:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
167:̲asm̲("\n W02:
\n");
168:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
169:̲asm̲("\nLDA,L\n"); /*
= 1
*/
170:
̲asm̲("\nORH\n"); /*
= 1
*/
171:
̲asm̲("\nJP
NZ,W02\n"); /*
= 3
*/
172:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
173: }

93

［リストの説明］ 前章のメインコントロールから追加された部分だけ解説します。
１８〜２０行：
このモジュールで使用する外部変数宣言を追加しました。
５５行：“Ｐ＿Ｕｓａｒｔ．ｃ”で使用する変数の初期化関数を呼んでいます。
６５行：
ＵＳＡＲＴを初期化する関数を呼んでいます。
１０６〜１１６行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。
以上で、この章の説明は終わりにします。
次は、ポーリングにおける総合デモ（メロディ）の解説へと進みます。

94

第 7 章 総合デモ（メロディ）
ここの章では、ポーリングでの総合デモ（メロディ）です。
評価ボードに付いているブザーを使い、チョットした演奏をします。
まずは、ＡＢＣｗｉｎのダウンロードで、￥評価ボード￥第１部ポーリング編￥第７章総合デモ（メロディ）￥にディレクトリの移動をしておいて下さい。
１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２０３ｐ．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
どうです？ ＬＣＤにオープニングメッセージがでましたか？
もう馴れたと思いますので、ＬＣＤ表示の左上に“Ｍｅｌｏｄｙ”と表示がでるまで、
ＰＢ［Ｐ３０］を押して下さい。
ＬＣＤの下行 Ｐ３１［Ｍ］３３［ス］３２［セ］ と表示しているはずです。
Ｐ３１［Ｍ］は、マニュアルの意味です。
ＳＷ［Ｐ４０］−＞ＳＷＰ［４７］を、オン／オフしてみて下さい。
ド、レ、ミ……と音がするはずです。
ＰＢ［Ｐ３１］を押して下さい。
（モード変更）Ｐ３１［Ａ］と表示したはずです。
（Ａｕｔｏ演奏の意味）
ＰＢ［Ｐ３２］を押して下さい。
（選曲）
ネコフンジャッタ−＞イヌノオマワリサン−＞アマリリス（好きな曲で止めて下さい）
ＰＢ［Ｐ３３］を押して下さい（開始／停止）
演奏したはずです。
（音痴ですみません）

95

止めたい時は、どれかＰＢを長く押して下さい。
演奏の音の長さは、ポーリング記述のためソフトタイマを使用しています。
ソフトタイマ使用中は、他の処理は完全に停止してしまうため、ＰＢを長く押す必要があるわけです。
また、演奏中ＬＥＤが止まって見えるはずです、これもソフトタイマの影響です。
この現象を無くす方法は、第２部割込み編 で説明します。
この章では、総合デモ（メロディ）の簡単な説明をしたいと思います。
それでは、プログラムリストを見てみましょう！
２．プログラムリスト
このサンプルは、前章に１モジュール追加して、８ファイルの構成になっています。
“ＳｔａｒｔｕｐＢ．ａｓｍ”“Ｐ＿Ｐｉｏ２．ｃ”“Ｐ＿Ｌｃｄ．ｃ”“Ｐ＿Ｔｉｍｅ．ｃ”“Ｐ＿Ｕｓａｒｔ．ｃ”“ＣａｔＳｕｂ．ｃ”“Ｐ＿Ｍｅｌｏｄｙ．ｃ”“Ｃａｔ２０３ｐ．ｃ”

前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
前章のまま使用したので解説を省略します。
メロディのコントロール部です。
メインコントロール部です。

96１）メロディのコントロール部
file “P_Melody.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
P̲Melody.c*/
6: /* ＜役割＞
デモ メロディー関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
音階 Hz*/
17: /****************************************************************************/
18: #define dO262/* ̲ド */
19: #define rE293/* ̲ﾚ */
20: #define mI330/* ̲ﾐ */
21: #define fhA
349/* ̲ﾌｧ */22: #define sO392/* ̲ｿ */
23: #define rA440/* ̲ﾗ */
24: #define sI494/* ̲ｼ */
25: #define do523/* ド */
26: #define re587/* ﾚ */
27: #define mi
659/* ﾐ */
28: #define fha
698/* ﾌｧ */
29: #define so784/* ｿ */
30: #define ra
880/* ﾗ */
31: #define si
987/* ｼ */
32: #define Do
1047/* ド */
33:
34: #define SCMAX
32/* 楽譜テーブルの最大数*/
35: /****************************************************************************/
36: /*
変数宣言*/
37: /****************************************************************************/
38:
UshortMelodyHz;/* Melody Hz
*/
39:
Uchar
MelMode;/* 演奏ﾓｰﾄﾞ
*/
40:
Uchar
MelSelect;/* 自動選曲
*/
41:
Uchar
MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ
*/
42:
Uchar
Music;/* 自動演奏ｶｳﾝﾀｰ*/
43:
UshortDoremi[SCMAX];/* ﾄﾞﾚﾐ音階周波数(Hz)の RAM 側*/
44:
UshortRhythm[SCMAX];/* ﾘｽﾞﾑ(msec)*/
97

45: const Ushort
DoremiTbl[] =/* ﾄﾞﾚﾐ音階周波数(Hz)
*/
46: {
47:
do,
/* ド */48:
re,/* ﾚ */
49:mi,/* ﾐ */
50:fha,/* ﾌｧ */
51:so,/* ｿ */
52:ra,/* ﾗ */
53:si,/* ｼ */
54:
Do,/* ド */
55:
056: };
57: const UshortMusicTbl[3][SCMAX] =/* 自動演奏の楽譜（最大 32 ﾏﾃﾞ） */58: {/* ﾈｺﾌﾝｼﾞｬｯﾀ */59:{ ra, so, do, Do, Do, ra, so, do, Do, Do,
60:
ra, so, do, Do, rA, Do, sO, si, si},61:/* ｲﾇﾉｵﾏﾜﾘｻﾝ */62:{ mi, do, do, do, mi, do, do, do,fha,fha, mi, mi, re,63:
fha,fha, mi, mi, re, re, ra, ra, so,fha, mi, re, do},64:/* ｱﾏﾘﾘｽ*/
65:{ so, ra, so, Do, so, ra, so, ra, ra, so, ra, so,fha, mi, re, mi, do, 0},
66: };
67: const Ushort
RhythmTbl[3][SCMAX] = /* 自動演奏のリズム(最大 32 ﾏﾃﾞ） */68: {/* ﾈｺﾌﾝｼﾞｬｯﾀ */69:{250,250,500,500,500,250,250,500,500,500,
70:
250,250,500,500,500,500,500,500,500},71:/* ｲﾇﾉｵﾏﾜﾘｻﾝ */72:{250,250,250,250,250,250,250,250,250,250,250,250,1000,
73:
250,250,250,250,250,250,250,250,250,250,250,250,1000,},
74:/* ｱﾏﾘﾘｽ*/
75:{500,500,500,500,500,500,1000,500,500,500,500,250,250,250,250,500,500, 0},76: };
77: const Uchar*MelodyTblA[] =/* 自動演奏の曲名
*/
78: {
79:
"
",
80:
"ﾈｺﾌﾝｼﾞｬｯﾀ",81:"ｲﾇﾉｵﾏﾜﾘｻﾝ",
82:"ｱﾏﾘﾘｽ",
83: };
84:
85: /****************************************************************************/
86: /*
Melodyﾒﾛﾃﾞｨｰｺﾝﾄﾛｰﾙ*/
87: /****************************************************************************/
88: void
Melody()89: {90:MelodySequence();/* ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/
91:
if (MelMode == 0) ManualMelody(); /* 手動演奏
*/
98

92:
else
AutoMelody();/* 自動演奏*/
93: }
94: /****************************************************************************/
95: /*
MelodySequence()
ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/
96: /****************************************************************************/
97: void
MelodySequence()
98: {
99:
Uchar port;
100:
101:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/102:
if (port & 0xe0) {/* PB[P31]->PB[P33] ON(立上) ?
*/103:
Buzzer(0);/* Buzer OFF*/
104:
if (port & 0x20) {/* PB[P31] ON ? ﾓｰﾄﾞ変更*/
105:
MelStep = 0;/* 強制停止*/106:
if (MelMode == 0) {/* 現在手動 ?
*/107:
MelMode = 1;/* 自動に変更*/
108:
MelSelect = 1;/* 自動選曲
*/
109:
}
110:
else {/* 現在自動 ?
*/111:
MelMode = 0;/* 手動に変更*/
112:
MelSelect = 0;/* 自動選曲
*/
113:
}
114:
}
115:
if (MelMode != 0) {/* 自動 ?
*/116:
if (port & 0x40) {/* PB[P32] ON ? 選曲*/
117:
MelStep = 0;/* 強制停止*/118:
if (++MelSelect > 3) MelSelect = 1;
119:
}
120:
if (port & 0x80) {/* PB[P33] ON ? 自動演奏開始*/
121:
if (MelStep == 0) MelStep = 1;
/* 開始
*/
122:
else
MelStep = 0;
/* 停止
*/
123:
Music = 0;
124:
}
125:
}
126:
if (MelMode == 0) GotoxyMemSet(4,1,"M");/* 手動表示
*/
127:
else
GotoxyMemSet(4,1,"A");/* 自動表示*/128:
GotoxyMemSet(7,0,(Uchar *)MelodyTblA[MelSelect]); /* 曲名表示
*/
129:
}
130: }
131: /****************************************************************************/
132: /*
Ｍｅｍ初期化̀*/133: /****************************************************************************/
134: void
MelMemInitial(void)
135: {
136:
MelodyHz = 0;/* Melody Min Hz*/
137:
MelMode = 0;/* 演奏ﾓｰﾄﾞ*/
138:
MelStep = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ
*/
99

139:
MelSelect = 0;/* 自動選曲*/
140: }
141: /****************************************************************************/
142: /*
Ｉ／Ｏ初期化
*/143: /****************************************************************************/
144: void
MelIoInitial(void)
145: {
146:
Buzzer(0);/* Buzer OFF*/
147: }
148: /****************************************************************************/
149: /*
ManualMelody 手動ﾒﾛﾃﾞｨｰ演奏*/
150: /****************************************************************************/
151: void
ManualMelody()
152: {
153:
Uchar port;
154:
155:
switch(MelStep) {156:
case 0:157:
̲strcpyW(Doremi,(Ushort *)DoremiTbl); /* ﾄﾞﾚﾐ音階周波数(初期準備)*/158:
MelStep++;
159:
break;
160:
case 1:161:
if (GetInPort(0) & 0xff) {/* P40->P47 どれかがＯＮしたか？
*/
162:
port = GetUpPort(0);163:
if (port & 0x1) {/* SW[P40] 立上がり ON (ド)*/164:
Buzzer(MelodyHz = Doremi[7]);
165:
}
166:
else if (port & 0x2) {/* SW[P41] 立上がり ON (レ)*/167:
Buzzer(MelodyHz = Doremi[6]);
168:
}
169:
else if (port & 0x4) {/* SW[P42] 立上がり ON (ミ)*/170:
Buzzer(MelodyHz = Doremi[5]);
171:
}
172:
else if (port & 0x8) {/* SW[P43] 立上がり ON (ファ)*/173:
Buzzer(MelodyHz = Doremi[4]);
174:
}
175:
else if (port & 0x10) {/* SW[P44] 立上がり ON (ソ)*/176:
Buzzer(MelodyHz = Doremi[3]);
177:
}
178:
else if (port & 0x20) {/* SW[P45] 立上がり ON (ラ)*/179:
Buzzer(MelodyHz = Doremi[2]);
180:
}
181:
else if (port & 0x40) {/* SW[P46] 立上がり ON (シ)*/182:
Buzzer(MelodyHz = Doremi[1]);
183:
}
184:
else if (port & 0x80) {/* SW[P47] 立上がり ON (ド)*/185:
Buzzer(MelodyHz = Doremi[0]);
100

186:
}
187:
}
188:
else if (MelodyHz != 0) {/* Buzzer 停止*/
189:
Buzzer(MelodyHz = 0);
190:
}
191:
break;
192:}
193: }
194: /****************************************************************************/
195: /*
AutoMelody 自動ﾒﾛﾃﾞｨｰ演奏*/
196: /****************************************************************************/
197: void
AutoMelody()
198: {
199:
switch(MelStep) {200:
case 0:201:
break;
202:
case 1:203:
̲strcpyW(Doremi,(Ushort *)&MusicTbl[MelSelect-1][0]);204:̲strcpyW(Rhythm,(Ushort *)&RhythmTbl[MelSelect-1][0]);205:++MelStep;
206:
break;
207:
case 2:
208:
MelodyHz = Doremi[Music];
/* 楽譜
*/
209:
if (MelodyHz != 0) {/* 演奏中*/210:
Buzzer(MelodyHz);
211:++MelStep;
212:
}
213:
else {
214:
Buzzer(0);
/* 停止
*/
215:
Music = 0;216:
MelStep = 4;
217:
}
218:
break;
219:
case 3:/* リズム*/220:
SoftWait1ms(Rhythm[Music]);
221:
Music++;
222:
MelStep = 2;
223:
break;
224:
case 4:225:
SoftWait1ms(500);/* 連続時の間 */226:
MelStep = 2;
227:
break;
228:}
229: }

101

［リストの説明］
１８〜３２行：
音階ごとの周波数をシンボル定義しました。
３４行：
自動演奏での音符数の最大数宣言です。
３８〜４４行：
このモジュールで使用する変数の宣言です。
４５〜５６行：
マニュアル演奏用ドレミ…の音階周波数テーブルです。
５７〜６６行：
自動演奏３曲の音階周波数テーブルです。
６７〜７６行：
自動演奏３曲のリズム（音の長さ）ｍｓ時間テーブルです。
７７〜８３行：
自動演奏曲名のテーブルです。
８８〜９３行：
手動／自動演奏を切り換えをコントロールする関数です。
９７〜１３０行：
メロディを動作させる場合、ＰＢ操作を管理する関数です。
１３４〜１４０行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
１４４〜１４７行：
このモジュールで使用するＩ／Ｏの初期化関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
１５１〜１９３行：
手動演奏を制御する関数です。
１９７〜２２９行：
自動演奏を制御する関数です。

102２）メインコントロール
file “Cat203p.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ ポーリング
*/
4: /*
*/
5: /* ＜MOD＞
Cat203p.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
外部変数使用
*/17: /****************************************************************************/
18: extern short
BuzzerHz;/* TIMER Buzzer Hz*/
19: extern Uchar
K51Step;/* USART ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
20: extern Uchar
K51Select;/*
ﾎﾞｰﾚｰﾄ選択*/
21: extern Uchar
MelStep;/* Melody ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
22: extern Uchar
MelMode;/*
演奏ﾓｰﾄﾞ
*/23: extern Uchar
MelSelect;
/*
自動選曲
*/
24: /****************************************************************************/
25: /*
変数宣言*/
26: /****************************************************************************/
27:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
28:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/29: /****************************************************************************/
30: /*
main()*/
31: /****************************************************************************/
32: voidmain(void)
33: {
34:
outp(SCR4,0x33);/* SYS ExtMem 0wait ExtIO 1wait
*/
35:
/*
P01->OUT1,P02->OUT2,P03->OUT3*/36:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
37:
MemInitial();/* ﾒﾓﾘ系初期化*/
38:
IoInitial();/* I/O 系初期化*/
39:
while(1) {40:
SigInput();/* Signal Input Process*/
41:
SoftWait1ms(20);/*
ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り*/
42:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
43:
AllLcdDisp();/* LCD
全画面表示*/
44:
SigOutput();/* Signal Output Process(LED 点灯) */
103

45:
}
46: }
47: /****************************************************************************/
48: /*
Ｍｅｍ初期化*/
49: /****************************************************************************/
50: void
MemInitial(void)
51: {
52:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/
53:
Shift = 0;/* Led Disp Patan Initial
*/
54:
55:
PioMemInitial();/* PIOMem 初期化*/
56:
LcdMemInitial();/* LCDMem 初期化*/
57:
TimMemInitial();/* TIM
Mem 初期化*/
58:
K51MemInitial();/* SIOMem 初期化*/
59:
MelMemInitial();/* Melody Mem 初期化*/
60: }61: /****************************************************************************/
62: /*
Ｉ／Ｏ初期化*/
63: /****************************************************************************/
64: void
IoInitial(void)
65: {
66:
PioIoInitial();/* PIOI/O 初期化*/
67:
LcdIoInitial();/* LCDI/O 初期化*/
68:
TimIoInitial();/* TIMI/O 初期化*/
69:
K51IoInitial();/* SIOI/O 初期化*/
70:
MelIoInitial();/* Melody I/O 初期化*/
71: }72: /****************************************************************************/
73: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
74: /****************************************************************************/
75: void
ModeCntrol()
76: {
77:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/78:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST*/
79:
else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST*/
80:
else if (ModeStep < 30) ModeStep = 30;/* USART Goto TEST*/
81:
else if (ModeStep < 40) ModeStep = 40;/* Demo Melody
*/
82:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
83:
Buzzer(0);/* 強制 OFF
*/
84:
}
85:
switch(ModeStep) {86:
case 0:87:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
88:
GotoxyMemSet(0,1,"Polling[P30]");
89:
ModeStep++;90:
break;
91:
case 1:
104

92:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
93:
break;
94:
case 10:/* PIO TEST*/
95:
GotoxyMemSet(0,0,"PIO");
96:
GotoxyMemSet(0,1,"SW[P47]->SW[P40]");97:
ModeStep++;98:
break;
99:
case 11:100:
PioDemo();101:
break;
102:
case 20:/* Timer TEST*/
103:
GotoxyMemSet(0,0,"Timer/Counter ");104:
GotoxyMemSet(0,1,"0000Hz[+P33-P32]");105:
BuzzerHz = 0;/* Buzzer Hz*/
106:
ModeStep++;
107:
break;
108:
case 21:
109:
TimerDemo();110:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
111:
break;
112:
case 30:/* USART TEST*/
113:
GotoxyMemSet(0,0,"Usart 8,n,1[P31]");
114:
GotoxyMemSet(0,1,"09600b[+P33-P32]");
115:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
116:
K51Select = 3;/* 9600BPS*/
117:
ModeStep++;
118:
break;
119:
case 31:120:
K51Demo();
121:
RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/
122:
break;
123:case 40:/* Demo Melody*/
124:
GotoxyMemSet(0,0,"Melody");
125:
GotoxyMemSet(0,1,"P31[M]33[ｽ]32[ｾ]");126:
MelStep = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
127:
MelMode = 0;/* 演奏ﾓｰﾄﾞ*/
128:
MelSelect = 0;/* 自動選曲*/
129:
ModeStep++;
130:
break;
131:case 41:
132:
Melody();133:
RunRun();134:
break;
135:}
136: }
137:
138: /****************************************************************************/
105139: /*
RunRun()
CPU 走行表示*/
140: /****************************************************************************/
141: void
RunRun()142: {
143:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
144:
PutOutPort(Shift,'=');
145: }
146: /****************************************************************************/
147: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
148: /****************************************************************************/
149: void
SoftWait1ms(Ushort ms)
150: {
151:
while(ms-- != 0) {152:
Wait1ms();153:}
154: }
155: /****************************************************************************/
156: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
157: /****************************************************************************/
158: void
Wait1ms()
159: {
160:
̲asm̲("\n
PUSH
HL
\n");
161:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */162:̲asm̲("\n W01:
\n");
163:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
164:̲asm̲("\nLDA,L\n"); /*
= 1
*/
165:
̲asm̲("\nORH\n"); /*
= 1
*/
166:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
167:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
168: }
169: /****************************************************************************/
170: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
171: /****************************************************************************/
172: void
SoftWait10us(Ushort us)
173: {
174:
while(us-- != 0) {175:
Wait10us();176:}
177: }
178: /****************************************************************************/
179: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
180: /****************************************************************************/
181: void
Wait10us()
182: {
183:
̲asm̲("\n
PUSH
HL
\n");
184:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
185:̲asm̲("\n W02:
\n");
106

186:
187:
188:
189:
190:
191: }

̲asm̲("\n̲asm̲("\n̲asm̲("\n̲asm̲("\n̲asm̲("\n

DEC
LD
OR
JP
POP

HL
A,L
H
NZ,W02
HL

\n");
\n");
\n");
\n");
\n");

/* cyc = 1
/*
= 1
/*
= 1
/*
= 3
/*
+= 6

*/
*/
*/
*/
*/

［リストの説明］
前章のメインコントロールから追加された部分だけ解説します。
２１〜２３行：
このモジュールで使用する外部変数宣言を追加しました。
５９行：“Ｐ＿Ｍｅｌｏｄｙ．ｃ”で使用する変数の初期化関数を呼んでいます。
７０行：“Ｐ＿Ｍｅｌｏｄｙ．ｃ”で使用するＩ／Ｏを初期化する関数を呼んでいます。
１２３〜１３４行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。
これで、この章のリスト説明は終わりです。
自動演奏曲“ネコフンジャッタ”を聞いて気がついた方もいらしゃるかと思いますが、半音の登録をしていないため、チョット編曲をしてしまいました。
興味の有る方は、半音登録をして作りなおしてみて下さい。
これも、プログラムに慣れ親しむ方法として、よいことかもしれません。
この章の前半でも説明しましたが、全てポーリングで作成しているため動作および反応が鈍い部分があります。
このままで市場に出したらクレームになってしまいます。
この動作を改善するために、第２部 割込み編より修正を進めていきたいと思います。

107

第２部 割込み編
第１章 タイマ割込み
ここの章では、割り込みを使用する場合どのような手続きが必要かをリストに沿って説明を進めていきます。
又、割り込み要因として、タイマチャネル０の連続カウントモードでの１０ｍｓ毎割り込み例を使用します。
なお、改造するサンプルの元は、“第１部ポーリング編−第７章総合デモ”で作成したサンプルを使用します。
動作仕様の変更はしませんので、この部より動作説明は省略しますが、￥評価ボード￥第２部割込み編￥第１章タイマ割込み￥にディレクトリの移動をしておいて下さい。
１．スタートアップを割り込み用に変更する。
ＫＣ８０で割り込みを使用する場合は、割り込み要因配列のきまった割り込みベクター方式を使用しています。
これは、ＫＣ８０内部の割り込みコントローラ仕様によるものです。
概略仕様
・クロック同期式の割り込みコントローラ
・モード２割り込み対応
・１６レベルの割り込み要因に対し、優先順位の制御ができる
・１６レベル個々にマスクができる
・多重割り込みが可能
・割り込み要求入力のエッジ／レベルの選択ができる
・不正割り込み検出機能がある
・割り込み処理終了は、ＲＥＴＩ命令で検出する。

108

割り込みルーチン
アドレスベクタテーブル
Ｉレジスタ

割込ベクタ

Ｈｉｇｈ（８ﾋﾞｯﾄ）ＬＯＷ（８ビット）

割込み

下位アドレス(8Bit)
上位アドレス(8Bit)

サービスルーチン
PC セット（プログラム）図［２・１−１−１］ モード２割り込みシーケンス

レベル名
ＩＲ［ ０］
ＩＲ［ １］
ＩＲ［ ２］
ＩＲ［ ３］
ＩＲ［ ４］
ＩＲ［ ５］
ＩＲ［ ６］
ＩＲ［ ７］
ＩＲ［ ８］
ＩＲ［ ９］
ＩＲ［１０］
ＩＲ［１１］
ＩＲ［１２］
ＩＲ［１３］
ＩＲ［１４］
ＩＲ［１５］
図［２・１−１−２］

割り込み要求元
タイマ／カウンタ ＣＨ２／外部入力Ｐ２０
タイマ／カウンタ ＣＨ３／外部入力Ｐ２１
Ｓｙｎｃ
ＳＩＯ ＣＨ１ Ｔｘ Ｒｘ／外部入力Ｐ２０
ＵＳＡＲＴ ＣＨ１ ＴＸＲＤＹＵＳＡＲＴ ＣＨ１ ＲＸＲＤＹＵＳＡＲＴ ＣＨ１ ＢＲＫ＋ＥＲＲ／外部入力Ｐ２１
ＤＭＡ ＤＭＴＣ０ＤＭＡ ＤＭＴＣ１
Ｓｙｎｃ
ＳＩＯ ＣＨ０ Ｔｘ Ｒｘ
ＵＳＡＲＴ ＣＨ０ ＴＸＲＤＹＵＳＡＲＴ ＣＨ０ ＲＸＲＤＹＵＳＡＲＴ ＣＨ０ ＢＲＫ＋ＥＲＲ
タイマ／カウンタ ＣＨ０
タイマ／カウンタ ＣＨ１
外部入力Ｐ２２
外部入力Ｐ２３
割り込みコントローラの要因とアドレスベクタテーブル

109１）プログラムリスト
file “StartupC.asm”
1: ;/****************************************************************************/
2: ;/*＜MOD＞
StartupC.asm*/
3: ;/*＜役割＞
スタートアップ (割込み対応 CAT203-KL5C8016)*/
4: ;/*
リンクの都合上、先頭に指定することが絶対条件*/
5: ;/*$$Rx̲init̲value̲は、knil（リンク）で作成されます。
*/
6: ;/*
＜TAB＞
４タブ編集
*/
7: ;/****************************************************************************/
8: STACK
EQU
0xFFFF; ｽﾀｯｸﾎﾞﾄﾑ
9: BBR1
EQU
0x0; KL5C8016(MMU) BBR1
10: BR1
EQU
0x1
;
BR1
11: BBR2
EQU
0x2
;
BBR2
12: BR2
EQU
0x3
;
BR2
13: BBR3
EQU
0x4
;
BBR3
14: BR3
EQU
0x5
;
BR3
15: BBR4
EQU
0x6
;
BBR4
16: BR4
EQU
0x7
;
BR4
17: ;/****************************************************************************/
18: ;/*
スタートアップ*/
19: ;/****************************************************************************/
20:CSEG
21: StartUp:
22:
ORG
0
23:
DI
24:
LD
SP,STACK
25:
IM
2
26:
LD
A,0
27:
LD
I,A
28: ;/****************************************************************************/
29: ;/*
ＭＭＵの初期設定*/
30: ;/****************************************************************************/31:
LD
A,LOW $$R1̲init̲value̲##32:
OUT(BBR1),A33:
LD
A,HIGH $$R1̲init̲value̲##34:
OUT(BR1),A
35:
LD
A,LOW $$R2̲init̲value̲##36:
OUT(BBR2),A37:
LD
A,HIGH $$R2̲init̲value̲##38:
OUT(BR2),A
39:
LD
A,LOW $$R3̲init̲value̲##40:
OUT(BBR3),A41:
LD
A,HIGH $$R3̲init̲value̲##42:
OUT(BR3),A
43:
LD
A,LOW $$R4̲init̲value̲##44:
OUT(BBR4),A
110

45:
JP
main̲##
46: ;/****************************************************************************/
47: ;/*
割込みベクター*/
48: ;/****************************************************************************/
49:
ORG
0x80
50:
DW
NON
; IR[ 0] TIMER CH2 /P20
51:
DW
NON
; IR[ 1] TIMER CH3 /P21
52:
DW
NON
; IR[ 2] Sync SIO CH1 Tx Rx/P20
53:
DW
NON
; IR[ 3] UART CH1 TXRDY
54:
DW
NON
; IR[ 4] UART CH1 RXRDY
55:
DW
NON
; IR[ 5] UART CH1 BRK+ERR/P21
56:
DW
NON
; IR[ 6] DMA DMTC0
57:
DW
NON
; IR[ 7] DMA DMTC1
58:
DW
NON
; IR[ 8] Sync SIO CH0 Tx Rx
59:
DW
NON
; IR[ 9] UART CH0 TXRDY
60:
DW
NON
; IR[10] UART CH0 RXRDY
61:
DW
NON
; IR[11] UART CH0 BRK+ERR
62:
DW
TIMER0; IR[12] TIMER CH0
63:
DW
NON
; IR[13] TIMER CH1
64:
DW
NON
; IR[14] P22
65:
DW
NON
; IR[15] P23
66: ;/****************************************************************************/
67: ;/*
割込みハンドラー*/
68: ;/****************************************************************************/
69: NON::; 割込み未使用
70:
EI
71:
RETI
72: TIMER0::; IR[15] TIMER CH0
73:
PUSH
AF
74:
PUSH
BC
75:
PUSH
DE
76:
PUSH
HL
77:
PUSH
IX
78:
PUSH
IY
79:
CALL
Timer0̲##
80:
POP
IY
81:
POP
IX
82:
POP
HL
83:
POP
DE
84:
POP
BC
85:
POP
AF
86:
EI
87:
RETI
88: ;/****************************************************************************/
89: ;/*
終了（C ｿｰｽへのｴﾝﾄﾘｰ）*/
90: ;/****************************************************************************/
91:
ORG
0x200
111

92:

END

［リストの説明］
２５行：
割り込みモード２だとＣＰＵに教える命令です。
２６〜２７行：
図［２・１−１−１］の説明にもあるように、割り込みベクターテーブルアドレスの上位８ビットをＩレジにセットします。
このサンプルは、０ｘ８０番地がベクターテーブルアドレスにしていますので、ゼロ（０）をセットしています。
４９〜６５行：
図［２・１−１−２］の割り込み要因ごとの割り込みベクターテーブルです。
割り込みが発生した場合、このテーブルに登録されたアドレス値にプログラムはジャンプします。
未使用割り込みは、とりあえず“ＮＯＮ：”という割り込みハンドラを登録しましたが、現実にはあり得ないことです。
６２行目は、今回組み込む“タイマチャネル０”の割り込みハンドラを登録しました。
６８〜７０行：
未使用割り込みハンドラです。
７１〜８６行：
タイマチャネル０の割り込みハンドラです。
全レジスタのＰＵＳＨをしてから、Ｃ言語記述の“Ｔｉｍｅｒ０（）”を呼び、戻って来てから全レ
ジスタのＰＯＰを実行し、“ＥＩ”と“ＲＥＴＩ”で終了しています。
多重割り込み処理をしたい場合は、全レジスタのＰＵＳＨ後に“ＥＩ”命令を置きますと、実現されます。
（スタック領域にご注意！！）
これが、Ｃ言語用割り込みハンドラの雛型です。

112

２．タイマモジュールを割り込み用に変更する。
タイマチャネル０の連続カウントモードで１０ｍｓ毎割り込みを使用する場合、タイマのモード変更が必要になります。
また、割り込みハンドラから呼ばれる関数“Ｔｉｍｅｒ０”も追加しました。
この関数は、タイマー割り込みを利用した内部ソフトタイマー機能を処理する役割になります。
プログラムに沿って説明します。
１）プログラムリスト
file “I_Time.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ 割込み
*/
4: /*
*/
5: /* ＜MOD＞
I̲Time.c*/
6: /* ＜役割＞
タイマ関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
マクロ宣言*/
17: /****************************************************************************/
18: #define BZMIN
200/* Buzzer Min 200Hz*/
19: #define BZMAX
1100
/* "
Max 1100Hz*/
20: /****************************************************************************/
21: /*
変数宣言*/
22: /****************************************************************************/
23:
short
BuzzerHz;/* Buzzer Hz
*/
24:
Uchar
TmUp[TMMAX];/* Soft Timer Up ﾌﾗｸﾞ
*/
25:
Uchar
TmSt[TMMAX];/*
Start ﾌﾗｸﾞ*/
26:
UshortTmCnt[TMMAX];
/*
Count
*/
27: /****************************************************************************/
28: /*
Ｍｅｍ初期化*/
29: /****************************************************************************/
30: void
TimMemInitial(void)
31: {
32:
BuzzerHz = 0;/* Buzzer Hz*/
33:
memset(TmSt, OFF,sizeof(TmSt));/* Timer(10ms) Initial*/
34:
memset(TmUp, OFF,sizeof(TmUp));35:
memset(TmCnt,OFF,sizeof(TmCnt));
113

36: }
37: /****************************************************************************/
38: /*
Ｉ／Ｏ初期化*/
39: /****************************************************************************/
40: void
TimIoInitial(void)
41: {
42:
outp(TCWD0,0x4);/* TM0 使用 10ms 割込み*/
43:
outp(TCNT0,(288 & 0xFF));/*
outL+連続+sys/256*/
44:outp(TCNT0,(288 >> 8));/*
7,372,800/256=28800Hz */45:/*28800/288=100Hz */46:
outp(TCWD1,0);/* TM1 未使用*/
47:
outp(TCWD2,0);/* TM2 使用 Buzzer*/
48:
outp(TCWD3,0);/* TM3 未使用*/
49: }50: /****************************************************************************/
51: /*
Buzzer Timer ﾁｬﾝﾈﾙ 2 OUT2 出力に Buzzer 接続*/
52: /****************************************************************************/
53: void
Buzzer(Ushort hz)
54: {
55:
Uchar cyc;56:
57:
if ((hz >= BZMIN) && (hz <= BZMAX)) { /* Buzzer ON*/
58:
outp(TCWD2,0x1c);/* outH+PWM+sys/256=28800Hz*/
59:
cyc = 28800 / hz;/* 周期の計算*/
60:
outp(TCNT2,cyc-1);/* 周期設定*/
61:
outp(TCNT2,(cyc/2)-1);/* 巾設定*/62:}
63:else {/* Buzzer OFF*/
64:
outp(TCWD2,0);65:
outp(TCNT2,0);66:
outp(TCNT2,0);
67:
}
68: }
69: /****************************************************************************/
70: /*
TmStart*/71: /****************************************************************************/
72: void
TmStart(short tno,short ms)
73: {
74:
Ushort cnt;
75:
76:
cnt = ms / 10;/* 単位 10ms に修正する*/
77:
TmUp[tno] = OFF;78:
TmCnt[tno] = cnt;
79:
TmSt[tno] = ON;
80: }81: /****************************************************************************/
82: /*
TmUpTest ﾀｲﾏ UP ﾌﾗｸﾞﾃｽﾄ*/
114

83: /****************************************************************************/
84: Uchar
TmUpTest(short tno)
85: {
86:
return(TmUp[tno]);87: }
88: /****************************************************************************/
89: /*
ＴＭ０ タイマー割り込み（10ms） 割り込みハンドラより呼ばれる*/
90: /****************************************************************************/
91: void
Timer0(void)
92: {
93:
short i;94:
95:
for(i = 0;i < TMMAX;i++) {/* 内部タイマー処理*/
96:
if (TmSt[i] == ON) {97:
if (--TmCnt[i] == 0) {98:
TmUp[i] = ON;
99:
TmSt[i] = OFF;
100:
}
101:
}
102:
}
103: }
104: /****************************************************************************/
105: /*
TimerDemo Timer デモ*/
106: /****************************************************************************/
107: void
TimerDemo()
108: {
109:
Uchar port;
110:
Uchar dec[4+1];
111:
112:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/113:
if (port & 0xc0) {/* PB[P32] | PB[P33] ON ?
*/114:
if (port & 0x40) {/* PB[-P32] ON-立上り*/
115:
BuzzerHz -= 100;
116:
}
117:
else if (port & 0x80) {/* PB[+P33] ON-立上り*/
118:
BuzzerHz += 100;
119:
}
120:
if (BuzzerHz < BZMIN) BuzzerHz = BZMIN;
121:
if (BuzzerHz > BZMAX) BuzzerHz = BZMAX;
122:
Buzzer(BuzzerHz);
123:
Bin2AdecN(dec,BuzzerHz,4);/* 表示用データ作成*/
124:
GotoxyMemSet(0,1,dec);
125:}
126: }

115

［リストの説明］ 前章から変更のあった部分をおもに解説します。
２４〜２６行：
タイマー割り込みを利用した内部ソフトタイマー処理を追加しましたので、その処理に使用するフラグおよびカウンタの役目をする変数を宣言する。
３０〜３６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
４６〜４９行：
タイマ／カウンタを初期化する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ここでは、タイマチャネル０の初期化をします。
図［５−２−２］参照
ＣＯＵＮＴＣＬＫ：
システムクロックの２５６分周 “００”
ＣＯＵＮＴＭＯＤＥ： 連続カウントモード“０１”
ＴＯＧＧＬＥ：ＯＵＴＰ端子の初期を“Ｌ”“０”［１０ｍｓ［１００Ｈｚ］タイミングの計算］
システムクロック ÷ 分周
＝ タイマ基本クロック（７３７２８００） （２５６）（２８８００）Ｈｚ
タイマ基本クロック ÷ タイマ出力クロック ＝ カウント値（２８８００）（１００）（２８８）になり、タイマチャネル０のカウント値は、“２８８”になります。
７２〜８０行：
タイマー割り込みを利用した内部ソフトタイマーのスタート関数です。
８４〜８７行：
タイマー割り込みを利用した内部ソフトタイマーのタイムアップしたかを調べる関数です。
９１〜１０３行：
タイマー割り込みを利用した内部ソフトタイマー処理関数です。
タイマチャンル０のタイマー割り込み処理で“StartupC.asm”の割り込みハンドラーから呼ばれてい
ます。

116

３．メインコントロール部を割り込み用に変更する。
割り込みを可能にするために必要な変更および、タイマー割り込みを利用した内部ソフトタイマーを利用するために、割り込み許可の挿入とメインループ処理の変更と割り込みコントローラへの設定をしています。
プログラムに沿って説明します。
１）プログラムリスト
file “Cat203i1.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ 割込み
*/
4: /*
*/
5: /* ＜MOD＞
Cat203i1.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
外部変数使用
*/17: /****************************************************************************/
18: extern short
BuzzerHz;/* TIMER Buzzer Hz*/
19: extern Uchar
K51Step;/* USART ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
20: extern Uchar
K51Select;/*
ﾎﾞｰﾚｰﾄ選択*/
21: extern Uchar
MelStep;/* Melody ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
22: extern Uchar
MelMode;/*
演奏ﾓｰﾄﾞ
*/23: extern Uchar
MelSelect;
/*
自動選曲
*/
24: /****************************************************************************/
25: /*
変数宣言*/
26: /****************************************************************************/
27:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
28:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/29: /****************************************************************************/
30: /*
main()*/
31: /****************************************************************************/
32: voidmain(void)
33: {
34:
outp(SCR4,0x33);/* SYS ExtMem 0wait ExtIO 1wait
*/
35:
/*
P01->OUT1,P02->OUT2,P03->OUT3*/36:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち
*/
117

37:
MemInitial();/* ﾒﾓﾘ系初期化*/
38:
IoInitial();/* I/O 系初期化*/
39:
TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ
*/
40:
ei();
/* <- 割り込み許可*/
41:
while(1) {42:
if (TmUpTest(TM0) == ON) {43:
TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ*/
44:
SigInput();/* Signal Input Process*/
45:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
46:
SigOutput();/* Signal Output Process
*/
47:
}
48:
AllLcdDisp();/* LCD
全画面表示
*/
49:
}
50: }
51: /****************************************************************************/
52: /*
Ｍｅｍ初期化*/
53: /****************************************************************************/
54: void
MemInitial(void)
55: {
56:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/
57:
Shift = 0;/* Led Disp Patan Initial
*/
58:
59:
PioMemInitial();/* PIOMem 初期化*/60:
LcdMemInitial();/* LCDMem 初期化*/
61:
TimMemInitial();/* TIM
Mem 初期化*/
62:
K51MemInitial();/* SIOMem 初期化*/
63:
MelMemInitial();/* Melody Mem 初期化*/
64: }65: /****************************************************************************/
66: /*
Ｉ／Ｏ初期化*/
67: /****************************************************************************/
68: void
IoInitial(void)
69: {
70:
PioIoInitial();/* PIOI/O 初期化*/
71:
LcdIoInitial();/* LCDI/O 初期化*/
72:
TimIoInitial();/* TIMI/O 初期化*/
73:
K51IoInitial();/* SIOI/O 初期化*/
74:
MelIoInitial();/* Melody I/O 初期化
*/
75:
76:
outp(LERL,0);/* 割込<- ﾚﾍﾞﾙ/ｴｯｼﾞ設定*/
77:
outp(LERH,0x10);/*<- IR[12]TIMER 0 ｴｯｼﾞ*/78:
outp(IVR,0x80);/*<- 先頭ﾍﾞｸﾀ 80H*/
79:
outp(PGRL,0);/*<- ﾌﾟﾗｲｵﾘﾃｨの設定*/
80:
outp(PGRH,0x10);/*<- IR[12]TIMER 0*/81:
outp(IMRL,0xFF);/*<- ﾏｽｸﾚｼﾞｽﾀ*/82:
outp(IMRH,0xEF);/*<- IR[12]TIMER 0
*/
83: }
118

84: /****************************************************************************/
85: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
86: /****************************************************************************/
87: void
ModeCntrol()
88: {
89:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/90:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST*/
91:
else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST*/
92:
else if (ModeStep < 30) ModeStep = 30;/* USART Goto TEST*/
93:
else if (ModeStep < 40) ModeStep = 40;/* Demo Melody
*/
94:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
95:
Buzzer(0);/* 強制 OFF
*/
96:
}
97:
switch(ModeStep) {98:
case 0:99:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
100:
GotoxyMemSet(0,1,"Interrupt [P30]");101:
ModeStep++;
102:
break;
103:
case 1:
104:
RunRun();105:
break;
106:
case 10:/* PIO TEST*/
107:
GotoxyMemSet(0,0,"PIO");
108:
GotoxyMemSet(0,1,"SW[P47]->SW[P40]");109:
ModeStep++;
110:
break;
111:
case 11:112:
PioDemo();113:
break;
114:
case 20:/* Timer TEST*/
115:
GotoxyMemSet(0,0,"Timer/Counter ");116:
GotoxyMemSet(0,1,"0000Hz[+P33-P32]");117:
BuzzerHz = 0;/* Buzzer Hz*/
118:
ModeStep++;
119:
break;
120:
case 21:
121:
TimerDemo();
122:
RunRun();123:
break;
124:
case 30:/* USART TEST*/
125:
GotoxyMemSet(0,0,"Usart 8,n,1[P31]");
126:
GotoxyMemSet(0,1,"09600b[+P33-P32]");
127:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
128:
K51Select = 3;/* 9600BPS*/
129:
ModeStep++;
130:
break;
119

131:
case 31:132:
K51Demo();
133:
RunRun();134:
break;
135:
case 40:/* Demo Melody*/
136:
GotoxyMemSet(0,0,"Melody");
137:
GotoxyMemSet(0,1,"P31[M]33[ｽ]32[ｾ]");138:
MelStep = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
139:
MelMode = 0;/* 演奏ﾓｰﾄﾞ*/
140:
MelSelect = 0;/* 自動選曲*/
141:
ModeStep++;
142:
break;
143:
case 41:
144:
Melody();145:
RunRun();146:
break;
147:}
148: }
149: /****************************************************************************/
150: /*
RunRun()
CPU 走行表示*/
151: /****************************************************************************/
152: void
RunRun()153: {
154:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
155:
PutOutPort(Shift,'=');
156: }
157: /****************************************************************************/
158: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
159: /****************************************************************************/
160: void
SoftWait1ms(Ushort ms)
161: {
162:
while(ms-- != 0) {163:
Wait1ms();
164:}
165: }
166: /****************************************************************************/
167: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
168: /****************************************************************************/
169: void
Wait1ms()
170: {
171:
̲asm̲("\n
PUSH
HL
\n");
172:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */173:
̲asm̲("\n W01:
\n");
174:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
175:̲asm̲("\nLDA,L\n"); /*
= 1
*/
176:
̲asm̲("\nORH\n"); /*
= 1
*/
177:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
120

178:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
179: }
180: /****************************************************************************/
181: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
182: /****************************************************************************/
183: void
SoftWait10us(Ushort us)
184: {
185:
while(us-- != 0) {186:
Wait10us();187:}
188: }
189: /****************************************************************************/
190: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
191: /****************************************************************************/
192: void
Wait10us()
193: {
194:
̲asm̲("\n
PUSH
HL
\n");
195:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
196:
̲asm̲("\n W02:
\n");
197:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
198:̲asm̲("\nLDA,L\n"); /*
= 1
*/
199:
̲asm̲("\nORH\n"); /*
= 1
*/
200:
̲asm̲("\nJP
NZ,W02\n"); /*
= 3
*/
201:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
202: }

121

［リストの説明］ 前章から変更のあった部分をおもに解説します。
３９行：
チャタリング防止タイマーに、タイマー割り込みを利用した内部ソフトタイマーの利用に変更します
ので、ここでスタートをかけておきます。
４０行：
ここで、割り込み許可“ｅｉ（）”をします。
逆を言えば、ここに来るまでに割り込み関数で使用するＩ／Ｏおよび変数は初期化ずみであることが必要になります。
４２〜４３行：
チャタリング防止タイマがタイムアップするのを待ちます。
いままで使用していたソフトタイマと違い、待っている間は他処理の実行が可能になっています。
７６〜８２行：
割り込みコントローラへの設定部分です。
アドレス
ブロック名
ライト時
リード時
ＬＥＲＬ／ＰＧＲＬ
ＩＳＲＬ
３４Ｈ
ＩＳＲＨ
割り込みコン ＬＥＲＨ／ＰＧＲＨ
３５Ｈ
ＩＭＲＬ
ＩＭＲＬ
トローラ
３６Ｈ
ＩＶＲ／ＩＭＲＨ
ＩＭＲＨ
３７Ｈ
図［１−３−１］ 割り込みコントローラＩ／Ｏマップ

シンボル
ＬＥＲＬ／ＰＧＲＬ／ＩＳＲＬ
ＬＥＲＨ／ＰＧＲＨ／ＩＳＲＨ
ＩＭＲＬ
ＩＶＲ／ＩＭＲＨ［７６〜７７行：］
ａ．割り込みのレベル／エッジの設定
ＬＥＲ［１２］＝タイマチャネル０をエッジモードにします。
レベル／エッジ レジスタ（ＬＥＲＨ） ０＝レベル １＝エッジ ＷＲＩＴＥ
ﾋﾞｯﾄ
名称
要求元
ＬＥＲ［１５］
ＩＲ［１５］ 外部入力Ｐ２３
７
ＬＥＲ［１４］
ＩＲ［１４］ 外部入力Ｐ２２
６
ＬＥＲ［１３］
ＩＲ［１３］ タイマ／カウンタ ＣＨ１
５
ＬＥＲ［１２］
ＩＲ［１２］
４
タイマ／カウンタ ＣＨ０
ＬＥＲ［１１］
ＩＲ［１１］ ＵＳＡＲＴ ＣＨ０ ＢＲＫ＋ＥＲＲ
３
ＬＥＲ［１０］ＩＲ［１０］ ＵＳＡＲＴ ＣＨ０ ＲＸＲＤＹ
２
ＬＥＲ［ ９］ＩＲ［ ９］ ＵＳＡＲＴ ＣＨ０ ＴＸＲＤＹ
１
ＬＥＲ［
８］
ＩＲ［ ８］ Ｓｙｎｃ
０
ＳＩＯ ＣＨ０ Ｔｘ Ｒｘ
図［１−３−２］ＬＥＲＨ（Ｌｅｖｅｌ／Ｅｄｇｅ Ｒｅｇｉｓｔｅｒ）

122レベル／エッジ レジスタ（ＬＥＲＬ） ０＝レベル １＝エッジ ＷＲＩＴＥ
名称
要求元
ＬＥＲ［
７］
ＩＲ［
７］
７
ＤＭＡ ＤＭＴＣ１
ＬＥＲ［ ６］ＩＲ［ ６］ ＤＭＡ ＤＭＴＣ０６ＬＥＲ［ ５］ＩＲ［ ５］ ＵＳＡＲＴ ＣＨ１ ＢＲＫ＋ＥＲＲ／外部入力Ｐ２１
５
ＬＥＲ［
４］
ＩＲ［
４］ ＵＳＡＲＴ ＣＨ１ ＲＸＲＤＹ
４
ＬＥＲ［ ３］ＩＲ［ ３］ ＵＳＡＲＴ ＣＨ１ ＴＸＲＤＹ
３
ＬＥＲ［
２］
ＩＲ［ ２］ Ｓｙｎｃ
２
ＳＩＯ ＣＨ１ Ｔｘ Ｒｘ／外部入力Ｐ２０
ＬＥＲ［ １］
ＩＲ［ １］ タイマ／カウンタ ＣＨ３／外部入力Ｐ２１
１
ＬＥＲ［ ０］ＩＲ［ ０］ タイマ／カウンタ ＣＨ２／外部入力Ｐ２００
図［１−３−２］ＬＥＲＬ（Ｌｅｖｅｌ／Ｅｄｇｅ Ｒｅｇｉｓｔｅｒ）
ﾋﾞｯﾄ［７８行：］
ｂ．割り込みベクターアドレスの下位８ビット中の上位３ビットの設定
割り込みベクター値を０ｘ８０にします。
Ｄ７
IVR

Ｄ６

ＩＶＲ［７］ ＩＶＲ［６］

Ｄ５

Ｄ４

Ｄ３

Ｄ２

Ｄ１

Ｄ０

Ｄ２

Ｄ１

Ｄ０

ＩＶＲ［５］

図［１−３−３］ＩｎｔｅｒｒｕｐｔＶｅｃｔｏｒＲｅｇｉｓｔｅｒ

Ｄ７
IVR

Ｄ６

ＩＶＲ［７］ ＩＶＲ［６］

Ｄ５

Ｄ４

Ｄ３

ＩＶＲ［５］

０

割り込み要求（ＩＲ［ｎ］）番号に応じた２進数コード出力＋ＩＲ［１５］

１

１

１

１

＋ＩＲ［１４］｜｜｜＋ＩＲ［ ０］

１

１

１

０

０

０

０

０

図［１−３−４］ 割り込みベクタ出力123［７９〜８０行：］
ｃ．割り込みプライオリティの設定
ＰＧＲ［１２］＝タイマチャネル０を“ＨＩＧＨ”グループとします。
プライオリティ グループ レジスタ（ＰＧＲＨ） ０＝ＬＯＷ １＝ＨＩＧＨ ＷＲＩＴＥ
名称
要求元
ＰＧＲ［１５］
ＩＲ［１５］ 外部入力Ｐ２３
７
ＰＧＲ［１４］
ＩＲ［１４］ 外部入力Ｐ２２
６
ＰＧＲ［１３］
ＩＲ［１３］ タイマ／カウンタ ＣＨ１
５
ＰＧＲ［１２］
ＩＲ［１２］ タイマ／カウンタ ＣＨ０
４
ＰＧＲ［１１］
ＩＲ［１１］ ＵＳＡＲＴ ＣＨ０ ＢＲＫ＋ＥＲＲ
３
ＰＧＲ［１０］ＩＲ［１０］ ＵＳＡＲＴ ＣＨ０ ＲＸＲＤＹ
２
ＰＧＲ［
９］
ＩＲ［
９］ ＵＳＡＲＴ ＣＨ０ ＴＸＲＤＹ
１
ＰＧＲ［ ８］ＩＲ［ ８］ Ｓｙｎｃ
０
ＳＩＯ ＣＨ０ Ｔｘ Ｒｘ

ﾋﾞｯﾄ

プライオリティ グループ レジスタ（ＰＧＲＬ） ０＝ＬＯＷ １＝ＨＩＧＨ ＷＲＩＴＥ
ﾋﾞｯﾄ

名称
要求元
ＰＧＲ［ ７］ＩＲ［ ７］ ＤＭＡ ＤＭＴＣ１
７ＰＧＲ［ ６］ＩＲ［ ６］ ＤＭＡ ＤＭＴＣ０６
ＰＧＲ［ ５］ＩＲ［ ５］ ＵＳＡＲＴ ＣＨ１ ＢＲＫ＋ＥＲＲ／外部入力Ｐ２１
５
ＰＧＲ［
４］
ＩＲ［
４］ ＵＳＡＲＴ ＣＨ１ ＲＸＲＤＹ
４
ＰＧＲ［ ３］ＩＲ［ ３］ ＵＳＡＲＴ ＣＨ１ ＴＸＲＤＹ
３
ＰＧＲ［
２］
ＩＲ［ ２］ Ｓｙｎｃ
２
ＳＩＯ ＣＨ１ Ｔｘ Ｒｘ／外部入力Ｐ２０
ＰＧＲ［ １］
ＩＲ［ １］ タイマ／カウンタ ＣＨ３／外部入力Ｐ２１
１
ＰＧＲ［ ０］ＩＲ［ ０］ タイマ／カウンタ ＣＨ２／外部入力Ｐ２００
図［１−３−５］ ＰｒｉｏｒｉｔｙＧｒｏｕｐＲｅｇｉｓｔａｅｒ124

［８１〜８２行：］
ｄ．割り込みマスクの設定（０＝非マスク状態：割込み可 １＝マスク状態：割込み不可）
ＩＭＲ［１２］＝タイマチャネル０のマスクを解除します。
インタラプト マスク レジスタ（ＩＭＲＨ） ０＝非マスク状態 １＝マスク状態 ＷＲＩＴＥ
名称要求元
ＩＭＲ［１５］
ＩＲ［１５］ 外部入力Ｐ２３
７
ＩＭＲ［１４］
ＩＲ［１４］ 外部入力Ｐ２２
６
ＩＭＲ［１３］
ＩＲ［１３］ タイマ／カウンタ ＣＨ１
５
ＩＭＲ［１２］
ＩＲ［１２］ タイマ／カウンタ ＣＨ０
４
ＩＭＲ［１１］
ＩＲ［１１］ ＵＳＡＲＴ ＣＨ０ ＢＲＫ＋ＥＲＲ
３
ＩＭＲ［１０］ＩＲ［１０］ ＵＳＡＲＴ ＣＨ０ ＲＸＲＤＹ
２
ＩＭＲ［
９］
ＩＲ［
９］ ＵＳＡＲＴ ＣＨ０ ＴＸＲＤＹ
１ＩＭＲ［ ８］ＩＲ［ ８］ Ｓｙｎｃ
０
ＳＩＯ ＣＨ０ Ｔｘ Ｒｘ

ﾋﾞｯﾄ

インタラプト マスク レジスタ（ＩＭＲＨ） ０＝非マスク状態 １＝マスク状態 ＷＲＩＴＥ
名称
要求元
ＩＭＲ［
７］
ＩＲ［
７］
７
ＤＭＡ ＤＭＴＣ１
ＩＭＲ［ ６］ＩＲ［ ６］ ＤＭＡ ＤＭＴＣ０６ＩＭＲ［ ５］ＩＲ［ ５］ ＵＳＡＲＴ ＣＨ１ ＢＲＫ＋ＥＲＲ／外部入力Ｐ２１
５
ＩＭＲ［ ４］ＩＲ［ ４］ ＵＳＡＲＴ ＣＨ１ ＲＸＲＤＹ
４
ＩＭＲ［
３］
ＩＲ［ ３］ ＵＳＡＲＴ ＣＨ１ ＴＸＲＤＹ
３
ＩＭＲ［ ２］ＩＲ［ ２］ Ｓｙｎｃ
２
ＳＩＯ ＣＨ１ Ｔｘ Ｒｘ／外部入力Ｐ２０
ＩＭＲ［
１］
ＩＲ［
１］
１
タイマ／カウンタ ＣＨ３／外部入力Ｐ２１
ＩＭＲ［ ０］ＩＲ［ ０］ タイマ／カウンタ ＣＨ２／外部入力Ｐ２００
図［１−３−６］ ＩｎｔｅｒｒｕｐｔＭａｓｋＲｅｇｉｓｔｅｒ
ﾋﾞｯﾄ

８４〜最終行：変更なし。
以上、３ファイルの変更で、タイマー割り込み処理が組み込まれました。
動作的には、ほとんど変わりませんが興味のあるかたは、動作確認してみて下さい。

125

ＡＢＣｗｉｎでダウンロード後、プログラム実行をして下さい。

“Ｃａｔ２０３ｉ１．ｈｅｘ”です
次章は、ＵＳＡＲＴ割り込みに挑戦したいと思います。

126

第２章 ＵＳＡＲＴ割込み
ここの章では、ＵＳＡＲＴの送受信を割り込みで処理する場合どのような手続きが必要かをリストに沿って説明を進めていきます。
また、送受信フォームを文字列通信に変更しましたので、文字列扱いを容易にするため簡単なプロトコ
ルでの通信仕様にしました。
［プロトコル仕様］
ＳＴＸ“文字列〜１４文字まで”ＥＴＸ ＳＴＸ＝０ｘ０２（スタート）
ＥＴＸ＝０ｘ０３（エンド）￥評価ボード￥第２部割込み編￥第２章ＵＳＡＲＴ割込み￥にディレクトリの移動をしておいて下さい。
１．スタートアップを変更する。
ＵＳＡＲＴの送受信割り込みを有効にする準備をします。
１）プログラムリスト
file “StartupD.asm”
1: ;/****************************************************************************/
2: ;/*＜MOD＞
StartupD.asm*/
3: ;/*＜役割＞
スタートアップ (割込み対応 CAT203-KL5C8016)*/
4: ;/*
リンクの都合上、先頭に指定することが絶対条件*/
5: ;/*$$Rx̲init̲value̲は、knil（リンク）で作成されます。
*/
6: ;/*
＜TAB＞
４タブ編集
*/
7: ;/****************************************************************************/
8: STACK
EQU
0xFFFF; ｽﾀｯｸﾎﾞﾄﾑ
9: BBR1
EQU
0x0; KL5C8016(MMU) BBR1
10: BR1
EQU
0x1
;
BR1
11: BBR2
EQU
0x2
;
BBR2
12: BR2
EQU
0x3
;
BR2
13: BBR3
EQU
0x4
;
BBR3
14: BR3
EQU
0x5
;
BR3
15: BBR4
EQU
0x6
;
BBR4
16: BR4
EQU
0x7
;
BR4
17: ;/****************************************************************************/
18: ;/*
スタートアップ*/
19: ;/****************************************************************************/
20:CSEG
21: StartUp:
22:
ORG
0
23:
DI
24:
LD
SP,STACK
25:
IM
2
26:
LD
A,0
27:
LD
I,A
127

28: ;/****************************************************************************/
29: ;/*
ＭＭＵの初期設定*/
30: ;/****************************************************************************/31:
LD
A,LOW $$R1̲init̲value̲##32:
OUT(BBR1),A33:
LD
A,HIGH $$R1̲init̲value̲##34:
OUT(BR1),A
35:
LD
A,LOW $$R2̲init̲value̲##36:
OUT(BBR2),A37:
LD
A,HIGH $$R2̲init̲value̲##38:
OUT(BR2),A
39:
LD
A,LOW $$R3̲init̲value̲##40:
OUT(BBR3),A41:
LD
A,HIGH $$R3̲init̲value̲##42:
OUT(BR3),A
43:
LD
A,LOW $$R4̲init̲value̲##44:
OUT(BBR4),A
45:
JP
main̲##
46: ;/****************************************************************************/
47: ;/*
割込みベクター*/
48: ;/****************************************************************************/
49:
ORG
0x80
50:
DW
NON
; IR[ 0] TIMER CH2 /P20
51:
DW
NON
; IR[ 1] TIMER CH3 /P21
52:
DW
NON
; IR[ 2] Sync SIO CH1 Tx Rx/P20
53:
DW
NON
; IR[ 3] UART CH1 TXRDY
54:
DW
NON
; IR[ 4] UART CH1 RXRDY
55:
DW
NON
; IR[ 5] UART CH1 BRK+ERR/P21
56:
DW
NON
; IR[ 6] DMA DMTC0
57:
DW
NON
; IR[ 7] DMA DMTC1
58:
DW
NON
; IR[ 8] Sync SIO CH0 Tx Rx
59:
DW
TXRDY
; IR[ 9] UART CH0 TXRDY
60:
DW
RXRDY
; IR[10] UART CH0 RXRDY
61:
DW
NON
; IR[11] UART CH0 BRK+ERR/P21
62:
DW
TIMER0; IR[12] TIMER CH0
63:
DW
NON
; IR[13] TIMER CH1
64:
DW
NON
; IR[14] P22
65:
DW
NON
; IR[15] P23
66: ;/****************************************************************************/
67: ;/*
割込みハンドラー*/
68: ;/****************************************************************************/
69: NON::; 割込み未使用
70:
EI
71:
RETI
72: TXRDY::; IR[ 9] TXRDY
73:
PUSH
AF
74:
PUSH
BC
128

75:
PUSH
DE
76:
PUSH
HL
77:
PUSH
IX
78:
PUSH
IY
79:
CALL
Txrdy̲##
80:
POP
IY
81:
POP
IX
82:
POP
HL
83:
POP
DE
84:
POP
BC
85:
POP
AF
86:
EI
87:
RETI
88: RXRDY::; IR[10] RXRDY
89:
PUSH
AF
90:
PUSH
BC
91:
PUSH
DE
92:
PUSH
HL
93:
PUSH
IX
94:
PUSH
IY
95:
CALL
Rxrdy̲##
96:
POP
IY
97:
POP
IX
98:
POP
HL
99:
POP
DE
100:
POP
BC
101:
POP
AF
102:
EI
103:
RETI
104: TIMER0::; IR[12] TIMER 0
105:
PUSH
AF
106:
PUSH
BC
107:
PUSH
DE
108:
PUSH
HL
109:
PUSH
IX
110:
PUSH
IY
111:
CALL
Timer0̲##
112:
POP
IY
113:
POP
IX
114:
POP
HL
115:
POP
DE
116:
POP
BC
117:
POP
AF
118:
EI
119:
RETI
120: ;/****************************************************************************/
121: ;/*
終了（C ｿｰｽへのｴﾝﾄﾘｰ）*/
129122: ;/****************************************************************************/
123:
ORG
0x200
124:
END

［リストの説明］ 前章に変更を加えた個所を説明します。
５９行：
ＴＸＲＤＹ割り込みのベクターテーブルです。
６０行：
ＲＸＲＤＹ割り込みのベクターテーブルです。
７２〜１０３行：
ＴＸＲＤＹとＲＸＲＤＹ用の割り込みハンドラを追加しました。
Ｃ言語記述関数名は、ＴＸＲＤＹ＝“Ｔｘｒｄｙ（）” ＲＸＲＤＹ＝“Ｒｘｒｄｙ（）
”です。

130

２．ＵＳＡＲＴモジュールを割り込み用に変更する。
割り込みに対応するため、割り込み用送受信関数が必要になります。
また、
ポーリング時は１文字での送受信ループバック動作でしたが、今回は割り込みサンプルですので、文字列での送受信ループバック動作をさせます。
プログラム例に沿って説明します。
１）プログラムリスト
file “I_Usart.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ 割込み
*/
4: /*
*/
5: /* ＜MOD＞
I̲Usart.c*/
6: /* ＜役割＞
USART(SIO) 関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
ETC*/
17: /****************************************************************************/
18: #define NON
0/* ﾊﾟﾘﾃｨ
NON*/
19: #define EVEN
1
/*
EVEN
*/
20: #define ODD
2
/*
ODD
*/
21: #define STX
0x2/* 送信スタートコード*/
22: #define ETX
0x3/* 送信ストップコード*/
23: /****************************************************************************/
24: /*
変数宣言*/
25: /****************************************************************************/
26:
Uchar
K51Step;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ
*/
27:
Uchar
K51Select;/* ﾎﾞｰﾚｰﾄ選択
*/
28:
29:
Uchar
TxDat[16];/* 送信ﾃﾞｰﾀ
*/
30:
Uchar
TxIdx;/* 送信中 ｲﾝﾃﾞｯｸｽ
*/
31:
Uchar
TxCnt;/* 送信残 ｶｳﾝﾀ
*/
32:
Uchar
RxDat[16];/* 受信ﾃﾞｰﾀ
*/
33:
Uchar
RxIdx;/* 受信中 ｲﾝﾃﾞｯｸｽ
*/
34:
Uchar
RxEnd;/* 受信終了ﾌﾗｸﾞ*/
35: const Ushort
BpsTbl[] =
36: {
131

37:
1200,
38:
2400,
39:
4800,
40:
9600,
41:
19200,
42:
38400,
43:0,44: };
45: /****************************************************************************/
46: /*
Ｍｅｍ初期化*/
47: /****************************************************************************/
48: void
K51MemInitial(void)
49: {
50:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
51:
K51Select = 2;/* 9600BPS*/
52: }53: /****************************************************************************/
54: /*
Ｉ／Ｏ初期化*/
55: /****************************************************************************/
56: void
K51IoInitial(void)
57: {
58:
RsOpen(9600,8,0);
59: }
60: /****************************************************************************/
61: /*
RS232C Open bps= ﾎﾞﾚｰﾄ[1200,2400,4800,*9600,19200,38400]*/
62: /*ch= ｷｬﾗｸﾀ[7,*8]*/
63: /*
pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/
64: /**= ﾃﾞﾌｫﾙﾄ
*/65: /*
固定 = STOP=1bit*/
66: /*
ﾎﾞｰﾚｰﾄ = 内臓ﾎﾞｰﾚｰﾄジェネレータを使用*/
67: /****************************************************************************/
68: void
RsOpen(Ushort bps,Uchar ch,Uchar pty)
69: {
70:
Uchar cyc;
71:
Uchar mode;72:
73:
outp(K51RATE,2);/* UART ｸﾛｯｸｼﾞｪﾈﾚｰﾄ
*/74:/* 7,372,800/((2+1)*(2^(BCK+1)))/16 */75:
cyc = 0xE1;/* Cmd B ﾎﾞｰﾚｰﾄ(ﾃﾞﾌｫﾙﾄ) 9600bps
*/
76:
if
(bps == 1200) cyc = 0xE7; /*BCK<6> 1200bps*/
77:else if (bps == 2400) cyc = 0xE6; /*BCK<5> 2400bps*/
78:else if (bps == 4800) cyc = 0xE5; /*BCK<4> 4800bps*/
79:else if (bps == 9600) cyc = 0xE4; /*BCK<3> 9600bps*/
80:else if (bps == 19200) cyc = 0xE3; /*BCK<2> 19200bps*/
81:
else if (bps == 38400) cyc = 0xE2; /*BCK<1> 38400bps
*/
82:
/*
BCK<0> 76800bps Unused*/
83:
mode = 0x0e;/* Mode Stop=1 NON 8bit
*/
132

84:
if
(pty == EVEN) mode |= 0x30; /*ﾊﾟﾘﾃｨ=EVEN*/
85:
else if (pty == ODD) mode |= 0x20; /*ﾊﾟﾘﾃｨ=ODD*/
86:
if (ch == 7) mode &= ~(0x4);/*
ｷｬﾗｸﾀ 7*/87:
outp(K51COM0,0);/* KP51 ﾀﾞﾐｰ*/
88:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
89:
outp(K51COM0,0);
/*
ﾀﾞﾐｰ
*/
90:
outp(K51COM0,0x40);/*
ｿﾌﾄﾘｾｯﾄ*/91:
outp(K51COM0,mode);/* Mode Set*/
92:
outp(K51COM0,0x36);/* Cmd A Set RTS ERR RX=EI DTR TX=DI*/93:
outp(K51COM0,cyc);/* Cmd B Set*/
94: }95: /****************************************************************************/
96: /*
TxStart
RS232C 文字列送信(TXRDY 割込み準備)*/
97: /****************************************************************************/
98: void
TxStart(Uchar *tx,Uchar cnt)
99: {
100:
TxDat[0] = STX;/* スタートコード*/
101:
memcpy(&TxDat[1],tx,cnt);/* 送信ﾊﾞｯﾌｧｰに記憶*/
102:
TxDat[cnt+1] = ETX;/* ストップコード*/
103:
TxIdx = 0;/* 送信中ｲﾝﾃﾞｯｸｽ*/
104:
TxCnt = cnt+2;/* 送信残ｶｳﾝﾀ*/
105:
outp(K51COM0,0x37);/* Cmd RTS ERR RX=EI DTR TX=EI*/
106: }
107: /****************************************************************************/
108: /*Txrdy
TXRDY 割込み
割り込みハンドラより呼ばれる*/
109: /****************************************************************************/
110: void
Txrdy()
111: {112:
if (TxCnt == 0) outp(K51COM0,0x36); /* 送信終了 TX=DI にする*/
113:
else {
114:
outp(K51DAT0,TxDat[TxIdx]);
115:++TxIdx;
116:--TxCnt;
117:}
118: }
119: /****************************************************************************/
120: /*Rxrdy
RXRDY 割込み
割り込みハンドラより呼ばれる*/
121: /****************************************************************************/
121:2void
Rxrdy()
123: {
124:
Uchar dt;125:
126:
dt = inp(K51DAT0);
/* 受信
*/
127:
if ((inp(K51COM0) & 0x38)) {/* USART Error?
*/128:
outp(K51COM0,0x32);/* ERR Reset RX=DI TX=DI*/
129:
RxIdx = 0;
130:
}
133

131:
else {/* 正常受信*/132:
if (dt == STX) RxIdx = 0;/* スタートコード*/
133:
else if (dt == ETX) RxEnd = ON;/* 受信終了ﾌﾗｸﾞｾｯﾄ*/
134:
else {/* 受信データ*/
135:
RxDat[RxIdx++] = dt;
136:
if (RxIdx >= sizeof(RxDat)) RxIdx = 0; /* ﾊﾞﾌｧｰｵｰﾊﾞｰの防止
*/
137:
}
138:
}
139: }
140: /****************************************************************************/
141: /*
UsartDemo()
ＵＳＡＲＴデモ*/142: /****************************************************************************/
143: void
K51Demo()144: {
145:
K51Sequence();/* Usart 操作ｺﾝﾄﾛｰﾙ*/
146:
switch(K51Step) {147:
case 0:148:
break;
149:
case 1:
150:
RsOpen(BpsTbl[K51Select],8,0); /* RS232C Open*/151:
K51Step++;
152:
break;
153:
case 2:
154:
RxEnd = OFF;/* 受信終了ﾌﾗｸﾞ*/
155:
TxStart("I t r u t C",11);/* 送信/受信割込み開始*/
156:
TmStart(TM1,500);/* ﾀｲﾑｵｰﾊﾞｰ管理*/
157:
K51Step++;
158:
break;
159:
case 3:160:
if (RxEnd == ON) {/* 受信終了を待つ*/
161:
RxDat[RxIdx] = 0;/* 確認用の表示データ作成*/
162:
GotoxyMemSet(0,0,RxDat);/* 受信割込みﾃﾞｰﾀ表示*/
163:
K51Step = 4;
164:
}
165:
else if (TmUpTest(TM1) == ON) {/* ﾀｲﾑｵｰﾊﾞｰ*/
166:
GotoxyMemSet(0,0,"ﾀｲﾑｵｰﾊﾞｰ "); /* Error 表示*/
167:
K51Step = 4;
168:
}
169:
break;
170:
case 4:171:
RxEnd = OFF;/* 受信終了ﾌﾗｸﾞ*/
172:
TxStart(" n e r p S ",11);/* 送信/受信割込み開始*/
173:
TmStart(TM1,500);/* ﾀｲﾑｵｰﾊﾞｰ管理*/
174:
K51Step++;
175:
break;
176:
case 5:177:
if (RxEnd == ON) {/* 受信終了を待つ
*/
134

178:
RxDat[RxIdx] = 0;/* 確認用の表示データ作成*/
179:
GotoxyMemSet(0,0,RxDat);/* 受信割込みﾃﾞｰﾀ表示*/
180:
K51Step = 2;
181:
}
182:
else if (TmUpTest(TM1) == ON) {/* ﾀｲﾑｵｰﾊﾞｰ*/183:
GotoxyMemSet(0,0,"ﾀｲﾑｵｰﾊﾞｰ "); /* Error 表示*/
184:
K51Step = 2;
185:
}
186:
break;
187:}
188: }
189: /****************************************************************************/
190: /*K51Sequence() Usart 操作ｺﾝﾄﾛｰﾙ*/
191: /****************************************************************************/
192: void
K51Sequence()
193: {
194:
Uchar port;
195:
Uchar dec[5+1];
196:
197:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/198:
if (port & 0xe0) {/* PB[P31]->PB[P33] ON(立上) ?
*/199:
if (port & 0x20) {/* PB[P31] ON ? 送信ｽﾀｰﾄ/ｽﾄｯﾌﾟ*/200:
if (K51Step == 0) K51Step = 1;
201:
else
K51Step = 0;
202:
}
203:
if (K51Step == 0) {/* 停止中のみ受け付ける*/
204:
if (port & 0x40) {/* PB[P32] ON ? ﾎﾞﾚｰﾄ下げ?
*/
205:
if (K51Select != 0) --K51Select;
206:
}
207:
else if (port & 0x80) {/* PB[P33] ON ? ﾎﾞﾚｰﾄ上げ?
*/
208:
if (BpsTbl[K51Select+1] != 0) ++K51Select;
209:
}
210:
Bin2AdecN(dec,BpsTbl[K51Select],5); /* 表示用データ作成*/
211:
GotoxyMemSet(0,1,dec);
212:
}
213:
}
214: }

135

［リストの説明］ 前章に変更を加えた個所を説明します。
２１〜２２行：
文字列データの最初と最後を示すコードのシンボル定義です。
２９〜３１行：
送信割り込み関数で使用する変数の宣言です。
３２〜３４行：
受信割り込み関数で使用する変数の宣言です。
８４行：送受信を割り込み処理にする場合、初期化の段階では送信はディセーブル状態にしておく必要があります。
９８〜１０６行：
送受信割り込みを開始させる関数です。
１００〜１０４行は、文字列送信を割り込みで処理するための準備です。
準備終了後、送信をイネーブル状態にし“ＴＸＲＤＹ”割り込みで文字列データを１バイトごとに割り込み発生毎に送信をします。
１１０〜１１８行：
ＴＸＲＤＹ（送信）割り込みハンドラより呼ばれる関数です。
１バイト毎に送信可能状態（ＴＸＲＤＹ）になると割り込みが発生します。
送信するデータがなくなった場合は、送信をディセーブル状態にして割り込みを止めます。
１２１〜１３９行：
ＲＸＲＤＹ（受信）割り込みハンドラより呼ばれる関数です。
１バイト毎に受信完了後、データ呼びだし可能状態（ＲＸＲＤＹ）になると割り込みが発生します。
受信データがＳＴＸ“￥ｘ０２”の場合、テキストスタートと判断して、内部インデックスをゼロ（０）にします。
受信データがＥＴＸ“￥ｘ０３”の場合、テキスト終了と判断して、受信終了フラグを立てます。
その他の受信データは、内部受信バッファーにセットしていきます。
エラーが発生した場合は、エラーリセット後内部インデックスカウンタをクリアにしています。
１４３〜１８８行：
ＵＳＡＲＴの動作確認用の関数です。
文字列送信後、文字列受信の終了を待ち,終了後ＬＣＤに表示させています。
この動作を、ＰＢ［Ｐ３１］ＯＮか、もしくはエラー発生するまで繰り返します。
無応答判定も、タイマー割り込みを利用した内部ソフトタイマを使用しましたので、ポーリング時に使用していたループソフトタイマを排除しました。

136

３．メインコントロール部の割り込みコントローラを変更する。
ＵＳＡＲＴ割り込みを可能にするため、割り込みコントローラの設定変更が必要です。
プログラム例に沿って説明します。
１）プログラムリスト
file “Cat203i2.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ 割込み
*/
4: /*
*/
5: /* ＜MOD＞
Cat203i2.c*/
6: /* ＜役割＞
main*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
外部変数使用
*/17: /****************************************************************************/
18: extern short
BuzzerHz;/* TIMER Buzzer Hz*/
19: extern Uchar
K51Step;/* USART ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
20: extern Uchar
K51Select;/*
ﾎﾞｰﾚｰﾄ選択*/
21: extern Uchar
MelStep;/* Melody ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
22: extern Uchar
MelMode;/*
演奏ﾓｰﾄﾞ
*/23: extern Uchar
MelSelect;
/*
自動選曲
*/
24: /****************************************************************************/
25: /*
変数宣言*/
26: /****************************************************************************/
27:
Uchar
ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
*/
28:
Uchar
Shift;/* shift ﾊﾟﾀｰﾝ*/29: /****************************************************************************/
30: /*
main()*/
31: /****************************************************************************/
32: voidmain(void)
33: {
34:
outp(SCR4,0x33);/* SYS ExtMem 0wait ExtIO 1wait
*/
35:
/*
P01->OUT1,P02->OUT2,P03->OUT3*/36:
SoftWait1ms(20);/* Power On Wait(20ms) 安定待ち*/
37:
MemInitial();/* ﾒﾓﾘ系初期化*/
38:
IoInitial();/* I/O 系初期化*/
39:
TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ
*/
137

40:
ei();
/* <- 割り込み許可*/
41:
while(1) {42:
if (TmUpTest(TM0) == ON) {43:
TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ*/
44:
SigInput();/* Signal Input Process*/
45:
ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
46:
SigOutput();/* Signal Output Process
*/
47:
}
48:
AllLcdDisp();/* LCD
全画面表示
*/
49:
}
50: }
51: /****************************************************************************/
52: /*
Ｍｅｍ初期化*/
53: /****************************************************************************/
54: void
MemInitial(void)
55: {
56:
ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ*/
57:
Shift = 0;/* Led Disp Patan Initial
*/
58:
59:
PioMemInitial();/* PIOMem 初期化*/60:
LcdMemInitial();/* LCDMem 初期化*/
61:
TimMemInitial();/* TIM
Mem 初期化*/
62:
K51MemInitial();/* SIOMem 初期化*/
63:
MelMemInitial();/* Melody Mem 初期化*/
64: }65: /****************************************************************************/
66: /*
Ｉ／Ｏ初期化*/
67: /****************************************************************************/
68: void
IoInitial(void)
69: {
70:
PioIoInitial();/* PIOI/O 初期化*/
71:
LcdIoInitial();/* LCDI/O 初期化*/
72:
TimIoInitial();/* TIMI/O 初期化*/
73:
K51IoInitial();/* SIOI/O 初期化*/
74:
MelIoInitial();/* Melody I/O 初期化
*/
75:
76:
outp(LERL,0);/* 割込<- ﾚﾍﾞﾙ/ｴｯｼﾞ設定*/
77:
outp(LERH,0x10);/*<- IR[12]TIMER 0 ｴｯｼﾞ*/78:
outp(IVR,0x80);/*<- 先頭ﾍﾞｸﾀ 80H*/
79:
outp(PGRL,0);/*<- ﾌﾟﾗｲｵﾘﾃｨの設定*/
80:
outp(PGRH,0x4);/*<- IR[10]RXRDY(High)*/81:
outp(IMRL,0xFF);/*<- ﾏｽｸﾚｼﾞｽﾀ*/82:
outp(IMRH,0xE9);/*<- IR[12]TIMER 0
*/
83:
/*
<- IR[10]RXRDY
*/
84:
/*
<- IR[ 9]TXRDY*/
85: }86: /****************************************************************************/
138

87: /*
ModeCntrol()
ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/
88: /****************************************************************************/
89: void
ModeCntrol()
90: {
91:
if (GetUpPort(1) & 0x10) {/* PB[P30] ON?(立上)*/92:
if (ModeStep < 10)
ModeStep = 10;/* PIO Goto TEST*/
93:
else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST*/
94:
else if (ModeStep < 30) ModeStep = 30;/* USART Goto TEST*/
95:
else if (ModeStep < 40) ModeStep = 40;/* Demo Melody
*/
96:
else
ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
97:
Buzzer(0);/* 強制 OFF
*/
98:
}
99:
switch(ModeStep) {100:case 0:101:
GotoxyMemSet(0,0,"CAT203&BF3000 by");/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*/
102:
GotoxyMemSet(0,1,"Interrupt [P30]");103:
ModeStep++;
104:
break;
105:
case 1:
106:
RunRun();107:
break;
108:
case 10:/* PIO TEST*/
109:
GotoxyMemSet(0,0,"PIO");
110:
GotoxyMemSet(0,1,"SW[P47]->SW[P40]");111:
ModeStep++;
112:
break;
113:
case 11:114:
PioDemo();115:
break;
116:
case 20:/* Timer TEST*/
117:
GotoxyMemSet(0,0,"Timer/Counter ");118:
GotoxyMemSet(0,1,"0000Hz[+P33-P32]");
119:
BuzzerHz = 0;/* Buzzer Hz*/
120:
ModeStep++;
121:
break;
122:case 21:123:
TimerDemo();
124:
RunRun();125:
break;
126:
case 30:/* USART TEST*/
127:
GotoxyMemSet(0,0,"Usart 8,n,1[P31]");
128:
GotoxyMemSet(0,1,"09600b[+P33-P32]");
129:
K51Step = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
130:
K51Select = 3;/* 9600BPS*/
131:
ModeStep++;
132:
break;
133:
case 31:
139

134:
K51Demo();
135:
RunRun();136:
break;
137:
case 40:/* Demo Melody*/
138:
GotoxyMemSet(0,0,"Melody");
139:
GotoxyMemSet(0,1,"P31[M]33[ｽ]32[ｾ]");140:
MelStep = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
141:
MelMode = 0;/* 演奏ﾓｰﾄﾞ*/
142:
MelSelect = 0;/* 自動選曲*/
143:
ModeStep++;
144:
break;
145:
case 41:
146:
Melody();147:
RunRun();148:
break;
149:}
150: }
151: /****************************************************************************/
152: /*
RunRun()
CPU 走行表示*/
153: /****************************************************************************/
154: void
RunRun()155: {
156:
if ((Shift <<= 1) == 0) Shift = 1;/* LED Shift 表示*/
157:
PutOutPort(Shift,'=');
158: }
159: /****************************************************************************/
160: /*
SoftWait1ms() 1ms 単位 ｿﾌﾄﾀｲﾏｰ*/
161: /****************************************************************************/
162: void
SoftWait1ms(Ushort ms)
163: {
164:
while(ms-- != 0) {165:
Wait1ms();
166:}
167: }
168: /****************************************************************************/
169: /*
Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
170: /****************************************************************************/
171: void
Wait1ms()
172: {
173:
̲asm̲("\n
PUSH
HL
\n");
174:
̲asm̲("\nLD
HL,1228\n"); /* 1228*6=7372cyc */175:
̲asm̲("\n W01:
\n");
176:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/
177:̲asm̲("\nLDA,L\n"); /*
= 1
*/
178:
̲asm̲("\nORH\n"); /*
= 1
*/
179:
̲asm̲("\nJP
NZ,W01\n"); /*
= 3
*/
180:
̲asm̲("\nPOP
HL\n"); /*
+= 6
*/
140

181: }
182: /****************************************************************************/
183: /*
SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/
184: /****************************************************************************/
185: void
SoftWait10us(Ushort us)
186: {
187:
while(us-- != 0) {188:
Wait10us();189:}
190: }
191: /****************************************************************************/
192: /*
Wait10us()
10us ｿﾌﾄﾀｲﾏｰ (7.3728MHz) Non Wait*/
193: /****************************************************************************/
194: void
Wait10us()
195: {
196:
̲asm̲("\n
PUSH
HL
\n");
197:
̲asm̲("\nLDHL,13\n"); /* 13*6=78cyc*/
198:̲asm̲("\n W02:
\n");
199:
̲asm̲("\nDEC
HL\n"); /* cyc = 1*/200:̲asm̲("\nLDA,L\n"); /*
= 1
*/
201:
̲asm̲("\nORH\n"); /*
= 1
*/
202:
̲asm̲("\nJP
NZ,W02\n"); /*
= 3
*/
203:
̲asm̲("\nPOP
HL\n"); /*+= 6*/
204: }

141

［リストの説明］

前章に変更を加えた個所を説明します。

このモジュールでの変更は、割り込みコントローラへの設定変更のみです。
８０行：
割り込みプライオリティの変更をしました。
ＩＲ［１０］ＲＸＲＤＹ を“ＨＩＧＨ”グループにしました。
通常ＲＸＲＤＹは、いつ発生するか不定のため“ＨＩＧＨ”グループにした方が良いと思います。
８２行：マスク解除を、ＩＲ［１２］ＴＩＭＥＲ ＣＨ０、ＩＲ［１０］ＲＸＲＤＹ，ＩＲ［９］ＴＸＲＤＹの３つ解除しました。
以上の変更で、タイマー／ＵＳＡＲＴ割り込み対応のシステムに変貌したわけです。
動作的には、ＵＳＡＲＴが文字列通信部分を変更しただけですが、動作確認してみましょう。
ＡＢＣｗｉｎでダウンロード後、プログラム実行をして下さい。

ここまでの変更では、メロディの割り込み対応は済んでいません。
次章は、メロディの割り込み対応にし、より良いシステムに変貌させたいと思います。

142

第３章 割込み総合デモ（メロディ）
いよいよ、前章までに築き上げた割り込みシステムを利用した、応用例として割込み総合デモ（メロディ♪♪）のアプリケーション作り上げの最終解説となりました。
リストに沿って説明を進めていきます。
￥評価ボード￥第２部割込み編￥第３章割込み総合デモ（メロディ）￥にディレクトリの移動をしておいて下さい。
１．総合デモ（メロディ）を割り込み対応にする。
ここで残された問題は、リズム（音の長さ）を調整している部分が、いまだにソフトタイマー（ループ式）を利用していることです。
これがシステムの反応（スイッチ入力反応）を鈍らせている原因です。ここを改善します。
１）プログラムリスト
file “I_Melody.c”
1: /****************************************************************************/
2: /**/
3: /* ＜サンプル＞ 割込み
*/
4: /*
*/
5: /* ＜MOD＞
I̲Melody.c*/
6: /* ＜役割＞
デモ メロディー関係*/
7: /* ＜TAB＞
４タブ編集*/
8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/
9: /* ＜使用ﾊｰﾄﾞ＞ CAT-203-KL5C8016 エーワン(株)*/10: /**/
11: /****************************************************************************/
12: #include<machine.H>
13: #include"CAT203.H"
14: #include"DemoCtl.h"
15: /****************************************************************************/
16: /*
音階 Hz*/
17: /****************************************************************************/
18: #define dO262/* ̲ド */
19: #define rE293/* ̲ﾚ */
20: #define mI330/* ̲ﾐ */
21: #define fhA
349/* ̲ﾌｧ */22: #define sO392/* ̲ｿ */
23: #define rA440/* ̲ﾗ */
24: #define sI494/* ̲ｼ */
25: #define do523/* ド */
26: #define re587/* ﾚ */
27: #define mi
659/* ﾐ */
28: #define fha
698/* ﾌｧ */
29: #define so784/* ｿ */
143

30: #define ra
880/* ﾗ */
31: #define si
987/* ｼ */
32: #define Do
1047/* ド */
33: #define SCMAX
32/* 楽譜テーブルの最大数*/
34: /****************************************************************************/
35: /*
変数宣言*/
36: /****************************************************************************/
37:
UshortMelodyHz;/* Melody Hz
*/
38:
Uchar
MelMode;/* 演奏ﾓｰﾄﾞ
*/
39:
Uchar
MelSelect;/* 自動選曲
*/
40:
Uchar
MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ
*/
41:
Uchar
Music;/* 自動演奏ｶｳﾝﾀｰ*/
42:
UshortDoremi[SCMAX];/* ﾄﾞﾚﾐ音階周波数(Hz)の RAM 側*/
43:
UshortRhythm[SCMAX];/* ﾘｽﾞﾑ(msec)*/
44: const Ushort
DoremiTbl[] =/* ﾄﾞﾚﾐ音階周波数(Hz)
*/
45: {
46:
do,
/* ド */
47:
re,/* ﾚ */48:mi,/* ﾐ */
49:fha,/* ﾌｧ */
50:so,/* ｿ */
51:ra,/* ﾗ */
52:si,/* ｼ */
53:
Do,/* ド */
54:
055: };
56: const UshortMusicTbl[3][SCMAX] =/* 自動演奏の楽譜（最大 32 ﾏﾃﾞ） */57: {/* ﾈｺﾌﾝｼﾞｬｯﾀ */58:{ ra, so, do, Do, Do, ra, so, do, Do, Do,
59:
ra, so, do, Do, rA, Do, sO, si, si},60:/* ｲﾇﾉｵﾏﾜﾘｻﾝ */61:{ mi, do, do, do, mi, do, do, do,fha,fha, mi, mi, re,62:
fha,fha, mi, mi, re, re, ra, ra, so,fha, mi, re, do},63:/* ｱﾏﾘﾘｽ*/
64:{ so, ra, so, Do, so, ra, so, ra, ra, so, ra, so,fha, mi, re, mi, do, 0},65: };
66: const Ushort
RhythmTbl[3][SCMAX] = /* 自動演奏のリズム(最大 32 ﾏﾃﾞ） */67: {/* ﾈｺﾌﾝｼﾞｬｯﾀ */68:{250,250,500,500,500,250,250,500,500,500,
69:
250,250,500,500,500,500,500,500,500},70:/* ｲﾇﾉｵﾏﾜﾘｻﾝ */71:{250,250,250,250,250,250,250,250,250,250,250,250,1000,72:
250,250,250,250,250,250,250,250,250,250,250,250,1000,},73:/* ｱﾏﾘﾘｽ*/
74:{500,500,500,500,500,500,1000,500,500,500,500,250,250,250,250,500,500, 0},75: };
76: const Uchar*MelodyTblA[] =/* 自動演奏の曲名*/
144

77: {
78:"",
79:"ﾈｺﾌﾝｼﾞｬｯﾀ",80:"ｲﾇﾉｵﾏﾜﾘｻﾝ",81:"ｱﾏﾘﾘｽ",82: };
83: /****************************************************************************/
84: /*
Melodyﾒﾛﾃﾞｨｰｺﾝﾄﾛｰﾙ*/
85: /****************************************************************************/
86: void
Melody()87: {88:MelodySequence();/* ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/
89:
if (MelMode == 0) ManualMelody(); /* 手動演奏
*/
90:
else
AutoMelody();/* 自動演奏*/
91: }
92: /****************************************************************************/
93: /*
MelodySequence()
ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/
94: /****************************************************************************/
95: void
MelodySequence()
96: {
97:
Uchar port;
98:
99:
port = GetUpPort(1);/* PB[P30]->PB[P33]*/100:
if (port & 0xe0) {/* PB[P31]->PB[P33] ON(立上) ?
*/101:
Buzzer(0);/* Buzer OFF*/
102:
if (port & 0x20) {/* PB[P31] ON ? ﾓｰﾄﾞ変更*/
103:
MelStep = 0;/* 強制停止*/104:
if (MelMode == 0) {/* 現在手動 ?
*/105:
MelMode = 1;/* 自動に変更*/
106:
MelSelect = 1;/* 自動選曲
*/
107:
}
108:
else {/* 現在自動 ?
*/109:
MelMode = 0;/* 手動に変更*/
110:
MelSelect = 0;/* 自動選曲
*/
111:
}
112:
}
113:
if (MelMode != 0) {/* 自動 ?
*/
114:
if (port & 0x40) {/* PB[P32] ON ? 選曲*/
115:
MelStep = 0;/* 強制停止*/116:
if (++MelSelect > 3) MelSelect = 1;
117:
}
118:
if (port & 0x80) {/* PB[P33] ON ? 自動演奏開始*/
119:
if (MelStep == 0) MelStep = 1;
/* 開始
*/
120:
else
MelStep = 0;
/* 停止
*/
121:
Music = 0;
122:
}
123:
}
145

124:
if (MelMode == 0) GotoxyMemSet(4,1,"M");/* 手動表示
*/
125:
else
GotoxyMemSet(4,1,"A");/* 自動表示*/126:
GotoxyMemSet(7,0,(Uchar *)MelodyTblA[MelSelect]); /* 曲名表示
*/
127:
}
128: }
129: /****************************************************************************/
130: /*
Ｍｅｍ初期化
*/131: /****************************************************************************/
132: void
MelMemInitial(void)
133: {
134:
MelodyHz = 0;/* Melody Min Hz*/
135:
MelMode = 0;/* 演奏ﾓｰﾄﾞ*/
136:
MelStep = 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/
137:
MelSelect = 0;/* 自動選曲*/
138: }
139: /****************************************************************************/
140: /*
Ｉ／Ｏ初期化
*/141: /****************************************************************************/
142: void
MelIoInitial(void)
143: {
144:
Buzzer(0);/* Buzer OFF*/
145: }
146: /****************************************************************************/
147: /*
ManualMelody 手動ﾒﾛﾃﾞｨｰ演奏*/
148: /****************************************************************************/
149: void
ManualMelody()
150: {
151:
Uchar port;
152:
153:
switch(MelStep) {154:
case 0:155:
̲strcpyW(Doremi,(Ushort *)DoremiTbl); /* ﾄﾞﾚﾐ音階周波数(初期準備)*/
156:
MelStep++;
157:
break;
158:
case 1:
159:
if (GetInPort(0) & 0xff) {/* P40->P47 どれかがＯＮしたか？
*/
160:
port = GetUpPort(0);161:
if (port & 0x1) {/* SW[P40] 立上がり ON (ド)*/162:
Buzzer(MelodyHz = Doremi[7]);
163:
}
164:
else if (port & 0x2) {/* SW[P41] 立上がり ON (レ)*/165:
Buzzer(MelodyHz = Doremi[6]);
166:
}
167:
else if (port & 0x4) {/* SW[P42] 立上がり ON (ミ)*/168:
Buzzer(MelodyHz = Doremi[5]);
169:
}
170:
else if (port & 0x8) {/* SW[P43] 立上がり ON (ファ)
*/
146

171:
Buzzer(MelodyHz = Doremi[4]);
172:
}
173:
else if (port & 0x10) {/* SW[P44] 立上がり ON (ソ)*/174:
Buzzer(MelodyHz = Doremi[3]);
175:
}
176:
else if (port & 0x20) {/* SW[P45] 立上がり ON (ラ)*/177:
Buzzer(MelodyHz = Doremi[2]);
178:
}
179:
else if (port & 0x40) {/* SW[P46] 立上がり ON (シ)*/180:
Buzzer(MelodyHz = Doremi[1]);
181:
}
182:
else if (port & 0x80) {/* SW[P47] 立上がり ON (ド)*/183:
Buzzer(MelodyHz = Doremi[0]);
184:
}
185:
}
186:
else if (MelodyHz != 0) {/* Buzzer 停止*/
187:
Buzzer(MelodyHz = 0);
188:
}
189:
break;
190:}
191: }
192: /****************************************************************************/
193: /*
AutoMelody 自動ﾒﾛﾃﾞｨｰ演奏*/
194: /****************************************************************************/
195: void
AutoMelody()
196: {
197:
switch(MelStep) {198:
case 0:199:
break;
200:
case 1:201:
̲strcpyW(Doremi,(Ushort *)&MusicTbl[MelSelect-1][0]);202:̲strcpyW(Rhythm,(Ushort *)&RhythmTbl[MelSelect-1][0]);203:++MelStep;
204:
break;
205:
case 2:
206:
MelodyHz = Doremi[Music];
/* 楽譜
*/
207:
if (MelodyHz != 0) {/* 演奏中*/208:
Buzzer(MelodyHz);209:
TmStart(TM2,Rhythm[Music]); /* <-リズム開始 */210:++MelStep;
211:
}
212:
else {
213:
Buzzer(0);
/* 停止
*/
214:
Music = 0;
215:
TmStart(TM2,500);/* <-連続時の間 */216:
MelStep = 4;
217:
}
147

218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231: }

break;
case 3:if (TmUpTest(TM2) == ON) {Music++;
MelStep = 2;}
break;
case 4:
if (TmUpTest(TM2) == ON) {MelStep = 2;}
break;}/* <-リズム*//* <-連続時の間 */148

［リストの説明］ 前章に変更を加えた個所を説明します。
２０９行： ２１５行： ２２０行： ２２６行：
自動演奏のソフトタイマ使用部分を、割り込み内部ソフトタイマに変更しました。
これで、通常動作時のソフトタイマ（ループ方式）使用は、全て排除したかたちになりました。
どの程度、動作がスムーズになったか、動かして確認して見ましょう。
ＡＢＣｗｉｎでダウンロード後、プログラム実行をして下さい。

いかがですか？
自動演奏を実行した時にＬＥＤが止まらないでしょう！
（止まるのも味があるのですが、今回の目的とは違います）
それに、いつＰＢ［Ｐｎｎ］を押しても即反応するでしょう！
これでシステムの反応が良くなりました。これが割り込み処理を導入したことによるメリットです。
しかし、このシステムには改造する部分（半音が入っていない等…）が、まだあると思います。
どうぞ改造にチャレンジして、より良いシステムに構築してみて下さい！！ 期待しています。
これで、この解説テキストの終了とします。
この内容で満足して頂いたとは思いませんが、皆様のご協力で成長させていきたいと思っています。
メールで頂いたご意見、ご質問を、出来る限り反映させ、より良い解説テキストにしていきたいと考えていますので、ご指導の程よろしくお願い致します。
２００２年 ３月 著者

149