評価ボード
アセンブラ・C 言語による実践解説テキスト（ＡＨＥ２６１－ＣＡＴ２６１ ｆｏｒ ルネサス純正Ｃ［ＨＥＷ］版）

初版

２００２年 ４月

第２版 ２００３年 ２月
第 3 版 ２００３年 ４月
第４版 ２００４年 ６月
第５版 ２００５年 ９月
第６版 ２００６年 ７月

Ｒｅｖ１．０６（２００６／０７／２１）

序

はじめに

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

エーワン㈱ 技術部 長谷川正博
URL: http://www.aone.co.jp
mail: hasegawa@aone.co.jp［変更履歴］
２００５年９月：ＤＥＦバージョン４．８０Ａより、割り込みモード０／２両対応にした為、一部説明を変更する。
２００６年７月：ＤＥＦバージョン５．７０Ａより、リセット遅延防止タイマ未使用の指定が出来るようになった為、一部説明を追加する。

［参考文献］
本書は、㈱ルネサス テクノロジのご了解をいただき以下のマニュアルから転用しております。
Ｈ８Ｓ／２６１２シリーズ ハードウェアマニュアル（ＡＤＪ－６０２－２４２Ａ）㈱ルネサス テクノロジ
マニュアルが改訂されていることもございますので、最新版はＷｅｂ上でご確認下さい。

筋書および概説

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

［バージョン］
ＨＥＷ

Ｖｅｒ １．２（ｒｅｌｅａｓｅ ９）

Ｈ８Ｓ，Ｈ８／３００ Ｃ／Ｃ＋＋ Ｃｏｍｐｉｌｅｒ Ｖｅｒ ４．０Ａ
Ｈ８Ｓ，Ｈ８／３００ Ａｓｓｅｍｂｌｅｒ

Ｖｅｒ ４．０Ａ

ＯｐｔＬｉｎｋｅｒ

Ｖｅｒ ７．０の環境で作成しました。

［注意事項］
この解説書は、デバッガＩ／ＦがブートポートタイプのＰＢＣ搭載ＣＰＵを元にした説明です。
デバッガＩ／Ｆが、Ｈ－ＵＤＩタイプおよびＥ７／Ｅ１０タイプとは一部相違があります。

目

次

ハード構成およびシステム構成 ................................................................................................................3
第１章 ハード構成........................................................................................................................................3
第２章 システム構成 ....................................................................................................................................4
１．システムブロック図（メロディ♪♪） ..............................................................................................4
２．ＣＡＴ２６１のプログラムメモリＭＡＰ ..........................................................................................5
３．評価ボードのディップ SW の設定とＩ／Ｏマップ表.......................................................................5
４．とにかく動かしてみましょう！！......................................................................................................7
第１部 ポーリング編............................................................................................................................ 11
第１章 スタートアップ .............................................................................................................................. 11
１．動かしてみましょう .......................................................................................................................... 11
２．プログラムリスト..............................................................................................................................12
３．統合環境ＨＥＷの利用.......................................................................................................................21
４．統合環境ＨＥＷを使ってみる ...........................................................................................................24
第２章 ルネサス純正Ｃ言語によるスタートアップ .................................................................................25
１．動かしてみましょう ..........................................................................................................................25
２．プログラムリスト..............................................................................................................................26
３．統合環境ＨＥＷを使ってみる ...........................................................................................................37
第３章 ＰＩＯ..............................................................................................................................................38
１．動かしてみましょう ..........................................................................................................................38
２．プログラムリスト..............................................................................................................................40
第４章 ＰＩＯの応用（ＬＣＤ） ...............................................................................................................50
１．動かしてみましょう ..........................................................................................................................50
２．プログラムリスト..............................................................................................................................51
第５章 タイマ／カウンタ...........................................................................................................................65
１．動かしてみましょう ..........................................................................................................................66
２．プログラムリスト..............................................................................................................................67
第６章 ＳＣＩ..............................................................................................................................................80
１．動かしてみましょう ..........................................................................................................................80
２．プログラムリスト..............................................................................................................................81
第 7 章 総合デモ（メロディ）...................................................................................................................99

1

１．動かしてみましょう ..........................................................................................................................99
２．プログラムリスト............................................................................................................................100
第２部 割込み編................................................................................................................................. 115
第１章 タイマ割込み ................................................................................................................................115
１．ベクターテーブルをタイマ割り込み用に変更する。 ...................................................................116
２．タイマモジュールを割り込み用に変更する。...............................................................................120
３．メインコントロール部を割り込み用に変更する。 .......................................................................128
第２章 ＳＣＩ割込み ................................................................................................................................134
１．ベクターテーブルをＳＣＩ割り込み用に変更する。 ...................................................................135
２．ＳＣＩモジュールを割り込み用に変更する。...............................................................................138
第３章 割込み総合デモ（メロディ）......................................................................................................149
１．総合デモ（メロディ）を割り込み対応にする。...........................................................................1492

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

Ｈ―デバッガ専用シリアル線
超小型マイコンＣＡＴ２６１

ホスト接続線
ＤＯＳ／Ｖ機

評価ボード ＡＨＥ２６１

DC 5V

［接続例］

3

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

１．システムブロック図（メロディ♪♪）

超小型マイコンＣＡＴ２６１（エーワン㈱製）
Ｈ８Ｓ／２６１２ベース
CPU クロック ２０．０ＭＨｚ

ｷｬﾗｸﾀﾀｲﾌﾟ LCD ﾓｼﾞｭｰﾙ
PD0→PD7LCD1DM1602F

PC6：PC7
LED1－＞LED８ ８点
P１0→P１7◎◎◎◎◎◎◎◎
ブザー１個

PB0/TIOCA3

外取り付け必要
ディップ SW１１

RS232C(TXD０)

ループバックテスト用

RS232C(TXD１)

DIP-SW11

２点

RS232C(RXD０)
RS232C(RXD１)
押しボタンスイッチ［PB］
PA0,PC2,PC5,PF7

PA0,PC2,PC５,PF7４点

トグルスイッチ
P40→P47

P40－＞P47[SW] ８点

4

２．ＣＡＴ２６１のプログラムメモリＭＡＰ

０ｘ０番地 ベクターテーブル

CPU 内部
フラッシュＲＯＭ０ｘ８００番地

電源ＯＮ時又はリセット時のＰＣ位置（１２８K）

０ｘ０１ＦＦＦＦ番地

１２８Ｋバイト
ＣＰＵ内蔵ＲＡＭ

０ｘＦＦＥ０００番地

約４Ｋバイト０ｘＦＦＥＦＢＦ番地

初期スタックポインタ位置（０ｘＦＦＥＦＢＥ番地）

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

ＯＦＦ

ＳＷ１１－１

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

シリアルＩ／ＯのTXD０,RXD１間オープン

ＳＷ１１－２

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

シリアルＩ／ＯのTXD１,RXD０間オープン

ＬＣＤ関係
ﾎﾟｰﾄｱﾄﾞﾚｽ

ﾎﾟｰﾄｼﾝﾎﾞﾙ

0xffff0c

PDDR

0xffff0b

PCDR

ピン番号
CN1-7B
1-7A
1-6B
1-6A
1-5B
1-5A
1-4B
1-4A
CN２-9A-9B

ﾋﾟﾝｼﾝﾎﾞﾙ
PD0
PD1
PD2
PD3
PD4
PD5
PD6
PD7
PC6
PC7

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

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

-14A

P07

5

未使用

ＬＥＤ関係
ﾎﾟｰﾄｱﾄﾞﾚｽ0xffff00

ﾎﾟｰﾄｼﾝﾎﾞﾙ

P1DR

ピン番号

ﾋﾟﾝｼﾝﾎﾞﾙ方向

CN1-14A
1-14B
1-15A
1-15B
1-16A
1-16B
1-17A
1-17B

P10
P11
P12
P13
P14
P15
P16
P17

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

信号名
LED1
LED2
LED3
LED4
LED5
LED6
LED7
LED8

ブザー関係（タイマ／ＴＰＵ３ ＴＩＯＣＡ３ アウトプットコンペア出力）
ﾎﾟｰﾄｱﾄﾞﾚｽ0xfffe88

ﾎﾟｰﾄｼﾝﾎﾞﾙ
TGRA_3

ピン番号
CN2-10A

ﾋﾟﾝｼﾝﾎﾞﾙ
PB0/TIOCA3仕様
ＰＷＭモード パルス出力

押しボタンスイッチ関係
ﾎﾟｰﾄｱﾄﾞﾚｽ

ﾎﾟｰﾄｼﾝﾎﾞﾙ

ピン番号

ﾋﾟﾝｼﾝﾎﾞﾙ方向

0xffffb9
0xffffbb

POATA
PORTC

0xffffbe

POATF

CN1-3B
2-7A
2-8B
2-5B

PA0
PC2
PC5
PF7

入力
入力
入力
入力

ピン番号

ﾋﾟﾝｼﾝﾎﾞﾙ方向

CN1-13B
1-13A
1-12B
1-12A
1-11B
1-11A
1-10B
1-10A

P40
P41
P42
P43
P44
P45
P46
P47

入力
入力
入力
入力
入力
入力
入力
入力

信号名
SW12
SW13
SW14
SW15

PB[PA0]PB[PC2]
PB[PC5]PB[PF7]

トグルスイッチ関係
ﾎﾟｰﾄｱﾄﾞﾚｽ0xffffb3

ﾎﾟｰﾄｼﾝﾎﾞﾙ

PORT４

信号名
SW16
SW17
SW18
SW19
SW20
SW21
SW22
SW23

SW[P40]SW[P41]
SW[P42]
SW[P43]
SW[P44]SW[P45]
SW[P46]
SW[P47]

外部ブザー回路図（要製作）
４７Ｋ
CN13-8B(PB0/TIOCA3)

1

2

２．２Ｋ

CN13-2A(GND)

ＢＺ(PKM13EPY-4002-B0)

6

４．とにかく動かしてみましょう！！

１）パソコン＋Ｈ－ｄｅｂｕｇｇｅｒ＋評価ボードの接続を確認して下さい。
２）評価ボードのディップスイッチＳＷ１１－１・２両方をＯＮにする。
３）ＣＡＴ２６１基板上のディップスイッチＳＷ１－１・２・３・４をＯＮにする。
４）評価ボードの電源をオンにする。
５）ＤＥＦを立ち上げる。
６）ＤＥＦの［オプション］－［環境設定］で環境設定をする。
７）ＤＥＦの［オプション］－［ＣＰＵ設定］
ＣＰＵシリーズ名：

Ｈ８Ｓ／２６１２Ｆ－ＺＴＡＴ

水晶発振子クロック： ２０．００００ＭＨｚ
周波数逓倍率：ｘ１に設定してください。
８）ＤＥＦの左下Ｓｔａｒｔをクリックする。
これで、パソコンとＨ－ｄｅｂｕｇｇｅｒとＣＡＴ２６１の通信が可能になり、デバック可能となります。
９）ＤＥＦを使って、ＨＥＸファイルをダウンロードして下さい。

テーマ“メロディ♪♪”のＨＥＸファイルは、¥AHE261_HEW¥S2_Interrupt¥NO3_Demo_Melody_Interrupt¥Cat261i¥Cat261i.mot です。
（ダウンロードの方法は、ＤＥＦのＨＥＬＰを参照）
１０）ダウンロードが終了しましたら、プログラムの実行をして下さい。
（ＤＥＦのショートＰＢのＧＯをクリック）

7これで、ＬＥＤが何やらパラパラ表示をして、ＬＣＤに文字が表示されるはずです。
ＣＡＴ２６１＆ＡＨ６０００ ｂｙ
Ｉｎｔｅｒｒｕｐｔ

０－４－１図 オープニング表示［ＰＡ０］

ここで、簡単に“メロディ♪♪”の操作手順を説明します。

ａ．まず、評価ボードにある押しボタンスイッチ（以後ＰＢと表記します）ＰＡ０を１回押してみてください。
ＰＩＯ動作モード
ＰＩＯ

０－４－２図 ＰＩＯ表示

ＳＷ［Ｐ４７］－＞ＳＷ［Ｐ４０］パラパラ表示していたＬＥＤが消灯します。
トグルスイッチ（以後ＳＷと表記します）Ｐ４７－＞Ｐ４０を上側（ＯＮ）にして見て下さい。
対角線上にＬＥＤが点灯します。
ちょっと寂しい仕様ですが、これがＰＩＯの仕様です。

ｂ．次に、ＰＢ［ＰＡ０］をもう１回押してみて下さい。
Ｔｉｍｅｒ動作モード
Ｔｉｍｅｒ／Ｃｏｕｎｔｅｒ

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

００００Ｈｚ［＋ＰＦ７－ＰＣ５］

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

8

ｃ．再度、ＰＢ［ＰＡ０］をもう一回押してみて下さい。
ＳＣＩ（ＳＩＯ）動作モード
ＳＣＩ

８，ｎ，１［ＰＣ２］０－４－４図 ＳＣＩ表示

０９６００ｂ［＋ＰＦ７－ＰＣ５］

ＳＣＩ（ＲＳ２３２Ｃ）調歩同期式シリアル通信のループテストです。
表示上の“８，ｎ，１”は、８ビット、パリティなし、ストップ１ビットの意味で固定になっています。

“０９６００ｂ”は、転送ボーレートです。
ＰＢ［ＰＦ７］で転送ボーレートを上げることができます。
ＰＢ［ＰＣ５］で転送ボーレートを下げることができます。

評価ボードのＳＷ１１－１・２がＯＮになっていることを確認して下さい。
（ループ接続）ＣＡＴ２６１のＳＷ１－１・２・３・４がＯＮになっていることを確認して下さい。
（ＲＳドライバへの接続）ＰＢ［ＰＣ２］で送信開始／停止をします。
送信データは、“ＩｎｔｅｒｒｕｐｔＳＣ”の文字列を 1 文字ずつ空けて分けて送信しています。

ＳＣＩ０＝“Ｉ ｔ ｒ ｕ ｔ Ｃ”

ＳＣＩ１＝“ ｎ ｅ ｒ ｐ Ｓ ”

受信データは、ＬＣＤの１行目に表示しますので、正常受信していますと重なり合い文字として読み取れるようになっていると思います。

他に、ＳＷ１１－１をＯＦＦにした場合とか、ボーレートを上下させて、色々と操作してみて下さい。

9ｄ．再度、ＰＢ［ＰＡ０］をもう一回押してみて下さい。
テーマのＭｅｌｏｄｙ（メロディ♪♪）です。
Ｍｅｌｏｄｙ０－４－５図 Ｍｅｌｏｄｙ表示

ＰＣ２［Ｍ］Ｆ７［ス］Ｃ５［セ］

ＰＢ［ＰＣ２］でモード変更出来ます。
（ｏｎトグル）ＰＣ２［Ｍ］：手動演奏モード
ＳＷ［Ｐ４０］－＞ＳＷ［Ｐ４７］をｏｎ／ｏｆｆしてみて下さい。
ＰＣ２［Ａ］：自動動演奏モード
３曲登録してあります。
（ネコフンジャッタ、イヌノオマワリサン、アマリリス）
ＰＢ［ＰＣ５］で曲を選択して下さい。
ＰＢ［ＰＦ７］で演奏の開始／停止になっています。

ここまでの説明で、最終目標の“メロディ♪♪”の仕様が理解していただけたでしょうか？
いよいよ、これから基礎から積み上げながら、システム名：“メロディ♪♪”の解説およびソフトウェア開発を進めていきます。

次で説明する第１部ポーリング編は、システム名：“メロディ♪♪”を割込みを一切使用せずに全ポーリン
グ仕様で書いた場合の説明です。
そして第１部が終了しますと、第２部割込み編として割込み処理を取り入れ、よりスムーズなシステムに変更します。
これが、テーマ“メロディ♪♪”になるわけです。

10

第１部 ポーリング編
第１章 スタートアップ

ここの章では、スタートアップ（電源ＯＮ時もしくはリセット時）の説明をします。
Ｈ８Ｓの場合、リセットおよび割り込みベクターは固定になっています。
そのベクターの定義ソースおよびスタートアップ部分のアセンブラーソースの説明をしたいと思います。

まずは、ＤＥＦのダウンロードで￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ１＿ＳｔａｒｔＵｐ￥Ｃａｔ２６１ｐ１￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２６１ｐ１．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
（ＤＥＦ画面左下のＧｏをクリック）

動作としては、なにかＬＥＤがパラパラ表示しているはずです。
このソフトは単純に２０ｍｓ毎にＬＥＤを１ビット左シフトしながら点灯させているだけのソフトです。

それでは、プログラムリストを見てみましょう！

11

２．プログラムリスト
file “StartupA.asm”
1: ;/****************************************************************************/
2: ;/* ＜サンプル＞ ポーリング*/

3: ;/**/

4: ;/*＜MOD＞

StartupA.asm*/

5: ;/*

＜役割＞

main

*/

6: ;/*

＜タブ＞

４タブ編集

7: ;/*(ルネサス純正Ｃ用)*/

スタートアップ (CAT261-H8S/2612)*/

8: ;/****************************************************************************/
9:.global_StartUp,_non10:.global_Wait1ms,_Wait10us

11:
12: ;********************************************************
13: ;* スタック宣言*

14: ;********************************************************
15: STACK.equ

H'0ffefbe; stack init data

16:
17: ;********************************************************
18: ;* マクロ宣言

Normal = .word Advanced = .long

19: ;********************************************************
20: VECTOR:.define".DATA.L"

21:
22: ;********************************************************
23: ;* Ｉ／Ｏ宣言
24: ;********************************************************
25: SYSCR.EQU

H'0fffde5; ｼｽﾃﾑｺﾝﾄﾛｰﾙ

26: P1DDR.EQU

H'0FFFE30; Moniter Port DIR

27: P1DR.EQU

H'0FFFF00; Moniter Port Out

28:
29: ;********************************************************
30: ;* ベクターテーブル
31: ;********************************************************
32:.section

33: _VectorTable:

VECT,CODE,LOCATE=0;12(共通/213x)(26xx)

34:

VECTOR_StartUp;* VCT( 0) RESET

35:

VECTOR_non;* VCT( 1) System 予約 1|

36:

VECTOR_non;* VCT( 2)

2|

37:

VECTOR_non;* VCT( 3)

3|

38:

VECTOR_non;* VCT( 4)

4|

39:

VECTOR_non;* VCT( 5)

5|

40:

VECTOR_non;* VCT( 6) 直接推移|

41:

VECTOR_non;* VCT( 7) NMI|

42:

VECTOR_non;* VCT( 8) TRAP0|43:

VECTOR_non;* VCT( 9) TRAP1|

44:

VECTOR_non;* VCT( 10) TRAP2|

45:

VECTOR_non;* VCT( 11) TRAP3|

46:

VECTOR_non;* VCT( 12) System 予約 1|

47:

VECTOR_non;* VCT( 13)

2|

48:

VECTOR_non;* VCT( 14)

3|

49:

VECTOR_non;* VCT( 15)

4|

50:

VECTOR_non;* VCT( 16) IRQ0|51:

VECTOR_non;* VCT( 17) IRQ1|

52:

VECTOR_non;* VCT( 18) IRQ2|

53:

VECTOR_non;* VCT( 19) IRQ3|

54:

VECTOR_non;* VCT( 20) IRQ4|55:

VECTOR_non;* VCT( 21) IRQ5|56:

VECTOR_non;* VCT( 22) IRQ6|57:

VECTOR_non;* VCT( 23) IRQ7|58:

VECTOR_non;* VCT( 24) DTC

END

59:

VECTOR_non;* VCT( 25) WDG

WOVI0 |

60:

VECTOR_non;* VCT( 26) WOVI1|

61:

VECTOR_non;* VCT( 27) PCB|

62:

VECTOR_non;* VCT( 28) A/D

63:

VECTOR_non;* VCT( 29) ﾘｻﾞｰﾌﾞ|

64:

VECTOR_non;* VCT( 30) ﾘｻﾞｰﾌﾞ|

65:

VECTOR_non;* VCT( 31) ﾘｻﾞｰﾌﾞ|

66:

VECTOR_non;* VCT( 32) ﾘｻﾞｰﾌﾞ|TPU_0 TGIA_0

67:

VECTOR_non;* VCT( 33) ﾘｻﾞｰﾌﾞ|

TGIB_068:

VECTOR_non;* VCT( 34) ﾘｻﾞｰﾌﾞ|

TGIC_069:

VECTOR_non;* VCT( 35) ﾘｻﾞｰﾌﾞ|

TGID_0

13

|

ADI

|

|

70:

VECTOR_non;* VCT( 36) ﾘｻﾞｰﾌﾞ|

71:

VECTOR_non;* VCT( 37) ﾘｻﾞｰﾌﾞ|

72:

VECTOR_non;* VCT( 38) ﾘｻﾞｰﾌﾞ|

73:

VECTOR_non;* VCT( 39) ﾘｻﾞｰﾌﾞ|

74:

VECTOR_non;* VCT( 40) ﾘｻﾞｰﾌﾞ|TPU_1 TGIA_1

75:

VECTOR_non;* VCT( 41) ﾘｻﾞｰﾌﾞ|

TGIB_1

76:

VECTOR_non;* VCT( 42) ﾘｻﾞｰﾌﾞ|

TGIV_1

77:

VECTOR_non;* VCT( 43) ﾘｻﾞｰﾌﾞ|TGIU_1

78:

VECTOR_non;* VCT( 44) ﾘｻﾞｰﾌﾞ|TPU_2 TGIA_2

79:

VECTOR_non;* VCT( 45) ﾘｻﾞｰﾌﾞ|

TGIB_280:

VECTOR_non;* VCT( 46) ﾘｻﾞｰﾌﾞ|

TGIV_2

81:

VECTOR_non;* VCT( 47) ﾘｻﾞｰﾌﾞ|TGIU_2

82:

VECTOR_non;* VCT( 48) FRTICIA |TPU_3 TGIA_3

83:

VECTOR_non;* VCT( 49)

ICIB |

TGIB_384:

VECTOR_non;* VCT( 50)

ICIC |

TGIC_3

85:

VECTOR_non;* VCT( 51)

ICID |

TGID_3

86:

VECTOR_non;* VCT( 52)

OCIA |

TCIV_087:

VECTOR_non;* VCT( 53)

OCIB |

88:

VECTOR_non;* VCT( 54)

FOVI |

89:

VECTOR_non;* VCT( 55) ﾘｻﾞｰﾌﾞ|

90:

VECTOR_non;* VCT( 56) ﾘｻﾞｰﾌﾞ|TPU_4 TGIA_4

91:

VECTOR_non;* VCT( 57) ﾘｻﾞｰﾌﾞ|

TGIB_492:

VECTOR_non;* VCT( 58) ﾘｻﾞｰﾌﾞ|

TGIV_493:

VECTOR_non;* VCT( 59) ﾘｻﾞｰﾌﾞ|TGIU_4

94:

VECTOR_non;* VCT( 60) ﾘｻﾞｰﾌﾞ|TPU_5 TGIA_5

95:

VECTOR_non;* VCT( 61) ﾘｻﾞｰﾌﾞ|

TGIB_596:

VECTOR_non;* VCT( 62) ﾘｻﾞｰﾌﾞ|

TGIV_597:

VECTOR_non;* VCT( 63) ﾘｻﾞｰﾌﾞ|TGIU_598:

VECTOR_non;* VCT( 64) TMR0 CMIA0 |99:

VECTOR_non;* VCT( 65)

CMIB0 |

100:

VECTOR_non;* VCT( 66)

OVI0 |

101:

VECTOR_non;* VCT( 67) ﾘｻﾞｰﾌﾞ

102:

VECTOR_non;* VCT( 68) TMR1 CMIA1 |103:

VECTOR_non;* VCT( 69)

CMIB1 |

104:

VECTOR_non;* VCT( 70)

OVI1 |

105:

VECTOR_non;* VCT( 71) ﾘｻﾞｰﾌﾞ

14

|

|

TCIV_0

106:

VECTOR_non;* VCT( 72) TMRXY CMIAY |107:

VECTOR_non;* VCT( 73)

CMIBY |

108:

VECTOR_non;* VCT( 74)OVIY |

109:

VECTOR_non;* VCT( 75)

ICIX |

110:

VECTOR_non;* VCT( 76)IBF1 |

111:

VECTOR_non;* VCT( 77)IBF2 |

112:

VECTOR_non;* VCT( 78) ﾘｻﾞｰﾌﾞ

|

113:

VECTOR_non;* VCT( 79) ﾘｻﾞｰﾌﾞ

|

114:

VECTOR_non;* VCT( 80) SCI0 ERI0 |115:

VECTOR_non;* VCT( 81)

RXI0 |

116:

VECTOR_non;* VCT( 82)

TXI0 |

117:

VECTOR_non;* VCT( 83)

TEI0 |

118:

VECTOR_non;* VCT( 84) SCI1 ERI1 |119:

VECTOR_non;* VCT( 85)

RXI1 |

120:

VECTOR_non;* VCT( 86)

TXI1 |

121:

VECTOR_non;* VCT( 87)

TEI1 |

122:

VECTOR_non;* VCT( 88) SCI2 ERI2 |123:

VECTOR_non;* VCT( 89)

RXI2 |

124:

VECTOR_non;* VCT( 90)

TXI2 |

125:

VECTOR_non;* VCT( 91)

TEI2 |

126:

VECTOR_non;* VCT( 92) IIC0 IICI0 |TMR2 CMIA2

127:

VECTOR_non;* VCT( 93)

DDCSW1|

CMIB2

128:

VECTOR_non;* VCT( 94) IIC1 IICI1 |

OVI2

129:

VECTOR_non;* VCT( 95) ﾘｻﾞｰﾌﾞ

|

130:

VECTOR_non;* VCT( 96) ﾘｻﾞｰﾌﾞ|TMR3 CMIA3131:

VECTOR_non;* VCT( 97) ﾘｻﾞｰﾌﾞ

|

CMIB3

132:

VECTOR_non;* VCT( 98) ﾘｻﾞｰﾌﾞ

|

OVI3

133:

VECTOR_non;* VCT( 99) ﾘｻﾞｰﾌﾞ

|

134:

VECTOR_non;* VCT(100) ﾘｻﾞｰﾌﾞ|IIC0 IICI0135:

VECTOR_non;* VCT(101) ﾘｻﾞｰﾌﾞ

|

136:

VECTOR_non;* VCT(102) ﾘｻﾞｰﾌﾞ|IIC1 IICI1

137:

VECTOR_non;* VCT(103) ﾘｻﾞｰﾌﾞ

|

138:

VECTOR_non;* VCT(104) ﾘｻﾞｰﾌﾞ|HCAN ERS0,OVR0139:

VECTOR_non;* VCT(105) ﾘｻﾞｰﾌﾞ

|

RM0

140:

VECTOR_non;* VCT(106) ﾘｻﾞｰﾌﾞ

|

RM1

141:

VECTOR_non;* VCT(107) ﾘｻﾞｰﾌﾞ

|

SLE0

15

DDCSW1

142:

VECTOR_non;* VCT(108) ﾘｻﾞｰﾌﾞ

|MMT

TGIMN

143:

VECTOR_non;* VCT(109) ﾘｻﾞｰﾌﾞ

|

TGINN

144:

VECTOR_non;* VCT(110) ﾘｻﾞｰﾌﾞ

|

POEIN

145:

VECTOR_non;* VCT(111) ﾘｻﾞｰﾌﾞ

|

146:

VECTOR_non;* VCT(112) ﾘｻﾞｰﾌﾞ

|

147:

VECTOR_non;* VCT(113) ﾘｻﾞｰﾌﾞ

|

148:

VECTOR_non;* VCT(114) ﾘｻﾞｰﾌﾞ

|

149:

VECTOR_non;* VCT(115) ﾘｻﾞｰﾌﾞ

|

150:

VECTOR_non;* VCT(116) ﾘｻﾞｰﾌﾞ

|

151:

VECTOR_non;* VCT(117) ﾘｻﾞｰﾌﾞ

|

152:

VECTOR_non;* VCT(118) ﾘｻﾞｰﾌﾞ

|

153:

VECTOR_non;* VCT(119) ﾘｻﾞｰﾌﾞ

|

154:

VECTOR_non;* VCT(120) ﾘｻﾞｰﾌﾞ|SCI_3 ERI2

155:

VECTOR_non;* VCT(121) ﾘｻﾞｰﾌﾞ

|

RXI2

156:

VECTOR_non;* VCT(122) ﾘｻﾞｰﾌﾞ

|

TXI2

157:

VECTOR_non;* VCT(123) ﾘｻﾞｰﾌﾞ

|

TEI2

158:

VECTOR_non;* VCT(124) ﾘｻﾞｰﾌﾞ|SCI_3 ERI2

159:

VECTOR_non;* VCT(125) ﾘｻﾞｰﾌﾞ

|

RXI2

160:

VECTOR_non;* VCT(126) ﾘｻﾞｰﾌﾞ

|

TXI2

161:

VECTOR_non;* VCT(127) ﾘｻﾞｰﾌﾞ

|

TEI2

162:
163: ;/****************************************************************************/
164: ;/*

スタートアップ*/

165: ;/****************************************************************************/
166:.SECTION

P,CODE

168:

mov.l

#STACK,sp;* ｽﾀｯｸﾎﾟｲﾝﾀ 設定

*/

169:

ldc.b

#H'6,exr;* disable() PBC 割込の為

*/

170:

jmp

@_main;* Main167: _StartUp:

171:
172: _non:173:;* 未使用割り込み

*/

rte

174: ;/****************************************************************************/
175: ;/*

メイン*/

176: ;/****************************************************************************/
177: _main:

16

178:

bset

#5,@SYSCR;* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

179:

bclr

#4,@SYSCR

;*

*/

180:

bclr

#3,@SYSCR;*NMI 立下りエッジ

*/

181:

bset

#1,@SYSCR;*RAME 有効

*/

183:

mov.b

#H'0ff,r0l;* MoniterPort All Out

*/

184:

mov.b

r0l,@P1DDR

;*

"

*/

185:

mov.b

#1,r1l;* LED

表示パターン

*/

187:

mov.b

r1l,r0l;* LED

点灯

*/

188:

not.b

r0l

;*

0=点灯のため

*/

189:

mov.b

r0l,@P1DR;*

出力（LED 点灯）

*/

190:

mov.b

#20,r0l;* 20msWait

192:

bsr

_Wait1ms

193:

dec.b

r0l

194:

bne

wait20ms

195:

rotl.b

r1l

196:

bra

loop

"

182:

186: loop:*/

191: wait20ms:;* LED<< 1*/

197: ;/****************************************************************************/
198: ;/*

Wait1ms()1ms ｿﾌﾄﾀｲﾏｰ (20.0000MHz) Non Wait*/

199: ;/****************************************************************************/
200: _Wait1ms:
201:

push.w r0

;

202:

mov.w

;/* 5000*4=20000cyc */#5000,r0

203: wait:

;

204:

dec.w

#1,r0

;/* 1 clock

*/

205:

bne

wait:16;/* 3 clock

*/

206:

pop.w

r0

;

207:

rts

208: ;/****************************************************************************/
209: ;/*

Wait10us()

10us ｿﾌﾄﾀｲﾏｰ (20.000MHz) Non Wait*/

210: ;/****************************************************************************/
211: _Wait10us:212:

push.w

r0

;

213:

mov.w

#50,r0;/* 50*4=200cyc

17*/214: wait1:

;

215:

dec.w

#1,r0

;/* 1 clock

*/

216:

bne

wait1:16;/* 3 clock

*/

217:

pop.w

r0

;

218:

rts

219:

.end

18

［リストの説明］
１～８行：
コメントです。
９～１０行：
グローバルシンボル宣言です。
この宣言により外部参照が可能になります。
１５行：
スタックポインタ（ＳＰ）の初期値設定値のマクロ宣言です。
ＳＰ動作は必ず－２して動作するため、この設定値ですと０ｘｆｆｅｆｂｅと０ｘｆｆｅｆｂｆ番地は使用しないことになります。
フルにＲＡＭを使用したい場合は、０ｘｆｆｅｆｃ０になるわけですが、この番地にはＲＡＭが存在していませんので、直感的でない数字のためこの方法は使用しないようにしています。
たんなる個人的なルールです。
２０行：
ベクターテーブルに置くアドレス値を、ノーマルモードは２バイト“．ＤＡＴＡ．Ｗ”でアドバンスド
は４バイト“．ＤＡＴＡ．Ｌ”になりますので、ここのマクロを変更することによりアドレス長を変えられるよう工夫がしてあります。
２５～２７行：
使用するＩ／Ｏレジスタアドレスをシンボル化している宣言です。
３２行：
ベクターテーブルを０番地にロケートするために、セクション宣言およびアブソリュート番地指定をしています。
３３～１６１行：
ベクターテーブルです。今回は３４行目のリセットベクターのみにアドレスを置いています。
１６６行：
この位置よりプログラムセクションであることを明示するための擬似命令です。
“Ｐ”は一般的ですので、このセクション名を使うことをお勧めします。
セクション名を変える目的は、モニターエリア０ｘ２００～０ｘ７ｆｆ番地を確保するためです。
リンク時に、ＶＥＣＴ＝０、Ｐ＝０ｘ８００と指定するだけでエリアの確保になります。
なお、Ｃ言語で記述した場合も、このセクション名になります。
１６７行：
電源ＯＮ時およびリセット時にプログラムはココから実行を始めるようにベクターテーブルに設定してあります。
１６８行：
電源ＯＮ時およびリセット時にまず実行させる命令は、このスタックポインタの設定です。
定石ですので必ず守って下さい。

19

なお、理由はＣＰＵハードウェアマニュアルに記載されています。
１６９行：
Ｈ８Ｓ／２６１２のＰＣブレーク例外処理の割り込みプライオリティが“７”になっていますので、ＰＣブレーク例外処理を有効にさせるために、この命令を置いています。
他の割り込み例外処理のプライオリティを“６”以下にする必要があります。
１７０行：
メインプログラムへのジャンプエントリです。
１７２～１７３行：
未使用割り込みのベクター値を置くためのプログラムです。
実際には、このプログラムが実行されることは通常状態である限りありえません。
ここまでがポーリングで済む場合の、世でいう“スタートアップ”になるわけです。
どうです簡単でしょう！！
１７７～１９６行：
このサンプルソフトが動作しているかを目で確かめるために用意したソフトです。
ＬＥＤ点灯部分等は、後章ＰＩＯ編で説明しますので、ここでは省略します。
２００～２０７行：
約１ｍｅｃのソフトタイマです。
ＣＰＵクロック＝２０００００００Ｈｚですので、１０００Ｈｚ（１ｍｓ）で割りますとマシンサイク
ル＝２００００サイクルになります。
１ループ４サイクルですので、２００００÷４＝５０００ループになります。
２１１～２１８行：
約１０ｕｓｅｃのソフトタイマです。
ＣＰＵクロック＝２０００００００Ｈｚですので、１０００００Ｈｚ（１０ｕｓ）で割りますとマシン
サイクル＝２００サイクルになります。
１ループ４サイクルですので、２００÷４＝５０ループになります。
２１９行：
アセンブラファイルの最後には、この擬似命令“．ｅｎｄ”を置いて下さい。

20

３．統合環境ＨＥＷの利用
エディタ・コンパイル・アセンブリ・リンケージエディタを管理／制御する保守ツールは、統合環境Ｈ
ＥＷを使いました。
“Ｂｕｉｌｄ”することにより、自動で修正したソースだけを探して、コンパイル・アセンブリ・リンク
を実行してくれる便利なツールです。
簡単ではありますが、ＨＥＷの使用例を説明します。

１）配布ＣＤに収めてある“￥ＡＨＥ２６１＿ＨＥＷ”をフォルダごとＨＤにコピーして下さい。
２）ＨＥＷを起動します。

３）上図のように“Ｂｒｏｗｓｅ ｔｏ ａｎｏｔｈｅｒ ｐｒｏｊｅｃｔ ｗｏｒｋｓｐａｃｅ”にチェックし、ＯＫをクリックします。

４）先ほどＣＤよりコピーしたディレクトリ“ＡＨＥ２６１＿ＨＥＷ”を選択をし、“ＡＨＥ２６１＿Ｈ
ＥＷ．ｈｗｓ”を開きます。

21５）原本の管理ディレクトリと今回コピーした管理ディレクトリが違うため“ＨＥＷ”が自動修正し、続けますか？のメッセージです。はい（Ｙ）をクリックします。

６）無事にワークスペースが開いたはずです。次にこの章のプロジェクト名“Ｃａｔ２６１ｐ１”を指定します。

７）［Ｐｒｏｊｅｃｔ］－［Ｓｅｔ Ｃｕｒｒｅｎｔ Ｐｒｏｊｅｃｔ］－［Ｃａｔ２６１ｐ１］をクリッ
クしますと、プロジェクトの変更になります。

22８）この図のように、画面左側で“Ｃａｔ２６１ｐ１”―“Ｐｒｏｊｅｃｔ Ｆｉｌｅｓ”―“ＳｔａｒｔｕｐＡ．ａｓｍ”を探してクリックをします。
そうしますと、画面右側にソースファイルの内容が表示されます。ここがエディタ（編集）画面になります。

９）一度、統合環境“ＨＥＷ”の便利さを実感してみたいと思いますが、その前にシンボルコンバータ“Ｈ
Ｃｓｙｍｃｏｎｖ．ＥＸＥ”が、［Ｏｐｔｉｏｎｓ］－［ＳｙｍｂｏｌＣｏｎｖｅｒｔ］をクリックしてみた場所に存在しているか確認をしてみて下さい。
ＤＥＦ．ｅｘｅ（Ｈ－ｄｅｂｕｇｇｅｒコントロールソフト）のインストール場所がデフォルトの場合は問題ありませんが、変更している場合は変更が必要になります。

23

４．統合環境ＨＥＷを使ってみる
統合環境“ＨＥＷ”の便利さを実感してみたいと思います。

１）このサンプルのＬＥＤを２０ｍｓ毎にシフト表示しているのを１００ｍｓ毎に変更してみます。
“ＳｔａｒｔｕｐＡ．ａｓｍ”をエディタで
189:

mov.b

r0l,@P1DR

;*

190:

mov.b

#20,r0l;* 20msWait

出力（LED 点灯）*/*/

191: wait20ms:
１９０行目の“２０”を“１００”に変更してみてください。
190:

mov.b

#100,r0l;* 100msWait*/

２）［Ｂｕｉｌｄ］－［Ｂｕｉｌｄ］をクリックします。
３）評価ボードに“Ｃａｔ２０４ｐ１．ｍｏｔ”ダウンロードして、実行してみて下さい。
どうです！！ＬＥＤのシフト表示スピードが遅くなりましたので、目で確認できるようになったはずです。

プログラムデバック作業は、簡単に言えばこの繰り返しです。
思ったように動かない場合は、デバッガでブレークをあてたり、メモリの内容を見たり、レジスタの内容を見たりして、間違いを探し、見つかったらソースを修正し“Ｂｕｉｌｄ”を実行して“＊．ｍｏｔ”ファイルを作成し、ターゲットにダウンロードして、実行させ、再び確認する。
気の遠くなるような作業を何度も何度も繰り返し、仕様どうりのプログラムを完成させるわけです。
簡単ではありますが、プログラム開発の流れはだいたい掴んで頂けたかと思います。
第１章は、ここまでとし、次へのステップとして、Ｃ言語でのプログラム開発方法へと進めていきたいと
思います。
24

第２章 ルネサス純正Ｃ言語によるスタートアップ

ここの章では、第１章の仕様そのままにして、メインプログラムをＣ言語でプログラムした場合どのような仕組みでＨＥＸファイルが作られるのかを解説します。

まずは、ＤＥＦのダウンロードで￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ２＿ＨＣ＿ＳｔａｒｔＵｐ￥Ｃａｔ２６１ｐ２にディレクトリの移動をしておいて下さい。

１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２６１ｐ２．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。
前章とまったく同じ動作のはずです。
それでは、プログラムリストを見てみましょう！

25

２．プログラムリスト

今後の移植性および役割分割のため、ソースを３ファイルに分割しました。
１）“Ｓｔａｒｔｕｐ．ａｓｍ”ベクターテーブルの定義とスタートアップです。前章よりメイン部分を抜きました。
［説明は省略します］
２）“Ｃａｔ２６１ｐ２．ｃ”メイン処理は、この章のメインコントロール部です。章が上がっていきま
すとこれをベースに追加していきます。
３）“ＰｏｌＰｉｏ２．ｃ”ＬＥＤ表示は、このサンプルソフトが動作しているかを目で確かめるために用意したソフトです。
ＬＥＤ点灯部分等は、後の章ＰＩＯ編で説明しますので、ここでの説明は省略します。

Ｃ言語の多モジュル化した場合に、定義文等を他のモジュールでも利用できるようにヘッダーファイルを
２ファイル作成しました。
１）“ｉｏ２６１ｘ．ｈ”は、ＣＡＴ２６１（超小型マイコン）が使用しているＣＰＵ（Ｈ８Ｓ／２６１２）の内部Ｉ／Ｏをシンボル定義および、マクロ命令をまとめたファイルです。
２）“ＤｅｍｏＣｔｌ．ｈ”は、サンプルプログラムを見やすくするためのシンボル定義集とモジュール
別に出来上がった関数のプロトタイプ宣言をまとめたファイルです。
章が上がることに、これをベースに追加していきます。

なお、［リストの説明］で前章と説明がダブル個所は省略します。

26*１）メイン処理（プログラム）
file “Cat261p2.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p2.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

変数宣言*/

16: /****************************************************************************/
17:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/18: /****************************************************************************/
19: /*

main()*/

20: /****************************************************************************/
21: void_main(void)

22: {
23:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

24:

/*

NMI 立下りエッジ

*/

25:

/*

RAME 有効*/26:

SYSCR = 0x21;

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

27:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

28:/* の 1 回リトライ時間分待つ(20 回)

*/

29:

MemInitial();/* ﾒﾓﾘ系初期化

*/

30:

IoInitial();/* I/O 系初期化

*/

31:

while(1) {32:

SoftWait1ms(20);/* 20msWait

*/

33:

RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

*/

27

34:
35:

SigOutput();/* Signal Output Process(LED 点灯)

*/

}

36: }
37: /****************************************************************************/
38: /*

Ｍｅｍ初期化*/

39: /****************************************************************************/
40: void

MemInitial(void)

41: {
42:

Shift = 0;/* Led Disp Patan Initial

*/

43:

PioMemInitial();/* PIO*/Mem 初期化

44: }
45: /****************************************************************************/
46: /*

Ｉ／Ｏ初期化*/

47: /****************************************************************************/
48: void

IoInitial(void)

49: {
50:

PioIoInitial();/* PIOI/O 初期化*/

51: }
52: /****************************************************************************/
53: /*

RunRun()

CPU 走行表示*/

54: /****************************************************************************/
55: void

RunRun()

56: {
57:

if ((Shift <<= 1) == 0) Shift = 1;

58:

PutOutPort(Shift,'=');/* LED Shift 表示

*/

59: }
60: /****************************************************************************/
61: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

62: /****************************************************************************/
63: void

SoftWait1ms(Ushort ms)

64: {
65:

while(ms-- != 0) {66:

Wait1ms();

67:

}

68: }

28

［リストの説明］
１～１１行：
コメントです。
１２～１３行：
後で説明しますが、このテーマで使用する定義文をまとめたヘッダーファイルを使用することをコンパイラに教えるステートメントです。
１７行：
内部使用する変数の宣言文です。
“Uchar”は、“io261x.h”でキーワード宣言してあるため、“unsigned char”と同じ意味を持ちます。
長い文章を入力したく無い場合よく使います。
（キー入力が苦手な日本人特有かも？）
変数名“Shift”の用途は、ＬＥＤ表示バッファーとして使用します。
２１行：“_main()”関数の先頭を意味する宣言文です。
前に説明した“スタートアップ”から、ここにジャンプして来ます。
標準の“main()”宣言を使用しても構いませんが、ＧＮＵ版の実践解説テキストと合わせる為、アンダーバー“＿”を付けて違う名前にしました。
２３行：
Ｈ－ｄｅｂｕｇｇｅｒを使用する場合、システムコントローラに対する設定をこのように指示して下さい。
（定石）
なお、ＣＰＵタイプにより設定内容が違います。
Ｈ８／３６６４の場合
１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）Ｈ８Ｓ／２１３２・２１３４・２１３８の場合
１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）Ｈ８Ｓ／２２３８・２２３８・２６３３の場合
１）割り込みモードを“２”にする。
（モード“０”でも良い）
２）ＮＭＩを立下りエッジにする。
（デフォルト）３）内部ＲＡＭ有効にする。
（デフォルト）ＳＨ／７０４５・７０５０・７０５１の場合
１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）２６行：
Ｈ－ｄｅｂｕｇｇｅｒを使用する場合、この４００ｍｓソフトタイマを入れておいて下さい。
理由は、リセット＋Ｍｏｎコマンド発行時にＨ－ｄｅｂｕｇｇｅｒは、リセット出力後２００ｍｓ後に29

２０ｍｓ毎にターゲットにモニタが存在しているか調査しにいきます。
（リトライ２０回）
この時にモニタが存在した場合、その時点でＰＣ値を０ｘ８００に戻しプログラム停止状態にします。
２００ｍｓタイマーがない場合は、この例ですとＩ／Ｏおよびメモリの初期化が進み、ユーザープログ
ラムが最大２００ｍｓ走行後にプログラム停止状態になってからＰＣ値が０ｘ８００になります。
この動作が嫌な人は、ソフトタイマを付けてください。

ただし、ＤＥＦバージョン５．７０Ａよりリセット遅延防止タイマ未使用の指定ができますので、未使用に指定した場合は「２０ｕｓ以上」のソフトタイマ値になります。
２９行：
このテーマで使用する変数の初期化をまとめた関数です。
章が上がっていく度に追加されていきます。
電源ＯＮ時に使用ＲＡＭエリアをオールゼロにする関数をアセンブラで組む方法もありますが、今回は使用する変数一個一個を初期化する方法にしています。
３０行：
このテーマで使用するＩ／Ｏの初期化をまとめた関数です。
３１行：
電源ＯＦＦするまで無限ループをする先頭を意味するステートメントです。
“while(1) {---------}”までが無限ループ内になります。
３２行：
２０ｍｓ毎にＬＥＤをシフト表示させるための２０ｍｓのソフトタイマーです。
この関数を抜けて来るまで他の処理は一切しません。
（もったいないことです）
３３行：
呼ばれる毎に変数“Shift”を１ビット左シフトし、ＬＥＤ表示のため、ｏｕｔバッファーにセットする関数を呼んでいます。
３４行：ｏｕｔバッファーをポート出力する関数を呼んでいます。
３５行：
前に説明した“while(1)”の終わりを示す記号です。
３６行：“main()”関数の終わりを示す記号です。
この２１行目から始まり、３６行目で終わる集まりを“関数”または“サブルーチン”と呼んでいます。
Ｃ言語で記述した場合は、この関数の集合体でプロジェクトを完成させています。
４０～４４行：
メモリ初期化の関数です。
４８～５１行：
Ｉ／Ｏ初期化の関数です。

30

５５～５９行：
動作表示モニタ用バッファを１ビット左シフトして、出力バッファにセットしています。
６３～６８行：
ｍｓｅｃ単位で指定するソフトタイマ関数です。

31*３）ＰＩＯ関係（プログラム）
file “PolPio2.c” LED 表示（動作目視用）
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolPio2.c*/

6: /* ＜役割＞

PIO 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

変数宣言*/

16: /****************************************************************************/
17:

Uchar

OutPort;/* Out Port Buffer*/

18: /****************************************************************************/
19: /*

Ｍｅｍ初期化*/

20: /****************************************************************************/
21: void

PioMemInitial(void)

22: {
23:

OutPort = 0;/* OUT Port 初期化

*/

24: }
25: /****************************************************************************/
26: /*

Ｉ／Ｏ初期化*/

27: /****************************************************************************/
28: void

PioIoInitial(void)

29: {
30:

P1DDR = 0xff;/* PIOB P0 全出力

*/

31: }
32: /****************************************************************************/
33: /*

SigOutput

Signal Output Process(LED 出力)*/

34: /****************************************************************************/

32

35: void

SigOutput()

36: {
37:

P1DR = ~OutPort;/* 0=点灯 1=消灯 のため

*/

38: }
39: /****************************************************************************/
40: /*

OutPortPut 出力バッファーにセット*/

41: /****************************************************************************/
42: void

PutOutPort(Uchar patan,Uchar log)

43: {
44:

if (log == '=')

OutPort = patan;45:

else if (log == '|') OutPort |= patan;

46:

else if (log == '&') OutPort &= patan;

47: }［リストの説明］ＰＩＯについては後章で説明しますので、ここでは省略します。

33*１）ヘッダーファイル（１）file “io261x.h”
1: //**************************************************************************
2: //
3: //

CPU

= H8S/2612

4: //MOD NAME = IO261x.H

5: //PROCESS= Ｉ／Ｏアドレス定義

6: //

EDIT

= ４タブ編集

7: //
8: //

Ver 1.00 2002-01-XX M.Hasegawa

9: //
10: //**************************************************************************
11: typedef unsigned char Uchar;
12: typedef unsigned short Ushort;
13: typedef unsigned long Ulong;
14: //**********************************************************
15: //

インライン関数

16: //Disable = Int Mask Level 6

17: //

Enable = Int Mask Level 0

18: //**********************************************************
19: #define disable()(set_imask_exr(6))

20: #define enable()(set_imask_exr(0))

21: //**********************************************************
22: //

内部I/O

23: //**********************************************************
24: #define MCR(*(volatile char *)0x0FFF800)

25: #define GSR(*(volatile char *)0x0FFF801)――――――――― 途中省略 ―――――――――

538: #define PORTA(*(volatile char *)0x0FFFFB9)

539: #define PORTB(*(volatile char *)0x0FFFFBA)

540: #define PORTC(*(volatile char *)0x0FFFFBB)

541: #define PORTD(*(volatile char *)0x0FFFFBC)

542: #define PORTF(*(volatile char *)0x0FFFFBE)

34// HCAN［リストの説明］
１１～１３行：“unsigned”長い予約語のため、このように予約語をキーワード宣言して使用しています。
使用したくないかたは、使用しなくてもかまいません。
ただし、サンプルソースは全部修正が必要になります。
１９行：
割り込み禁止のマクロ定義です。
（ルネサス純正Ｃのライブラリを使用しました）
Ｈ－ｄｅｂｕｇｇｅｒを使用した場合の割り込みディセーブルマスク値です。
モニタを外した場合でも、このままで問題無いはずですが、気になる方は、マスク値を“７”にして下さい。
２０行：
割り込み許可のマクロ定義です。
（ルネサス純正Ｃのライブラリを使用しました）
Ｈ－ｄｅｂｕｇｇｅｒを使用した場合の割り込みイネーブルマスク値です。
マスクレベルを変更されたいユーザーは、自由に変更して下さい。
２４～５４２行：
Ｈ８Ｓ／２６１２の内部Ｉ／Ｏレジスタをシンボル化しました。
ほとんどマニュアル記載どうりの名前にしましたが、重複部分は変更してありますので確認後、ご利用
下さい。

35

*３）ヘッダーファイル（２）file “DemoCtl.h”
1: /****************************************************************************/
2: /*

*/

3: /* ＜役割＞

サンプルソフト特有の宣言*/

4: /* ＜TAB＞

４タブ編集

*/

5: /*

*/

6: /****************************************************************************/
7: /****************************************************************************/
8: /*

マクロ

*/

9: /****************************************************************************/
10: #define ON

0xaa/* ﾌﾗｸﾞ内部 ON ﾌﾗｸﾞ*/

11: #define OFF

0

/*

"

*/

OFF

12: /****************************************************************************/
13: /*

プロトタイプ宣言*/

14: /****************************************************************************/
15: /*

Cat204p.c*/

16: void

MemInitial(void);

17: void

IoInitial(void);

18: void

RunRun();

19: void

SoftWait1ms(Ushort ms);

20: void

Wait1ms();

21: /*

PolPio.c

22: void

PioMemInitial();

23: void

PioIoInitial();

24: void

SigOutput();

25: void

PutOutPort(Uchar patan,Uchar log);*/36

［リストの説明］
１０～１１行：
内部で使用するフラグ数値をシンボル化しました。
直接数字を記述しますと、数字の意味が不明になるため、シンボル化しておくと便利です。
１５～２１行：
各モジュールで作成した関数をまとめてプロトタイプ宣言をしておきます。
プロトタイプ宣言をしておきますと、関数型および引数の型をコンパイラがチェックしてくれますので、是非宣言して下さい。

なお、これから章が上がるたびに関数が増えていきますので、当然プロトファイル宣言も比例して増えていき、このヘッダーファイルの内容も追加されていきますが、わざわざファイル名を変えて説明する必要も無いと思いますので、説明はこの章だけとさせてもらいます。

３．統合環境ＨＥＷを使ってみる
１）前章と同じように、２０ｍｓ毎にシフト表示しているのを、１００ｍｓ毎に変更してみましょう“Ｃａｔ２６１ｐ２．ｃ”をエディタで開き
31:

while(1) {32:

SoftWait1ms(20);/* 20msWait

*/

33:

RunRun();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/

３２行目の“２０”を“１００”に変更してみてください。
32:

SoftWait1ms(100);/* 100msWait*/

２）［Ｂｕｉｌｄ］－［Ｂｕｉｌｄ］をクリックします。
３）評価ボードに“Ｃａｔ２０４ｐ２．ｍｏｔ”ダウンロードして、実行してみて下さい。
どうです！！ＬＥＤのシフト表示スピードが遅くなりましたので、目で確認できるようになったはずです。

ここまで来ますと、Ｃ言語で開発する土台が出来あがりました。
次章は、評価ボードに付いている、トグルスイッチと押しボタンスイッチを使えるようにすることと、いままで使用していたＬＥＤ表示についての解説をします。

37

第３章 ＰＩＯ

ここの章では、ＰＩＯイニシャルとＰＩＯ使用サンプルの解説を主におきたいと思います。
ＰＩＯの応用例として、入力（８点のトグルスイッチ、４点の押しボタンスイッチ）と出力（８点のＬＥ
Ｄ）と（ＬＣＤ表示－第４章で説明します）です。

まずは、ＤＥＦのダウンロードで￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ３＿ＰＩＯ￥Ｃａｔ２６１ｐ３￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

後の説明進行のため、評価ボード下のトグルスイッチ（８点）を全部を下（オフ）にしておいて下さい。

移動したディレクトリの中に、“Ｃａｔ２６１ｐ３．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。

最初は、いままで通りの動作ですが、チョット仕様追加してあります。
評価ボードの右下の押しボタン（以後ＰＢと称します）ＰＡ０を押してみて下さい。
どうです？ＬＥＤ表示が消えたはずです。

ここで、評価ボード下のトグルスイッチ（以後ＳＷと称します）Ｐ４０を上（オン）にしてみて下さい。
どうです？ＬＥＤ［Ｐ１７］が点灯したはずです。

つまり、ＳＷをオンすると対角線上のＬＥＤを点灯させる仕様になっています。
とりあえず、全ＳＷをオン／オフしてみて下さい。
どうです？ＬＥＤが対角線上で点灯したはずです。

38ここでもう１回、ＰＢ［ＰＡ０］を押してみて下さい。
最初に戻ってＬＥＤがパラパラ表示しているはずです。

これがすべての仕様ですが、下記の機能が追加されています。
１）ＰＩＯのイニシャル
２）ＳＷ，ＰＢの取りこみ（チャタリング取り付き）
３）ＳＷ入力処理
４）（ＬＥＤ表示処理）＜－すでに使用していますが、未解説です。
５）モード制御機能の開始／停止をコントロールする部分が必要になってきましたので作成しましました。

動作はいたってシンプルですが、上記のプログラムを追加しなければ機能しないところが、マイコンプロ
グラムの世話のかかるところです。

それでは、プログラムリストに沿って説明していきます。

39

２．プログラムリスト

このサンプルは、３ファイルの構成になっています。
“Ｓｔａｒｔｕｐ．ａｓｍ” 前章のまま使用したので解説を省略します。
“ＰｏｌＰｉｏ．ｃ”

ＰＩＯ関係をまとめました。

“Ｃａｔ２６１ｐ３．ｃ”

メインコントロール部です。

１）ＰＩＯ関係
file “PolPio.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolPio.c*/

6: /* ＜役割＞

PIO 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.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];/* INPort 一ヶ前 Buffer

*/

21:

Uchar

In20ms[2];/* INPort 20ms 前 Buffe

*/

22:

Uchar

InNows[2];/* INPort 生 Buffer

*/

23:

Uchar

OutPort;/* Out Port Buffer*/

24: /****************************************************************************/
25: /*

Ｍｅｍ初期化*/

26: /****************************************************************************/

40

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: /*

Ｉ／Ｏ初期化*/

38: /****************************************************************************/
39: void

PioIoInitial(void)

40: {
41:

P1DDR = 0xff;

42:/* Port1

全出力[LED]*//* Port4

入固定[SW]D0->D7

*/

43:

PADDR = 0;/* PortA

入力 D0=PB[PA0]

*/

44:

PCDDR = 0xc0;/* PortC

出力 D7=LCD-E

*/

45:

/*

出力 D6=LCD-RS

*/

46:

/*

入力 D5=PB[PC5]

*/

47:

/*

入力 D2=PB[PC2]

*/

48:

PFDDR = 0;/* PortF

入力 D7=PB[PF7]

*/

49:

PDDDR = 0xff;/* PortD

全出力[LCD]*/

50: }
51: /****************************************************************************/
52: /*SigInput Signal Input Process(チャタ取り+状態検出+立上り検出)*/

53: /****************************************************************************/
54: void

SigInput()

55: {
56:

InNows[0] = ~PORT4;/* IN 生 負論理 SW[P47->P40]

57:

if (PORTA & 0x1) InNows[1] &= ~1; /* IN 生 負論理 PB[PF7,PC5,PC2,PA0] */

58:

else

59:

if (PORTC & 0x4) InNows[1] &= ~2;

60:

else

61:

if (PORTC & 0x20) InNows[1] &= ~4;

62:

else

InNows[1] |= 1;

InNows[1] |= 2;

InNows[1] |= 4;

41

*/

63:

if (PORTF & 0x80) InNows[1] &= ~8;

64:

else

65:

InPort[0] = In20ms[0] & InNows[0]; /* チャタ取り+状態検出[P47->P40]

*/

66:

InPort[1] = In20ms[1] & InNows[1]; /*

*/

67:

UpPort[0] = (InPort[0] ^ InBack[0]) & InPort[0]; /* 立上検出[P47->P40] */68:

UpPort[1] = (InPort[1] ^ InBack[1]) & InPort[1]; /*69:

In20ms[0] = InNows[0];/* 20ms 前 Buffe 記憶[P47->P40]

*/

70:

In20ms[1] = InNows[1];

/*

*/

71:

InBack[0] = InPort[0];/* １ヶ前記憶[P47->P40]

*/

72:

InBack[1] = InPort[1];/**/InNows[1] |= 8;"[PF7->PA0]

"

"

"

[PF7->PA0] */[PF7->PA0][PF7->PA0]

73: }
74: /****************************************************************************/
75: /*

PioDemo() ＰＩＯデモ*/

76: /****************************************************************************/
77: void

PioDemo()

78: {
79:

if (InPort[0] & 0x1) OutPort = OutPort |

80:

else

81:

if (InPort[0] & 0x2) OutPort = OutPort |

82:

else

83:

if (InPort[0] & 0x4) OutPort = OutPort |

84:

else

85:

if (InPort[0] & 0x8) OutPort = OutPort |

86:

else

87:

if (InPort[0] & 0x10) OutPort = OutPort |

88:

else

89:

if (InPort[0] & 0x20) OutPort = OutPort |

90:

else

91:

if (InPort[0] & 0x40) OutPort = OutPort |

92:

else

93:

if (InPort[0] & 0x80) OutPort = OutPort |

94:

else

0x80;

/* SW[P40] */OutPort = OutPort & ~(0x80);
0x40;/* SW[P41] */OutPort = OutPort & ~(0x40);
0x20;/* SW[P42] */OutPort = OutPort & ~(0x20);
0x10;/* SW[P43] */OutPort = OutPort & ~(0x10);
0x8;/* SW[P44] */OutPort = OutPort & ~(0x8);
0x4;/* SW[P45] */OutPort = OutPort & ~(0x4);
0x2;/* SW[P46] */OutPort = OutPort & ~(0x2);
0x1;/* SW[P47] */OutPort = OutPort & ~(0x1);

95: }
96: /****************************************************************************/
97: /*

GetInPort() InPort[x]の読み取り*/

98: /****************************************************************************/

42

99: Uchar

GetInPort(Uchar port)

100: {
101:

return(InPort[port]);102: }
103: /****************************************************************************/
104: /*

GetUpPort() UpPort[x]の読み取り*/

105: /****************************************************************************/
106: Uchar

GetUpPort(Uchar port)

107: {
108:

return(UpPort[port]);109: }
110: /****************************************************************************/
111: /*

SigOutput

Signal Output Process(LED 出力)*/112: /****************************************************************************/
113: void

SigOutput()

114: {
115:

P1DR = ~OutPort;/* 0=点灯 1=消灯 のため*/

116: }
117: /****************************************************************************/
118: /*

OutPortPut 出力バッファーにセット*/

119: /****************************************************************************/
120: void

PutOutPort(Uchar patan,Uchar log)

121: {
122:

if (log == '=')

OutPort = patan;

123:

else if (log == '|') OutPort |= patan;

124:

else if (log == '&') OutPort &= patan;

125: }

43

［リストの説明］
１８～２３行：
このモジュールで使用する変数宣言です。
役割は、コメント参照して下さい。
２７～３５行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
３９～４９行：
ＰＩＯの初期化関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ポートｘデータディレクションレジスタに入出力方向をビットごとに指定します。
ビットを“１”にセットすると出力になります。
ビットを“０”にセットすると入力になります。
各ポートの割り振りは、コメントに記載されていますので、参考にしてください。
５４～７３行：
ＳＷおよびＰＢのチャタ取り＋状態検出＋立上り検出付きの入力関数です。
メインで２０ｍｓ毎に呼ばれます。
タイミングチャートで説明します。

０ｍｓ

２０ｍｓ

４０ｍｓ

６０ｍｓ

８０ｍｓ

１００ｍｓ

時間軸

ハーﾄﾞ信号

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

ハード信号＝ＩｎＮｏｗｓ［ｎ］

ｎ＝０ ＳＷ［Ｐ４７－＞Ｐ４０］

ソフト状態信号＝ＩｎＰｏｒｔ［ｎ］

ｎ＝１ ＰＢ［ＰＦ７－＞ＰＡ０］

ソフト立上信号＝ＵｐＰｏｒｔ［ｎ］

２０ｍｓ前のハード信号＝Ｉｎ２０ｍｓ［ｎ］

２０ｍｓ前のソフト状態信号＝ＩｎＢａｃｋ［ｎ］

44

の構成になっています。
ロジックを文章で説明するのは困難ですので、リストとタイミングチャートで解釈してみて下さい。
７７～９５行：
ＳＷ［Ｐ４０－＞Ｐ４７］のスイッチをオンすると、ＬＥＤ［Ｐ１０－＞Ｐ１７］を対角線上に点灯させるデモ関数です。
９９～１０２行：
ＳＷおよびＰＢのソフト状態信号を取得する関数です。
１０６～１０９行：
ＳＷおよびＰＢのソフト立ち上がり信号を取得する関数です。
１１３～１１６行：
出力バッファ“OutPort”をポート出力する関数です。
ハード的に、０＝点灯 １＝消灯のため、ここでＮＯＴにしています。
１２０～１２５行：
出力信号を出力バッファにセットする関数です。

45２）メインコントロール
file “Cat261p3.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p3.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

変数宣言*/

16: /****************************************************************************/
17:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

18:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/19: /****************************************************************************/
20: /*_main()*/

21: /****************************************************************************/
22: void_main(void)

23: {
24:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

25:

/*

NMI 立下りエッジ

*/

26:

/*

RAME 有効*/27:

SYSCR = 0x21;

SoftWait1ms(400);/* 20msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

28:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

29:/* の 1 回リトライ時間分待つ(20 回)

*/

30:

MemInitial();/* ﾒﾓﾘ系初期化

*/

31:

IoInitial();/* I/O 系初期化

*/

32:

while(1) {/* Signal Input Process

*/

33:

SigInput();

46

34:

SoftWait1ms(20);

/*

35:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

36:

SigOutput();/* Signal Output Process(LED 点灯)

*/

37:

ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り

*/

}

38: }
39: /****************************************************************************/
40: /*

Ｍｅｍ初期化*/

41: /****************************************************************************/
42: void

MemInitial(void)

43: {
44:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

45:

Shift = 0;/* Led Disp Patan Initial*/

PioMemInitial();/* PIO

*/

46:
47:

Mem 初期化

48: }
49: /****************************************************************************/
50: /*

Ｉ／Ｏ初期化*/

51: /****************************************************************************/
52: void

IoInitial(void)

53: {
54:

PioIoInitial();/* PIOI/O 初期化*/

55: }
56: /****************************************************************************/
57: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

58: /****************************************************************************/
59: void

ModeCntrol()

60: {
61:

if (GetUpPort(1) & 0x1) {62:

if (ModeStep < 10)

ModeStep = 10;/* PIO

Goto TEST

*/

63:

else

ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

64:

}

65:

switch(ModeStep) {66:

case 0:67:

ModeStep++;

68:

break;

69:/* PB[P30] ON?(立上)case 1:

47

*/

70:

RunRun();71:

break;

72:

case 10:73:

ModeStep++;

74:

break;

75:*//* PIO*/

TEST

case 11:76:

PioDemo();77:

break;

78:/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

}

79: }
80:
81: /****************************************************************************/
82: /*

RunRun()

CPU 走行表示*/

83: /****************************************************************************/
84: void

RunRun()

85: {
86:

if ((Shift <<= 1) == 0) Shift = 1;

87:

PutOutPort(Shift,'=');/* LED Shift 表示

*/

88: }
89: /****************************************************************************/
90: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

91: /****************************************************************************/
92: void

SoftWait1ms(Ushort ms)

93: {
94:

while(ms-- != 0) {95:

Wait1ms();

96:

}

97: }

48

［リストの説明］

前章のメインコントロールから追加された部分だけ解説します。

１７行：
モード制御用に使用するコントロールステップ変数の宣言です。
３３行：“ＰｏｌＰｉｏ．ｃ”で作成した、ＳＷとＰＢの入力関数を呼んでいます。
３５行：
モード制御する関数を呼んでいます。
４４行：
モード制御用に使用するコントロールステップ変数を初期化しています。
４７行：“ＰｏｌＰｉｏ．ｃ”で使用する変数を初期化する関数を呼んでいます。
５４行：
ＰＩＯのＩ／Ｏ初期化する関数を呼んでいます。
５９～７９行：
モード制御の関数です。
ＰＢ［ＰＡ０］をオンしたら、ＰＩＯのデモ関数を呼ぶ仕組みになっています。

保守ツールについては、もうご理解したと思いますので、この章以降説明は省略します。
このサンプルで変更したい部分がありましたら各自変更をし、ＨＥＷの［Ｂｕｉｌｄ］－［Ｂｕｉｌｄ］
をクリックしてみて下さい。

49

第４章 ＰＩＯの応用（ＬＣＤ）

ここの章では、ＰＩＯの応用としてＬＣＤの表示関数を作成してみました。
表示機能を追加しますと、いろいろとしゃべることができますので表現が豊かになります。
この章は、応用例ですので各自リストを読み、何をやっているのかを理解していただくことが目的です。

まずは、ＤＥＦのダウンロードで￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ４＿ＰＩＯ＿ＬＣＤ￥Ｃａｔ２６１ｐ４￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

移動したディレクトリの中に、“Ｃａｔ２６１ｐ４．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。

どうです？ ＬＣＤにオープニングメッセージがでましたか？

仕様は、前章と同じですので、ＰＢ［ＰＡ０］を押してみて下さい。
表現が豊かになったと思います。

どのような仕組みでＬＣＤに表示させているか説明するためにプログラムリストに沿って説明をします。

50

２．プログラムリスト

このサンプルは、前章に１モジュール追加して、４ファイルの構成になっています。
“Ｓｔａｒｔｕｐ．ａｓｍ” 前章のまま使用したので解説を省略します。
“ＰｏｌＰｉｏ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＬｃｄ．ｃ”

追加したＬＣＤコントロールのモジュールです。

“Ｃａｔ２６１ｐ４．ｃ”

メインコントロール部です。

表示方法の仕組みを説明します。
ＬＣＤに表示したい場合、ＣＰＵ内部の表示バッファー“LcdBuf[2][16]”に表示データーを“LcdReq”に表示要求フラグをセットします。
そして、メインの１ループ毎で要求フラグを監視し、フラグが立っていた場合、メインより直接ＬＣＤに
表示データを送る方式です。

１）ＬＣＤコントロール関係
file “PolLcd.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolLcd.c*/

6: /* ＜役割＞

LCD 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.h"

14: #include"DemoCtl.h"

15: /****************************************************************************/
16: /*

ＬＣＤ関係のマクロ*/

17: /****************************************************************************/
18: #define CLRCD

0x1/* LCD ｺﾏﾝﾄﾞ Disp Clear*/

19: #define EMDCD

0x6

/*

*/

51

ｴﾝﾄﾘｰﾓｰﾄﾞｾｯﾄ

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: /****************************************************************************/
31: void

LcdMemInitial(void)

32: {
33:

memset(LcdBuf[0],0x20,16);

34:

memset(LcdBuf[1],0x20,16);35:

LcdReq = ON;/* LCD 表示 Buffer

*/

/*

*/

表示 要求ﾌﾗｸﾞ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);

/*

*/

45:

LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(2)

*/

46:

SoftWait10us(10);

/*

*/

47:

LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(3)

*/

48:

LcdCmd(FUKCD);/* LCD ｺﾏﾝﾄﾞ ﾌｧﾝｸｼｮﾝｾｯﾄ(4)

*/

49:

LcdDispOn();/* LCD

表示ｵﾝ

*/

50:

LcdDispClear();/* LCD

表示ｸﾘｱ

*/

51:

LcdCmd(EMDCD);/* LCD ｺﾏﾝﾄﾞ ｴﾝﾄﾘｰﾓｰﾄﾞｾｯﾄ

*/

52:

SoftWait10us(4);/**/5ms Wait100us Wait

40us Wait

53: }54: /****************************************************************************/
55: /*AllLcdDisp()

全画面表示

*/

52

56: /****************************************************************************/
57: void

AllLcdDisp()

58: {
59:

if (LcdReq == ON) {60:

LcdReq = OFF;61:

LcdDispOff();

62:

GotoxyDisp(0,0,LcdBuf[0]);/* 1 行目*/

63:

GotoxyDisp(0,1,LcdBuf[1]);/* 2 行目*/

64:

LcdDispOn();65:/* 表示要求/*"*/
OFF にするのはココだけ

*/

}

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: }
78: /****************************************************************************/
79: /*

GotoxyDisp()

カーソル移動＋表示*/

80: /****************************************************************************/
81: void

GotoxyDisp(Uchar x,Uchar y,Uchar *str)

82: {
83:

Gotoxy(x,y);84:

while(*str != 0) {

85:
86:

LcdPutch(*str++);/* カーソル移動*//* １文字表示

*/

}

87: }
88: /****************************************************************************/
89: /*

Gotoxy()カーソル移動*/90: /****************************************************************************/
91: void

Gotoxy(Uchar x,Uchar y)53

92: {
93:

Uchar

ramadr;94:
95:

if (y == 0) ramadr = 0;/* DDRAM ｱﾄﾞﾚｽ計算

*/

96:

else

97:

ramadr += x;98:

LcdCmd(ramadr | 0x80);/* LCD ｺﾏﾝﾄﾞ DDRAM ｱﾄﾞﾚｽｾｯﾄ

*/

99:

SoftWait10us(4);/**/ramadr = 0x40;

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: /****************************************************************************/
125: void

LcdPutch(Uchar data)

126: {
127:

PCDR |= 0x40;/* LCD RS

54

ON

*/

128:

if (data < 0x20) data = 0x20;

129:

LcdCmd(data);

130:

PCDR &= ~0x40;/* LCD RS

131:

SoftWait10us(4);

/*

OFF

*/

40us Wait*/

132: }
133: /****************************************************************************/
134: /*

LcdCmd()LCD command OUT*/

135: /****************************************************************************/
136: void

LcdCmd(Uchar cmd)

137: {138:

PDDR = cmd;/* LCD Data

139:

PCDR |= 0x80;

/*

E

ON

*/

140:

PCDR &= ~0x80;

/*

E

OFF

*/

141:
142: }

55*/

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

機能

Ｄ０－Ｄ７

入出力

８本のデータバス。トライステート双方向性
この線を通してデータ・コマンドのやり取りをします。

Ｅ

入力

動作起動信号。データの書き込みおよび読み出しの起動をかけます。

Ｒ／Ｗ

入力

読み出し（Ｒ）／書き込み（Ｗ）の選択信号“１”：読み出し “０”
：書きこみ

ＲＳ

入力

レジスタを選択する信号。
“０”：インストラクションレジスタ（Ｗ）
ビジィフラグ、アドレスカウンタ（Ｒ）“１”：データレジスタ

ＶＯ

電源

ＶＤ

電源

液晶表示駆動用電源、ＶＯを変えることにより画面の濃淡を変化させることができます
＋５Ｖ

ＶＳ

電源

グランド端子：０Ｖ

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

ＲＳ

Ｔａｓ
Tas

：Ｍｉｎ ４０ｎｓ

ＰＷｅｈ ：Ｍｉｎ ２３０ｎｓ

Ｒ／Ｗ

Ｔｄｓｗ ：Ｍｉｎ ８０ｎｓ
Pweh

Ｅ

Tdsw

Ｄ０－Ｄ７

有効データ

ＴｃｙｃＥ：Ｍｉｎ ５００ｎｓ

TcycE

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

56

ＤＤ ＲＡＭアドレスと表示桁の対応関係
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

図［４－２－３］ ＤＤ ＲＡＭアドレスマップ
コード
インストラクション

RSR/W

D7 D6 D5 D4 D3 D2 D1 D0

機能

実行時間
(max)

０

０

0 0 0 0 0 0 0 1

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

1.64ms表示クリア００

0 0 0 0 0 0 1 *カーソルホーム０

0 0 0 0 0 1 1/D S

００

0 0 0 0 1 D C B

全表示オン／オフ（Ｄ）
カーソルのｵﾝ/ｵﾌ（Ｃ）
ｶｰｿﾙ位置のﾌﾞﾘﾝｸ（Ｂ）

40us

０

０

0 0 0 1 S/C R/L * *DD RAM の内容を変えずに、
カーソルの移動と、表示シフトをします。

40us

０

０

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

40us

０

０

１―――ＡＤＤ―――

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

40us

表示オン／オフ
コントロール
カーソル／
表示シフト
ファンクションセット
ＤＤ ＲＡＭ
アドレスセット

Ｉ／Ｄ＝１：インクリメント

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

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

Ｓ

カーソルをホーム位置へ戻します、シフトしていた表示も戻ります。DDRAM の内容
は変化しません
データの書き込みおよび読
み出し時に、カーソルの進
む方向、表示をシフトかの設定をする。

Ｂ＝１：カーソルオン

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

ＤＬ ＝１：８ビット＝０：ブリンクオフ＝０：４ビット

Ｓ／Ｃ＝１：表示シフトＮ＝０：カーソル移動

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

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

40us

電源オン
ＶDD が４．５Ｖに達してから４５ｍｓ以上待つ

ファンクションセット
ga
４．１ｍｓ以上待つ

ファンクションセット
ga
１００ｕｓ以上待つ

ファンクションセット
ga
ファンクションセット
ga
表示オフ
ga
表示クリア
ga
エントリーモードセットga
初期設定終了図［４－２－５］ ＬＣＤ初期設定手順58

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

59２）メインコントロール
file “Cat261p4.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p4.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

変数宣言*/

16: /****************************************************************************/
17:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

18:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/19: /****************************************************************************/
20: /*_main()*/

21: /****************************************************************************/
22: void_main(void)

23: {
24:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

25:

/*

NMI 立下りエッジ

*/

26:

/*

RAME 有効*/27:

SYSCR = 0x21;

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

28:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

29:/* の 1 回リトライ時間分待つ(20 回)

*/

30:

MemInitial();/* ﾒﾓﾘ系初期化

*/

31:

IoInitial();/* I/O 系初期化

*/

32:

while(1) {/* Signal Input Process

*/

33:

SigInput();

60

34:

SoftWait1ms(20);

/*

35:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

36:

AllLcdDisp();/* LCD*/

37:

SigOutput();/* Signal Output Process(LED 点灯)

38:

ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り

全画面表示

*/

*/

}

39: }
40: /****************************************************************************/
41: /*

Ｍｅｍ初期化*/

42: /****************************************************************************/
43: void

MemInitial(void)

44: {
45:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

46:

Shift = 0;/* Led Disp Patan Initial

*/

48:

PioMemInitial();/* PIOMem 初期化*/

49:

LcdMemInitial();/* LCDMem 初期化

*/

47:

50: }
51: /****************************************************************************/
52: /*

Ｉ／Ｏ初期化*/

53: /****************************************************************************/
54: void

IoInitial(void)

55: {
56:

PioIoInitial();/* PIOI/O 初期化*/

57:

LcdIoInitial();/* LCDI/O 初期化*/

58: }
59: /****************************************************************************/
60: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

61: /****************************************************************************/
62: void

ModeCntrol()

63: {
64:

if (GetUpPort(1) & 0x1) {65:

if (ModeStep < 10)

ModeStep = 10;/* PIO

Goto TEST

*/

66:

else

ModeStep = 0;/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

67:

}

68:

switch(ModeStep) {69:

case 0:/* PB[PA0] ON?(立上)

61

*/

70:

GotoxyMemSet(0,0,"CAT261&AH6000 by");71:

GotoxyMemSet(0,1,"Polling

72:

ModeStep++;

73:

break;

74:*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* PIO*/[PA0]");

case 1:75:

RunRun();76:

break;

77:/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

case 10:78:

GotoxyMemSet(0,0,"PIO

79:

GotoxyMemSet(0,1,"SW[P47]->SW[P40]");80:

ModeStep++;

81:

break;

82:");

case 11:83:

PioDemo();84:

break;

85:

TEST

}

86: }
87: /****************************************************************************/
88: /*

RunRun()

CPU 走行表示*/

89: /****************************************************************************/
90: void

RunRun()

91: {
92:

if ((Shift <<= 1) == 0) Shift = 1;

93:

PutOutPort(Shift,'=');/* LED Shift 表示

*/

94: }
95: /****************************************************************************/
96: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

97: /****************************************************************************/
98: void

SoftWait1ms(Ushort ms)

99: {
100:

while(ms-- != 0) {101:

Wait1ms();

102:

}

103: }
104: /****************************************************************************/
105: /*

SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ

62*/106: /****************************************************************************/
107: void

SoftWait10us(Ushort us)

108: {
109:

while(us-- != 0) {110:

Wait10us();

111:

}

112: }

63

［リストの説明］

前章のメインコントロールから追加された部分だけ解説します。

３６行：
ＬＣＤ全画面表示関数を呼んでいます。
４９行：“ＰｏｌＬｃｄ．ｃ”で使用する変数を初期化する関数を呼んでいます。
５７行：
ＬＣＤの初期設定をする関数を呼んでいます。
７０～７１行：
ＬＣＤにオープニングメッセージを表示させるための関数を呼んでいます。
７８～７９行：
ＬＣＤにＰＩＯモードメッセージを表示させるための関数を呼んでいます。

これで、この章のリスト説明は終わりです。
ご理解いただけたでしょうか？ プログラム記述は個性がヒジョウにでるもので、なれない記述だと読みにくいと思います。
私自身も、他人の書いたプログラムを読むのには、かなりのエネルギーが必要です。
しかし、プログラム記述の標準仕様ができない限り、この問題はプログラマに付きまといます。
根気に読み続けて頂き理解してもらいたいと思います。

次は、タイマ／カウンタ使用例の解説へと進みます。

64

第５章 タイマ／カウンタ

ここの章では、タイマ／カウンタのイニシャルとタイマ使用サンプルの解説を主におき、応用例として評価ボードに外付けしたブザーを利用したいと思います。
ＣＮ１３－８Ｂ（ＰＢ０／ＴＩＯＣＡ３）にブザーを接続します。
タイマーのＰＷＭモードを利用し、指定周波数のパルス出力をしますとブザーを色々な音階で鳴らすことができますので、この仕組みを使ったサンプルを作成していきたいと思います。

まずは、ＤＥＦのダウンロードで￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ５＿Ｔｉｍｅｒ_Ｃｏｕｎｔｅｒ￥Ｃａｔ２６１ｐ５￥にディレクトリの移動をしておいて下さい。

65

１．動かしてみましょう

移動したディレクトリの中に、“Ｃａｔ２６１ｐ５．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。

どうです？ ＬＣＤにオープニングメッセージがでましたか？

仕様は、前章に追加したかたちになります。ＰＢ［ＰＡ０］を押してみて下さい。

どうです？ ＬＣＤ表示の左上に“ＰＩＯ”と表示したはずです。

ここでもう 1 回、ＰＢ［ＰＡ０］を押してみて下さい。

どうです？ ＬＣＤ表示の左上に“Ｔｉｍｅｒ／Ｃｏｕｎｔｅｒ”と表示したはずです。

ここが、この章の追加サンプルプログラム部分です。

ここで、ＰＢ［ＰＦ７］を押してみて下さい。

どうです？ ブザーが鳴り、ＬＣＤ表示の左下に“２００Ｈｚ”と表示したはずです。

ここで、数回ＰＢ［ＰＦ７］を押してみて下さい。

どうです？ ブザーの音が高くなり、ＬＣＤに周波数を表示しているはずです。

ここで、ＰＢ［ＰＣ５］を押してみて下さい。周波数が下がったはずです。

ここでの操作仕様は、ＰＢ［ＰＡ０］ モード開始／終了
ＰＢ［ＰＦ７］ 周波数を１００Ｈｚ上げます（ＭＡＸ １１００Ｈｚ）
ＰＢ［ＰＣ５］ 周波数を１００Ｈｚ下げます（ＭＩＮ ２００Ｈｚ）
です。
ブザーを鳴らすだけでなく、ＣＮ１３－８Ｂの信号をシンクロで見るのも面白いかもしれません。
それでは、プログラムリストを見てみましょう！

66

２．プログラムリスト

このサンプルは、前章に２モジュール追加して、６ファイルの構成になっています。
“Ｓｔａｒｔｕｐ．ａｓｍ” 前章のまま使用したので解説を省略します。
“ＰｏｌＰｉｏ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＬｃｄ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＴｉｍｅ．ｃ”

Ｔｉｍｅｒコントロールのモジュールです。

“ＣａｔＳｕｂ．ｃ”

共通サブルーチンのモジュールです。

“Ｃａｔ２６１ｐ５．ｃ”

メインコントロール部です。

１）Ｔｉｍｅｒコントロール関係
file “PolTime.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolTime.c*/

6: /* ＜役割＞

タイマ関係

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.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

67*/

24: /****************************************************************************/
25: /*

Ｍｅｍ初期化*/

26: /****************************************************************************/
27: void

TimMemInitial(void)

28: {
29:

BuzzerHz = 0;/* Buzzer Hz

*/

30: }
31: /****************************************************************************/
32: /*

Ｉ／Ｏ初期化*/

33: /****************************************************************************/
34: void

TimIoInitial(void)

35: {
36:

MSTPCRA &= ~0x20;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ TPU ｽﾀｰﾄ

*/

37:

TSTR = 0;/* Buzzer TPU_3 ここでは停止

*/

38: }
39: /****************************************************************************/
40: /*

Buzzer

TPU_3 TIOCA3 出力に Buzzer 接続 sys = 20,000,000Hz*/

41: /****************************************************************************/
42: void

Buzzer(Ushort hz)

43: {
44:

Ushort

cyc;

45:
46:

if ((hz >= BZMIN) && (hz <= BZMAX)) {47:

TCR_3 = 0x21;/* Buzzer ON*//* CNTL TGRA ｺﾝﾍﾟｱﾏｯﾁで TCNT ｸﾘｱ

001 */

48:/*

立上りｴｯｼﾞ

00 */

49:

/*

sys/4(5,000,000Hz)

001 */

50:

TMDR_3 = 0xc2;

51:
52:

TIORH_3 = 3;53:/* MODE Default

1100 *//*

0010 */PWM ﾓｰﾄﾞ 1/* I/O TGRB 未使用

0000 *//*

0011 */TIOCA3 ﾏｯﾁﾄｸﾞﾙ出力54:

cyc = 5000000 / hz;/* 周期の計算*/

55:

TGRA_3 = cyc / 2;/* 周期設定/2*/

56:

TCNT_3 = 0;/* ｶｳﾝﾄｸﾘｱ

*/

57:

TSTR |= 0x8;/* TCNT_3 ｽﾀｰﾄ*//* Buzzer OFF

*/

58:

}

59:

else {

68

60:

TCNT_3 = 0;/* ｶｳﾝﾄｸﾘｱ

*/

61:

TSTR &= ~0x8;/* TCNT_3 ｽﾄｯﾌﾟ

*/

62:

}

63: }
64: /****************************************************************************/
65: /*

TimerDemo

Timer デモ*/66: /****************************************************************************/
67: void

TimerDemo()

68: {
69:

Uchar

port;

70:

Uchar

dec[4+1];

71:
72:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

73:

if (port & 0xc) {/* PB[PC5] | PB[PF7] ON ?

*//* PB[-PC5] ON-立上り*//* PB[+PF7] ON-立上り

*/

74:

if (port & 0x4) {75:

BuzzerHz -= 100;

76:

}

77:

else if (port & 0x8) {78:

BuzzerHz += 100;

79:

}

80:

if (BuzzerHz < BZMIN) BuzzerHz = BZMIN;

81:

if (BuzzerHz > BZMAX) BuzzerHz = BZMAX;

82:

Buzzer(BuzzerHz);

83:

Bin2AdecN(dec,BuzzerHz,4);84:

GotoxyMemSet(0,1,dec);85:/* 表示用データ作成

}

86: }

69

*/

リストの説明に入る前に、ＰＷＭモードの説明をします。
このサンプルでは、ＴＰＵ＿３を使用しましたので、ＴＰＵ＿３について説明します。

（１）使用内部レジスタ
シンボル
ＭＳＴＰＣＲＡＴＳＴＲ
ＴＣＲ＿３
ＴＭＤＲ＿３
ＴＩＯＲ＿３
ＴＧＲＡ＿３
ＴＣＮＴ＿３

機能
ＴＰＵのモジュールストップモードを解除する
タイマカウンタの動作／停止を設定する
ＴＣＮＴの入力クロックおよびクリア要因を設定する

ＰＷＭモードの設定
コンペアマッチＡ発生時の出力パルスレベルの設定
出力パルスの１／２周期を設定する
カウンターとして使用する

Ｃソースライン
３６行
３７・５７・６１行
４７行
５０行
５２行
５５行
５６行

表［５－２－１］ ＴＰＵ＿３内部レジスタ（２）パルス出力仕様

５０％

５０％

パルス周期
・ＰＷＭ１モード使用
・コンペアマッチ時、カウンタクリア機能
・トグル出力機能・ＴＣＮＴ＿３のクロックをｓｙｓ／４でカウント（ｓｙｓ＝２０ＭＨｚ）（３）周期計算システムクロック＝２０ＭＨｚとして、ＴＣＮＴの内部カウントクロックをｓｙｓ／４としましたので、

２０ＭＨｚ ÷ ４ ＝ ５．０ＭＨｚ（内部クロック）

ＴＣＮＴは、ｗｏｒｄサイズ（１６ビット）ですので、最大６５５３５まで設定できるとして、

５．０ＭＨｚ ÷ （６５５３５ × ２） ＝ 約３９Ｈｚ （最小周波数）
５．０ＭＨｚ ÷ （１× ２） ＝ ２．５ＭＨｚ（最大周波数）

になります

70

［リストの説明］
１８行：
ブザー出力周波数の最小値の定義です。
１９行：
ブザー出力周波数の最大値の定義です。
２３行：
出力周波数を記憶しておく変数の宣言です。
２７～３０行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
３４～３８行：
タイマ／カウンタを初期化する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
重要 モジュールストップコントロールレジスタのＴＰＵをオフ（開始）することをお忘れなく！
ただし、ここではＴＰＵ＿３未動作状態で初期化しておきます。
４２～６３行：
指定周波数のパルスをブザーに出力する関数です。ＴＰＵ＿３使用します。

指定周波数が、範囲外だった場合、ブザーを止める仕組みになっています。
指定周波数が、範囲内だった場合は、指定周波数になるように周期計算をし、デューティ５０％になる
ように、ＰＷＭ設定のトグル出力を使用します。
１）ＴＣＮＴの内部カウントクロックプリスケール設定およびクリア要因の設定
２）タイマモードの設定（ＰＷＭモード１）
３）ＴＩＯＲのコンペアマッチＡのトグル出力指定
４）ＴＧＲＡにパルス周期の１／２を設定
５）カウンタクリア（する必要はありませんが念のため）
６）ＴＰＵ＿３カウント開始指示

詳細は、前ページを参照して下さい。
６４～８３行：
ＰＢ［ＰＦ７］，ＰＢ［ＰＣ５］で出力周波数を指定させる操作をコントロールする関数です。
ここで、指定周波数のタイマ出力をさせ、その周波数の表示をしています。

71２）汎用サブルーチン関係
file “CatSub.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプルプログラム＞

*/

4: /*

*/

5: /* ＜MOD＞

CatSub.c*/

6: /* ＜役割＞

汎用ｻﾌﾞﾙｰﾁﾝ関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws

*/

9: /*

*/

10: /****************************************************************************/
11: #include"io261x.h"

12: #include"DemoCtl.h"

13: /****************************************************************************/
14: /*

ＢＩＮー＞アスキーＤＥＣ変換 桁指定 asc[keta]=NULL 付き*/

15: /****************************************************************************/
16: void

Bin2AdecN(char *asc,Ushort bin,Uchar keta)

17: {
18:

asc[keta] = 0;19:while(keta--) {20:

asc[keta] = bin % 10;

21:bin /= 10;22:

asc[keta] |= '0';

23:

}

24: }
25: /****************************************************************************/
26: /*

ＢＩＮー＞アスキーＨＥＸ変換 桁指定 asc[keta]=NULL 付き*/

27: /****************************************************************************/
28: void

Bin2AhexN(char *asc,Ushort bin,Uchar keta)

29: {
30:

Uchar dt;31:
32:

asc[keta] = 0;33:

while(keta--) {

72

34:

dt = (bin & 0xf);

35:

if (dt >= 0xa) dt = (dt + 0x37);

36:

else

37:

asc[keta] = dt;

38:

bin >>= 4;39:

dt = (dt + 0x30);

}

40: }
41: /****************************************************************************/
42: /*

アスキーＤＥＣ－＞ＢＩＮ変換 桁指定*/

43: /****************************************************************************/
44: char * Adec2binN(Ushort *bin,char *ptr,Uchar keta)
45: {
46:

char

dt;

47:
48:

*bin = 0;49:

while(keta--) {

50:

dt

= (char)(*ptr - 0x30);

51:*bin = (*bin * 10) + dt;

52:

ptr++;

53:

}

54:

return(ptr);

55: }
56: /****************************************************************************/
57: /*

アスキーＨＥＸー＞ＢＩＮ変換 桁指定*/

58: /****************************************************************************/
59: char * Ahex2binN(Ushort *bin,char *ptr,Uchar keta)
60: {
61:

Uchar dt;

62:

Uchar c;63:
64:*bin = 0;65:while(keta--) {66:

c = (Uchar)toupper(*ptr);

67:

if (c >= 'A') dt = c - 0x37;

68:

else

69:

*bin = (*bin << 4) | dt;

dt = c - 0x30;

73

70:

ptr++;

71:

}

72:

return(ptr);

73: }
74: /****************************************************************************/
75: /*

ストリングＣｏｐｙ(WORD)*/

76: /****************************************************************************/
77: Ushort * _strcpyW(Ushort *dst,Ushort *src)
78: {
79:

while(*src != 0) {80:

*dst++ = *src++;

81:

}

82:

*dst = 0;83:

return(dst);

84: }［リストの説明］
１６～２４行：Ｕｓｈｏｒｔのバイナリを指定桁の１０進アスキー変換をする関数です。
２８～４０行：Ｕｓｈｏｒｔのバイナリを指定桁の１６進アスキー変換をする関数です。
４４～５５行：
１０進アスキーデータの指定桁分をＵｓｈｏｒｔのバイナリに変換をする関数です。
５９～７３行：
１６進アスキーデータの指定桁分をＵｓｈｏｒｔのバイナリに変換をする関数です。
７７～８４行：
Ｗｏｒｄデータを元から先へゼロ（０）までコピーする関数です。

以後、この共通サブルーチンを各所で使用します。

74３）メインコントロール
file “Cat261p5.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p5.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

外部変数使用宣言*/

16: /****************************************************************************/
17: extern short

BuzzerHz;/* Buzzer Hz*/

18: /****************************************************************************/
19: /*

変数宣言*/

20: /****************************************************************************/
21:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

22:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/23: /****************************************************************************/
24: /*_main()*/

25: /****************************************************************************/
26: void_main(void)

27: {
28:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

29:

/*

NMI 立下りエッジ

*/

30:

/*

RAME 有効*/31:

SYSCR = 0x21;

SoftWait1ms(400);/* 20msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

32:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

33:/* の 1 回リトライ時間分待つ(20 回)

75

*/

34:

MemInitial();/* ﾒﾓﾘ系初期化

*/

35:

IoInitial();/* I/O 系初期化

*/

36:

while(1) {37:

SigInput();/* Signal Input Process

*/

38:

SoftWait1ms(20);

/*

*/

39:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

40:

AllLcdDisp();/* LCD*/

41:

SigOutput();/* Signal Output Process(LED 点灯)

42:

ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り

全画面表示

*/

}

43: }
44: /****************************************************************************/
45: /*

Ｍｅｍ初期化*/

46: /****************************************************************************/
47: void

MemInitial(void)

48: {
49:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

50:

Shift = 0;/* Led Disp Patan Initial

*/

52:

PioMemInitial();/* PIOMem 初期化*/

53:

LcdMemInitial();/* LCDMem 初期化*/

54:

TimMemInitial();/* TIM

Mem 初期化

*/

51:

55: }
56: /****************************************************************************/
57: /*

Ｉ／Ｏ初期化*/

58: /****************************************************************************/
59: void

IoInitial(void)

60: {
61:

PioIoInitial();/* PIOI/O 初期化*/

62:

LcdIoInitial();/* LCDI/O 初期化*/

63:

TimIoInitial();/* TIMI/O 初期化*/

64: }
65: /****************************************************************************/
66: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

67: /****************************************************************************/
68: void

ModeCntrol()

69: {

76

70:

if (GetUpPort(1) & 0x1) {71:

if (ModeStep < 10)72:/* PB[PA0] ON?(立上)Goto TEST*/

else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST

*/

73:

else

/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

74:

Buzzer(0);/* 強制 OFF*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* PIOTEST*//* Timer TEST

*/

75:

}

76:

switch(ModeStep) {77:

case 0:ModeStep = 10;

ModeStep = 0;78:

GotoxyMemSet(0,0,"CAT261&AH6000 by");79:

GotoxyMemSet(0,1,"Polling

80:

ModeStep++;

81:

break;

82:[PA0]");

case 1:

83:

RunRun();84:

break;

85:

case 10:86:

GotoxyMemSet(0,0,"PIO

87:

GotoxyMemSet(0,1,"SW[P47]->SW[P40]");88:

ModeStep++;

89:

break;

90:");

case 11:91:

PioDemo();92:

break;

93:

case 20:94:

GotoxyMemSet(0,0,"Timer/Counter95:

GotoxyMemSet(0,1,"0000Hz[+PF7-PC5]");96:

BuzzerHz = 0;97:

ModeStep++;98:

break;99:");/* Buzzer Hz*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/

case 21:100:

TimerDemo();101:

RunRun();102:

break;

103:/* PIO*/}

104: }
105: /****************************************************************************/

77106: /*

RunRun()

CPU 走行表示*/

107: /****************************************************************************/
108: void

RunRun()109: {110:

if ((Shift <<= 1) == 0) Shift = 1;

111:

PutOutPort(Shift,'=');/* LED Shift 表示*/

112: }
113: /****************************************************************************/
114: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

115: /****************************************************************************/
116: void

SoftWait1ms(Ushort ms)

117: {
118:

while(ms-- != 0) {119:

Wait1ms();

120:

}

121: }
122: /****************************************************************************/
123: /*

SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/

124: /****************************************************************************/
125: void

SoftWait10us(Ushort us)

126: {
127:

while(us-- != 0) {128:

Wait10us();

129:

}

130: }

78

［リストの説明］ 前章のメインコントロールから追加された部分だけ解説します。

１７行：
このモジュールで使用する外部変数宣言です。
５４行：“ＰｏｌＴｉｍｅ．ｃ”で使用する変数の初期化関数を呼んでいます。
６３行：
タイマレジスタを初期化する関数を呼んでいます。
９３～１０２行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

これで、この章のリスト説明は終わりです。
ご理解いただけたでしょうか？
周波数を１００Ｈｚごとの変化でなく、もっと細かくしたい場合は、どこを修正すれば良いか、わかりましたか？（ＰｏｌＴｉｍｅ．ｃのどこか）興味のあるかたは、修正して［Ｂｕｉｌｄ］を実行してチャレンジしてみて下さい。

次は、ＳＣＩ使用例の解説へと進みます。

79

第６章 ＳＣＩ
ここの章では、ＳＣＩのイニシャルとＳＣＩ使用サンプルの解説をします。
ＳＣＩ使用サンプルは、ポーリング送／受信の１バイトのループバック通信です。
ＳＣＩ０（送信）―＞ＳＣＩ１（受信）ＳＣＩ１（送信）―＞ＳＣＩ０（受信） の方式でループバックします。

まずは、ＤＥＦのダウンロードで、￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ６＿ＳＣＩ￥Ｃａｔ２６１ｐ６￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２６１ｐ６．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。

どうです？ ＬＣＤにオープニングメッセージがでましたか？

もう馴れたと思いますので、ＬＣＤ表示の左上に“ＳＣＩ”と表示がでるまで、ＰＢ［ＰＡ０］を押して下さい。
［評価ボード上のＳＷ１１－１，２をオン（ＴＸＤ，ＲＸＤを折り返す）にして下さい。
］［ＣＡＴ２６１基板のＳＷ１－１，２，３，４をオン（信号をＲＳドライバ経由）にして下さい。
］

ＰＢ［ＰＣ２］が、送受信開始／停止になっていますので、押してみて下さい。
これで、ＰＢ［ＰＣ２］停止を押されるまで、送受信を繰り返します。

ＬＣＤ画面

ＴｘｘＲｏｘｘＲｉｘｘ［ＰＣ２］ Ｒｏ＝ＳＣＩ０ Ｒｉ＝ＳＣＩ１の受信と“ｘｘ”の部分は、送信するごとに＋１する送受信データです。
送受信停止中に、ＰＢ［ＰＦ７］、ＰＢ［ＰＣ５］を押しますと、ボーレートの変更ができます。
それでは、どのような仕組みでプログラムされているかプログラムリストを見てみましょう！
80

２．プログラムリスト

このサンプルは、前章に１モジュール追加して、７ファイルの構成になっています。
“Ｓｔａｒｔｕｐ．ａｓｍ” 前章のまま使用したので解説を省略します。
“ＰｏｌＰｉｏ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＬｃｄ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＴｉｍｅ．ｃ”

前章のまま使用したので解説を省略します。

“ＣａｔＳｕｂ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＳｃｉ．ｃ”

ＳＣＩコントロールのモジュールです。

“Ｃａｔ２６１ｐ５．ｃ”

メインコントロール部です。

１）ＳＣＩコントロール関係
file “PolSci.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolSci.c*/

6: /* ＜役割＞

SCI(SIO) 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.h"

14: #include"DemoCtl.h"

15: /****************************************************************************/
16: /*SCI ボレート計算+etc*/

17: /****************************************************************************/
18: #define CLOCK(20000000/32)/* 調歩同期 n=0 時の計算式*/

19: #define BRRN(b)((CLOCK/b)-1)

20: #define NON

0/* ﾊﾟﾘﾃｨ

NON*/

21: #define EVEN

1

/*

EVEN

*/

22: #define ODD

2

/*

ODD

*/

81

23: /****************************************************************************/
24: /*

変数宣言*/

25: /****************************************************************************/
26:

Uchar

SciStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

27:

Uchar

SciSelect;/* ﾎﾞｰﾚｰﾄ選択

*/

28:

Uchar

TxDat;/* 送信ﾃﾞｰﾀ

*/

29:

Uchar

RxDat;/* 受信ﾃﾞｰﾀ*/

30: const

UshortBpsTbl[] =

31: {
32:

4800,

33:

9600,

34:

19200,

35:

31250,

36:

38400,

37:0,38: };
39: /****************************************************************************/
40: /*

Ｍｅｍ初期化*/

41: /****************************************************************************/
42: void

SciMemInitial(void)

43: {
44:

SciStep= 0;

45:

SciSelect = 1;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS

*/

46: }
47: /****************************************************************************/
48: /*

Ｉ／Ｏ初期化*/

49: /****************************************************************************/
50: void

SciIoInitial(void)

51: {
52:

RsOpen0(9600,8,NON);/* SCI0 Open

*/

53:

RsOpen1(9600,8,NON);/* SCI1 Open

*/

54: }
55: /****************************************************************************/
56: /* RS232C(SCI0) Open bps= ﾎﾞﾚｰﾄ[4800,*9600,19200,31250,38400]*/

57: /*ch= ｷｬﾗｸﾀ[7,*8]*/

58: /*

pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/

82

59: /**= ﾃﾞﾌｫﾙﾄ

*/60: /*

固定= x1 STOP=1bit*/

61: /****************************************************************************/
62: void

RsOpen0(Ushort bps,Uchar ch,Uchar pty)

63: {
64:

Uchar

bck;

65:

Uchar

smr;

66:
67:

MSTPCRB &= ~0x80;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ SCI0 ｽﾀｰﾄ

*/

68:

SCMR_0 = 0xf2;/* ｽﾏｰﾄ SMIF=0 Non ｽﾏｰﾄ

*/

70:

smr = 0;/* ﾓｰﾄﾞ ｷｬﾗｸﾀ[8bit] ﾊﾟﾘﾃｨ[NON]

*/

71:

if (ch == 7)

smr |= 0x40;/*

ｷｬﾗｸﾀ[7bit]

*/

72:

if (pty == EVEN)

smr |= 0x20;/*

ﾊﾟﾘﾃｨ[EVEN]

*/

73:

else if (pty == ODD) smr |= 0x30;/*

ﾊﾟﾘﾃｨ[ODD]

*/

74:

SMR_0 = smr;

69:

75:
76:

if (bps == 4800)

bck = BRRN(4800);77:else if (bps == 9600)

bck = BRRN(9600);

78:else if (bps == 19200) bck = BRRN(19200);79:else if (bps == 31250) bck = BRRN(31250);80:else if (bps == 38400) bck = BRRN(38400);81:

BRR_0 = bck;/* ﾎﾞｰﾚｰﾄｼﾞｪﾈﾚｰﾄ設定

*/

82:

Wait1ms();/* 1bit 経過待ち 2400BPS(0.42ms+a)

*/

83:

SSR_0 &= 0x87;/* RDRF+ResetStatus

*/

84:

SCR_0 = 0x30;/* TE+RE*/

85: }
86: /****************************************************************************/
87: /* RS232C(SCI1) Open bps= ﾎﾞﾚｰﾄ[4800,*9600,19200,31250,38400]*/

88: /*ch= ｷｬﾗｸﾀ[7,*8]*/

89: /*

pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/

90: /**= ﾃﾞﾌｫﾙﾄ

*/91: /*

固定= x1 STOP=1bit*/

92: /****************************************************************************/
93: void

RsOpen1(Ushort bps,Uchar ch,Uchar pty)

94: {

83

95:

Uchar

bck;

96:

Uchar

smr;

97:
98:

MSTPCRB &= ~0x40;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ SCI1 ｽﾀｰﾄ

*/

99:

SCMR_1 = 0xf2;/* ｽﾏｰﾄ SMIF=0 Non ｽﾏｰﾄ

*/

101:

smr = 0;/* ﾓｰﾄﾞ ｷｬﾗｸﾀ[8bit] ﾊﾟﾘﾃｨ[NON]

*/

102:

if (ch == 7)

smr |= 0x40;/*

ｷｬﾗｸﾀ[7bit]

*/

103:

if (pty == EVEN)

smr |= 0x20;/*

ﾊﾟﾘﾃｨ[EVEN]

*/

104:

else if (pty == ODD) smr |= 0x30;/*

ﾊﾟﾘﾃｨ[ODD]

*/

105:

SMR_1 = smr;

100:

106:
107:

if (bps == 4800)

bck = BRRN(4800);108:else if (bps == 9600)

bck = BRRN(9600);

109:

else if (bps == 19200) bck = BRRN(19200);110:else if (bps == 31250) bck = BRRN(31250);

111:else if (bps == 38400) bck = BRRN(38400);112:

BRR_1 = bck;/* ﾎﾞｰﾚｰﾄｼﾞｪﾈﾚｰﾄ設定

*/

113:

Wait1ms();/* 1bit 経過待ち 2400BPS(0.42ms+a)

*/

114:

SSR_1 &= 0x87;/* RDRF+ResetStatus

*/

115:

SCR_1 = 0x30;/* TE+RE*/

116: }
117: /****************************************************************************/
118: /*

RsPutch0

RS232C(SCI0) 送信*/

119: /****************************************************************************/
120: void

RsPutch0(Uchar tx)

121: {
122:

while((SSR_0 & 0x80) == 0) {}123:

TDR_0 = tx;

124:

SSR_0 &= ~(0x80);// TDRE=1 wait

125: }
126: /****************************************************************************/
127: /*

RsPutch1

RS232C(SCI1) 送信*/

128: /****************************************************************************/
129: void

RsPutch1(Uchar tx)

130: {

84

131:

while((SSR_1 & 0x80) == 0) {}132:

TDR_1 = tx;

133:

SSR_1 &= ~(0x80);// TDRE=1 wait

134: }
135: /****************************************************************************/
136: /*

RsGetch0

RS232C(SCI0) 受信*/

137: /****************************************************************************/
138: short

RsGetch0()139: {
140:

Ushort time;

141:

Uchar

dt;

142:
143:

time = 0;144:

while((SSR_0 & 0x78) == 0) {/* RDRF+OE+FE+PE

ON ?

*/

145:

SoftWait1ms(1);/* 1ms*/146:

if (++time >= 20) return(-1);/* Error

*/

147:

}

148:

dt = RDR_0;

/* 受信

*/

149:

if (SSR_0 & 0x38) {/* SCI OE+FE+PE Error

*/

150:

SSR_0 &= 0x87;/* Error Reset

*/

151:

return(-1);/* Error Return*//* RDRF OFF

*/

152:

}

153:

SSR_0 &= ~(0x40);

154:

return(dt);155: }
156: /****************************************************************************/
157: /*

RsGetch1

RS232C(SCI1) 受信*/

158: /****************************************************************************/
159: short

RsGetch1()

160: {
161:

Ushort time;

162:

Uchar

dt;

163:
164:

time = 0;165:

while((SSR_1 & 0x78) == 0) {166:

SoftWait1ms(1);/* RDRF+OE+FE+PE/* 1ms

85

ON ?

*/
*/

167:

if (++time >= 20) return(-1);/* Error

*/

168:

}

169:

dt = RDR_1;

/* 受信

*/

170:

if (SSR_1 & 0x38) {/* SCI OE+FE+PE Error

*/

171:

SSR_1 &= 0x87;/* Error Reset

*/

172:

return(-1);/* Error Return*//* RDRF OFF

*/

173:

}

174:

SSR_1 &= ~(0x40);

175:

return(dt);176: }
177: /****************************************************************************/
178: /*

SciDemo()

ＵＳＡＲＴデモ*/179: /****************************************************************************/
180: void

SciDemo()181: {
182:

Uchar

dec[2+1];

183:

short

stat;

184:
185:

SciSequence();

186:

switch(SciStep) {187:

case 0:188:
189:/* SCI 操作ｺﾝﾄﾛｰﾙ*/

break;
case 1:

190:

RsOpen0(BpsTbl[SciSelect],8,NON);/* RS232C(SCI0) Open

*/

191:

RsOpen1(BpsTbl[SciSelect],8,NON);/* RS232C(SCI1) Open

*/

192:

GotoxyMemSet(0,0,"TxxRoxxRixx");

193:

TxDat = 0;

194:

SciStep++;

195:

break;/* 表示用送信データ作成(SCI0)*//* 送信(SCI0)

*/

196:

case 2:

197:

Bin2AhexN(dec,TxDat,2);198:

GotoxyMemSet(1,0,dec);

199:

RsPutch0(TxDat);

200:

SciStep++;

201:

break;

202:

case 3:86

203:

stat = RsGetch1();204:

if (stat == -1) strcpy(dec,"ee");

205:

else

206:

GotoxyMemSet(9,0,dec);

207:

SciStep++;

208:

break;

209:

Bin2AhexN(dec,stat,2);/* 表示用受信データ作成

RsPutch1(TxDat++);211:

SciStep++;

212:

break;/* 送信(SCI1)*/*/

case 5:214:

stat = RsGetch0();215:

if (stat == -1) strcpy(dec,"ee");

216:

else

217:

GotoxyMemSet(5,0,dec);

218:

SciStep = 2;219:

break;

220:*/

case 4:

210:

213:

/* Error/* Error

Bin2AhexN(dec,stat,2);/* 表示用受信データ作成

*/
*/

}

221: }
222: /****************************************************************************/
223: /*

SciSequence()

Usart 操作ｺﾝﾄﾛｰﾙ*/

224: /****************************************************************************/
225: void

SciSequence()

226: {
227:

Uchar

port;

228:

Uchar

dec[5+1];

229:
230:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

231:

if (port & 0xe) {/* PB[P31]->PB[P33] ON(立上) ?

*//* PB[PC2] ON ? 送信ｽﾀｰﾄ/ｽﾄｯﾌﾟ

*/

232:

if (port & 0x2) {233:

if (SciStep == 0) SciStep = 1;

234:

else

235:

}

236:

if (SciStep == 0) {

237:
238:

if (port & 0x4) {SciStep = 0;/* 停止中のみ受け付ける*//* PB[PC5] ON ? ﾎﾞﾚｰﾄ下げ?

*/

if (SciSelect != 0) --SciSelect;

87

239:

}

240:

else if (port & 0x8) {241:/* PB[PF7] ON ? ﾎﾞﾚｰﾄ上げ?

if (BpsTbl[SciSelect+1] != 0) ++SciSelect;

242:

}

243:

Bin2AdecN(dec,BpsTbl[SciSelect],5); /* 表示用データ作成

244:

GotoxyMemSet(0,1,dec);

245:
246:

*/

}
}

247: }

88*/

リストの説明に入る前に、ＳＣＩ関係資料を添付します。
チャネル

端子名

入出力

０

ＲＸＤ０
ＴＸＤ０
ＲＸＤ１
ＴＸＤ１

入力
出力
入力
出力

１

チャネル
０

機能
チャネル０の受信データ入力端子
チャネル０の送信データ出力端子
チャネル１の受信データ入力端子
チャネル１の送信データ出力端子

名 称

シンボル

シリアルモードレジスタ０
ビットレートレジスタ０
シリアルコントロールレジスタ０
トランスミットデータレジスタ０
シルアルステータスレジスタ０
レシーブデータレジスタ０
シリアルモードレジスタ１
ビットレートレジスタ１
シリアルコントロールレジスタ１
トランスミットデータレジスタ１
シルアルステータスレジスタ１
レシーブデータレジスタ１

１

ＳＭＲ＿０
ＢＲＲ＿０
ＳＣＲ＿０
ＴＤＲ＿０
ＳＳＲ＿０
ＲＤＲ＿０
ＳＭＲ＿１
ＢＲＲ＿１
ＳＣＲ＿１
ＴＤＲ＿１
ＳＳＲ＿１
ＲＤＲ＿１

アドレス
０ｘｆｆｆｆ７８
０ｘｆｆｆｆ７９
０ｘｆｆｆｆ７ａ
０ｘｆｆｆｆ７ｂ
０ｘｆｆｆｆ７ｃ
０ｘｆｆｆｆ７ｄ
０ｘｆｆｆｆ８０
０ｘｆｆｆｆ８１
０ｘｆｆｆｆ８２
０ｘｆｆｆｆ８３
０ｘｆｆｆｆ８４
０ｘｆｆｆｆ８５

表［６－２－１］ ＳＣＩの端子名とＩ／Ｏマップ
シリアルモードレジスタ（ＳＭＲ＿ｘ）
ﾋﾞｯﾄ 名前

初期値

R/W

７

C/A

０

R/W

０：調歩同期モード
１：クロック同期式モード

６

CHR

０

R/W

５

PE

０

R/W

４

O/E

０

R/W

０：データ長８ビット クロック同期では８ビット固定
１：データ長７ビット LSB ファースト固定
０：パリティディセーブル
１：パリティイネーブル
０：偶数パリティ（EVEN）
１：奇数パリティ（ODD）

３

STOP

０

R/W

０：１ストップビット
１：２ストップビット

２

MP

０

R/W

１
０

CKS1
CKS0

０
０

R/W

０：マルチプロセッサ通信ディセーブル
１：マルチプロセッサ通信イネーブル
内蔵ボーレートジェネレートのクロックソース選択
００：φクロック
０１：φ／４クロック
１０：φ／１６クロック
１１：φ／６４クロック機能

表［６－２－２］ シリアルモードレジスタ89シリアルコントロールレジスタ（ＳＣＲ＿ｘ）
ﾋﾞｯﾄ 名前

初期値

R/W

７

TIE

０

R/W

６

RIE

０

R/W

５

TE

０

R/W

４

RE

０

R/W

３

MPIE

０

R/W

２

TEIE

０

R/W

１
０

CKE1
CKE0

０
０

R/W

機能
０：ＴＸＩ割り込み要求ディセーブル
１：ＴＸＩ割り込み要求イネーブル
０：ＲＸＩ／ＥＲＩ割り込み要求ディセーブル
１：ＲＸＩ／ＥＲＩ割り込み要求イネーブル
０：送信動作不可
１：送信動作可能
０：受信動作不可
１：受信動作可能
マルチプロセッサインタラプトイネーブル
０：ＴＥＩ割り込み要求ディセーブル
１：ＴＥＩ割り込み要求イネーブル
クロックソースの選択
調歩同期の場合 ００：内部クロック
０１：内部クロック（ＳＣＫからビットレート出力）
１ｘ：外部クロック（ＳＣＫへ入力）

表［６－２－３］ シリアルコントロールレジスタ
シリアルステータスレジスタ（ＳＳＲ＿ｘ）
ﾋﾞｯﾄ 名前

初期値

R/W

７

TDRE

１

R/W

１：ＴＤＲからＴＳＲにデータ転送された時

６

RDRF

０

R/W

１：受信正常終了 ＲＳＲからＲＤＲへ受信データ転送完了

５

ORER

０

R/W

１：オーバランエラー発生

４

FER

０

R/W

１：フレミングエラー発生

３

PER

０

R/W

１：パリティエラー発生

２

TEND

１

R

１：送信データの最終ビットが送信された時

１

MPB

０

R

マルチプロセッサビット

０

MPBT

０

R/W

マルチプロセッサビットトランスファ

機能表［６－２－４］ シリアルステータスレジスタ

90［リストの説明］
１８～１９行：
調歩同期式モードでの通信時、指定ボーレートを得るためにビットレートレジスタへ与える数値を求める計算式の定義です。

ＢＲＲ値＝（（システムクロック／３２）／ボーレート）－１［ＳＭＲへの内蔵ボーレートジェネレータのクロックソースをゼロ（φクロック）とする］［システムクロック＝２０．０ＭＨｚ］［ボーレート＝４８００，９６００，１９２００，３１２５０，３８４００］
２６行：
送受信をコントロールする変数宣言です。
２７行：
ボーレートを選択する変数宣言です。
２８行：
送信データを記憶する変数宣言です。
２９行：
受信データを記憶する変数宣言です。
３０～３８行：
選択できるボーレートテーブルの変数宣言です。
４２～４６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
５０～５４行：
ＳＣＩ０を初期化する関数“ＲｓＯｐｅｎ０”を呼んでいます。
ＳＣＩ１を初期化する関数“ＲｓＯｐｅｎ１”を呼んでいます。
デフォルトで、９６００ｂｐｓ、８ビット、パリティＮＯＮの仕様にしています。
メインのＩ／Ｏ初期化の時に呼ばれます。
６２～８５行：
ＳＣＩ０を初期化する関数です。
重要 モジュールストップコントロールレジスタのＳＣＩ０をオフ（開始）することをお忘れなく！
次にこの関数は、３個の引数を持っています。
第１引数は、ボーレート［２４００，４８００，９６００，１９２００，３８４００］
第２引数は、キャラクタ長［７，８］第３引数は、パリティ［０＝ＮＯＮ（ディセーブル） １＝偶数 ２＝基数］
ストップビットは、１ビット固定とします。
［６７行］

91

モジュールストップコントロールレジスタのＳＣＩ０をオフ（開始）しています。
［６８行］
スマートカードインタフェースをディセーブルにしています。
［７０～７４行］
シリアルモードレジスタを設定するために、通信フォームの引数を分析して設定データを作成し設定しています。
［７６～８１行］
ビットレートレジスタを設定するために、調歩同期式モードでの通信ボーレートを得るための数値を求め設定しています。
［８２行］
１ビット送信経過時間以上待っています。
［８３行］
シリアルステータスレジスタの“ＲＤＲＦ”＋“ＯＲＥＲ”＋“ＦＥＲ”＋“ＰＥＲ”をリセットして
います。
［８４行］
シリアルコントロールレジスタの“ＴＥ”＋“ＲＥ”をイネーブルにしています。
９３～１１６行：
ＳＣＩ１を初期化する関数です。
重要 モジュールストップコントロールレジスタのＳＣＩ１をオフ（開始）することをお忘れなく！
ＳＣＩ０の初期化と同じですので省略します。
１２０～１２５行：
ＳＣＩ０の１バイトデータを送信する関数です。
１２９～１３４行：
ＳＣＩ１の１バイトデータを送信する関数です。
１３８～１５５行：
ＳＣＩ０の１バイトデータを受信する関数です。
ＲＤＲＦ（受信あり）か、受信エラーが発生するまで待つループには、２０ｍｓのソフトタイマーが入れてあります。
受信エラーが発生した場合は、エラーリセットコマンドを発行後、ｓｈｏｒｔ（－１）を返しています。
正常受信した場合は、受信データを呼び先へ返します。
１５９～１７６行：
ＳＣＩ１の１バイトデータを受信する関数です。
ＳＣＩ０の１バイトデータを受信と同じですので省略します。
１８０～２２１行：
ＳＣＩ０とＳＣＩ１の動作確認をするための関数です。
ＳＣＩ０／１の設定、１バイト送信、１バイト受信、送受信データの表示等を処理しています。

92

ＳＣＩ０（１バイト送信） ――――＞ ＳＣＩ１（１バイト受信）
ＳＣＩ１（１バイト送信） ――――＞ ＳＣＩ０（１バイト受信）の繰り返しをしています。
２２５～２４７行：
ＳＣＩの動作確認をする場合、ＰＢ操作のコントロールを管理する関数です。

93２）メインコントロール
file “Cat261p6.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p6.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

外部変数使用宣言*/

16: /****************************************************************************/
17: extern short

BuzzerHz;/* Buzzer Hz*/

18: extern Uchar

SciStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/

19: extern Uchar

SciSelect;/* ﾎﾞｰﾚｰﾄ選択*/

20: /****************************************************************************/
21: /*

変数宣言*/

22: /****************************************************************************/
23:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

24:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/

25: /****************************************************************************/
26: /*_main()*/

27: /****************************************************************************/
28: void_main(void)

29: {
30:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

31:

/*

NMI 立下りエッジ

*/

32:

/*

RAME 有効*/33:

SYSCR = 0x21;

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

94

*/

34:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

35:/* の 1 回リトライ時間分待つ(20 回)

*/

36:

MemInitial();/* ﾒﾓﾘ系初期化

*/

37:

IoInitial();/* I/O 系初期化

*/

38:

while(1) {39:

SigInput();/* Signal Input Process

*/

40:

SoftWait1ms(20);

/*

*/

41:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

42:

AllLcdDisp();/* LCD*/

43:

SigOutput();/* Signal Output Process(LED 点灯)

44:

ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り

全画面表示

*/

}

45: }
46: /****************************************************************************/
47: /*

Ｍｅｍ初期化*/

48: /****************************************************************************/
49: void

MemInitial(void)

50: {
51:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

52:

Shift = 0;/* Led Disp Patan Initial

*/

54:

PioMemInitial();/* PIOMem 初期化*/

55:

LcdMemInitial();/* LCDMem 初期化*/

56:

TimMemInitial();/* TIM

Mem 初期化*/

57:

SciMemInitial();/* SCIMem 初期化

*/

53:

58: }
59: /****************************************************************************/
60: /*

Ｉ／Ｏ初期化*/

61: /****************************************************************************/
62: void

IoInitial(void)

63: {
64:

PioIoInitial();/* PIOI/O 初期化*/

65:

LcdIoInitial();/* LCDI/O 初期化*/

66:

TimIoInitial();/* TIMI/O 初期化*/

67:

SciIoInitial();/* SCII/O 初期化*/

68: }
69: /****************************************************************************/

95

70: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

71: /****************************************************************************/
72: void

ModeCntrol()

73: {
74:

if (GetUpPort(1) & 0x1) {75:

if (ModeStep < 10)76:/* PB[PA0] ON?(立上)Goto TEST*/

else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST

*/

77:

else if (ModeStep < 30) ModeStep = 30;/* SCI

Goto TEST

*/

78:

else

/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

79:

Buzzer(0);/* 強制 OFF*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* PIOTEST*//* Timer TEST

*/

80:

}

81:

switch(ModeStep) {82:

case 0:ModeStep = 10;

ModeStep = 0;83:

GotoxyMemSet(0,0,"CAT261&AH6000 by");84:

GotoxyMemSet(0,1,"Polling

85:

ModeStep++;

86:

break;

87:[PA0]");

case 1:

88:

RunRun();89:

break;

90:

case 10:91:

GotoxyMemSet(0,0,"PIO

92:

GotoxyMemSet(0,1,"SW[P47]->SW[P40]");93:

ModeStep++;

94:

break;

95:");

case 11:96:

PioDemo();97:

break;

98:case 20:99:

GotoxyMemSet(0,0,"Timer/Counter

100:

GotoxyMemSet(0,1,"0000Hz[+PF7-PC5]");101:

BuzzerHz = 0;102:

ModeStep++;

103:

break;

104:
105:/* PIO*/");/* Buzzer Hz

case 21:
TimerDemo();

96

*/

106:

RunRun();107:

break;

108:

case 30:/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* SCI TEST

*/

109:

GotoxyMemSet(0,0,"SCI

110:

GotoxyMemSet(0,1,"09600b[+PF7-PC5]");111:

SciStep

112:

SciSelect = 1;

113:

ModeStep++;

114:

break;

115:= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/

case 31:116:

SciDemo();

117:

RunRun();118:

break;

119:

8,n,1[PC2]");}

120: }
121: /****************************************************************************/
122: /*

RunRun()

CPU 走行表示*/

123: /****************************************************************************/
124: void

RunRun()125: {
126:

if ((Shift <<= 1) == 0) Shift = 1;

127:

PutOutPort(Shift,'=');/* LED Shift 表示*/

128: }
129: /****************************************************************************/
130: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

131: /****************************************************************************/
132: void

SoftWait1ms(Ushort ms)

133: {
134:

while(ms-- != 0) {135:

Wait1ms();

136:

}

137: }
138: /****************************************************************************/
139: /*

SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/

140: /****************************************************************************/
141: void

SoftWait10us(Ushort us)97

142: {
143:

while(us-- != 0) {144:

Wait10us();

145:

}

146: }［リストの説明］ 前章のメインコントロールから追加された部分だけ解説します。
１８～１９行：
このモジュールで使用する外部変数宣言を追加しました。
５７行：“ＰｏｌＳｃｉ．ｃ”で使用する変数の初期化関数を呼んでいます。
６７行：
ＳＣＩを初期化する関数を呼んでいます。
１０８～１１８行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

以上で、この章の説明は終わりにします。
次は、ポーリングにおける総合デモ（メロディ）の解説へと進みます。

98

第 7 章 総合デモ（メロディ）

ここの章では、ポーリングでの総合デモ（メロディ）です。
評価ボードに付いているブザーを使い、チョットした演奏をします。

まずは、ＤＥＦのダウンロードで、￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ１＿Ｐｏｌｌｉｎｇ￥ＮＯ７＿Ｄｅｍｏ＿Ｍｅｌｏｄｙ￥Ｃａｔ２６１ｐ￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

移動したディレクトリの中に、“Ｃａｔ２６１ｐ．ＨＥＸ”というＨＥＸファイルがあります。
これをダウンロードしてから、プログラム実行してみて下さい。

どうです？ ＬＣＤにオープニングメッセージがでましたか？

もう馴れたと思いますので、ＬＣＤ表示の左上に“Ｍｅｌｏｄｙ”と表示がでるまで、
ＰＢ［ＰＡ０］を押して下さい。
ＬＣＤの下行 ＰＣ２［Ｍ］Ｆ７［ス］Ｃ５［セ］ と表示しているはずです。
ＰＣ２［Ｍ］は、マニュアルの意味です。

ＳＷ［Ｐ４０］－＞ＳＷＰ［４７］を、オン／オフしてみて下さい。
ド、レ、ミ……と音がするはずです。

ＰＢ［ＰＣ２］を押して下さい。
（モード変更）ＰＣ２［Ａ］と表示したはずです。
（Ａｕｔｏ演奏の意味）

99

ＰＢ［ＰＣ５］を押して下さい。
（選曲）
ネコフンジャッタ－＞イヌノオマワリサン－＞アマリリス（好きな曲で止めて下さい）

ＰＢ［ＰＦ７］を押して下さい（開始／停止）
演奏したはずです。
（音痴ですみません）

止めたい時は、どれかＰＢを長く押して下さい。
演奏の音の長さは、ポーリング記述のためソフトタイマを使用しています。
ソフトタイマ使用中は、他の処理は完全に停止してしまうため、ＰＢを長く押す必要があるわけです。
また、演奏中ＬＥＤが止まって見えるはずです、これもソフトタイマの影響です。
この現象を無くす方法は、第２部割込み編 で説明します。
この章では、総合デモ（メロディ）の簡単な説明をしたいと思います。

それでは、プログラムリストを見てみましょう！

２．プログラムリスト

このサンプルは、前章に１モジュール追加して、７ファイルの構成になっています。
“Ｓｔａｒｔｕｐ．ａｓｍ” 前章のまま使用したので解説を省略します。
“ＰｏｌＰｉｏ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＬｃｄ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＴｉｍｅ．ｃ”

前章のまま使用したので解説を省略します。

“ＣａｔＳｕｂ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＵｓａｒｔ．ｃ”

前章のまま使用したので解説を省略します。

“ＰｏｌＭｅｌｏｄｙ．ｃ” メロディのコントロール部です。
“Ｃａｔ２０４ｐ．ｃ”

メインコントロール部です。

100１）メロディのコントロール部
file “PolMelody.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

PolMelody.c*/

6: /* ＜役割＞

デモ メロディー関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.h"

14: #include"DemoCtl.h"

15: /****************************************************************************/
16: /*

音階 Hz*/

17: /****************************************************************************/
18: #define dO

262/* _ド */

19: #define rE

293/* _ﾚ */

20: #define mI330/* _ﾐ */

21: #define fhA

349/* _ﾌｧ */22: #define sO392/* _ｿ */

23: #define rA

440/* _ﾗ */

24: #define sI494/* _ｼ */

25: #define do523/* ド */

26: #define re

587

/* ﾚ

*/

27: #define mi

659

/* ﾐ

*/

28: #define fha

698/* ﾌｧ */

29: #define so

784

/* ｿ

*/

30: #define ra

880

/* ﾗ

*/

31: #define si

987

/* ｼ

*/

32: #define Do

1047/* ド */

33:101

34: #define SCMAX

32/* 楽譜テーブルの最大数*/

35: /****************************************************************************/
36: /*

変数宣言*/

37: /****************************************************************************/
38:

Uchar

MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

39:

Uchar

MelMode;/* 演奏ﾓｰﾄﾞ

*/

40:

Uchar

MelSelect;/* 自動選曲*/

41:

UshortMelodyHz;/* Melody Hz

*/

42:

Uchar

Music;/* 自動演奏ｶｳﾝﾀｰ

*/

43:

UshortDoremi[SCMAX];/* ﾄﾞﾚﾐ音階周波数(Hz)の RAM 側

*/

44:

UshortRhythm[SCMAX];/* ﾘｽﾞﾑ(msec)*/

45: const

UshortDoremiTbl[] =/* ﾄﾞﾚﾐ音階周波数(Hz)

*/

47:

do,

/* ド */48:

re,/* ﾚ */

49:mi,/* ﾐ */

50:fha,/* ﾌｧ */

51:so,/* ｿ */

52:ra,/* ﾗ */

53:si,/* ｼ */

54:

Do,/* ド */

55:

0

46: {

56: };
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

UshortRhythmTbl[3][SCMAX] =/* 自動演奏のリズム(最大 32 ﾏﾃﾞ） */

68: {
69:

/* ﾈｺﾌﾝｼﾞｬｯﾀ{250,250,500,500,500,250,250,500,500,500,

102

*/

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: /****************************************************************************/
87: void

MelMemInitial(void)

88: {
89:

MelStep= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

90:

MelMode= 0;/* 演奏ﾓｰﾄﾞ*/

91:

MelSelect = 0;/* 自動選曲*/

92:

MelodyHz = 0;/* Melody Min Hz

*/

93: }
94: /****************************************************************************/
95: /*

Ｉ／Ｏ初期化*/

96: /****************************************************************************/
97: void

MelIoInitial(void)

98: {
99:

Buzzer(0);/* Buzer OFF*/

100: }
101: /****************************************************************************/
102: /*

Melodyﾒﾛﾃﾞｨｰｺﾝﾄﾛｰﾙ*/

103: /****************************************************************************/
104: void

Melody()105: {

103

106:

MelodySequence();/* ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ

*/

107:

if (MelMode == 0) ManualMelody();/* 手動演奏

*/

108:

else

/* 自動演奏*/

AutoMelody();

109: }
110: /****************************************************************************/
111: /*

MelodySequence()

ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/

112: /****************************************************************************/
113: void

MelodySequence()

114: {
115:

Uchar

port;

116:
117:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

118:

if (port & 0xe) {/* PB[PC2]->PB[PF7] ON(立上) ?

*/

119:

Buzzer(0);/* Buzer OFF

*/

120:

if (port & 0x2) {/* PB[PC2] ON ? ﾓｰﾄﾞ変更

*/

121:

MelStep = 0;/* 強制停止*/122:

if (MelMode == 0) {/* 現在手動 ?

*//* 自動に変更*//* 自動選曲*//* 現在自動 ?

*//* 手動に変更*//* 自動選曲*//* 自動 ?

*//* PB[PC5] ON ? 選曲*//* 強制停止*/123:

MelMode124:

MelSelect = 1;

125:

}

126:

else {= 1;

127:

MelMode128:

MelSelect = 0;

129:

= 0;

}

130:

}

131:

if (MelMode != 0) {132:

if (port & 0x4) {133:

MelStep = 0;134:

if (++MelSelect > 3) MelSelect = 1;

135:

}

136:

if (port & 0x8) {/* PB[PF7] ON ? 自動演奏開始

*/

137:

if (MelStep == 0) MelStep = 1;

/* 開始

*/

138:

else

/* 停止

*/

139:

Music

140:
141:

MelStep = 0;
= 0;

}
}

104

142:

if (MelMode == 0) GotoxyMemSet(4,1,"M");/* 手動表示

*/

143:

else

/* 自動表示*/144:

GotoxyMemSet(7,0,(Uchar *)MelodyTblA[MelSelect]);

145:

GotoxyMemSet(4,1,"A");/* 曲名表示*/}146: }
147: /****************************************************************************/
148: /*

ManualMelody

手動ﾒﾛﾃﾞｨｰ演奏*/

149: /****************************************************************************/
150: void

ManualMelody()

151: {
152:

Uchar

port;

153:
154:

switch(MelStep) {155:

case 0:156:_strcpyW(Doremi,(Ushort *)DoremiTbl);

157:

MelodyHz = 0;

158:

MelStep++;

159:

break;

160:/* Melody Min Hz*//* P40->P47 どれかがＯＮしたか？

*//* SW[P40] 立上がり ON (ド)*/case 1:161:

if (GetInPort(0) & 0xff) {162:

port = GetUpPort(0);163:

if (port & 0x1) {164:

Buzzer(MelodyHz = Doremi[7]);

165:

}

166:

else if (port & 0x2) {167:/* SW[P41] 立上がり ON (レ)*/Buzzer(MelodyHz = Doremi[6]);

168:

}

169:

else if (port & 0x4) {170:/* SW[P42] 立上がり ON (ミ)*/Buzzer(MelodyHz = Doremi[5]);

171:

}

172:

else if (port & 0x8) {173:/* SW[P43] 立上がり ON (ファ)*/Buzzer(MelodyHz = Doremi[4]);

174:

}

175:

else if (port & 0x10) {

176:
177:

/* ﾄﾞﾚﾐ音階周波数(初期準備) *//* SW[P44] 立上がり ON (ソ)Buzzer(MelodyHz = Doremi[3]);
}

105

*/

178:

else if (port & 0x20) {

179:

*/

Buzzer(MelodyHz = Doremi[2]);

180:

}

181:

else if (port & 0x40) {182:/* SW[P46] 立上がり ON (シ)*/Buzzer(MelodyHz = Doremi[1]);

183:

}

184:

else if (port & 0x80) {185:/* SW[P47] 立上がり ON (ド)*/Buzzer(MelodyHz = Doremi[0]);

186:

}

187:

}

188:

else if (MelodyHz != 0) {189:

Buzzer(MelodyHz = 0);

190:

}

191:

break;

192:/* SW[P45] 立上がり ON (ラ)/* Buzzer 停止*/}

193: }
194: /****************************************************************************/
195: /*

AutoMelody

自動ﾒﾛﾃﾞｨｰ演奏*/

196: /****************************************************************************/
197: void

AutoMelody()

198: {
199:

switch(MelStep) {200:

case 0:201:
202:

break;
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 {

106

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: }

107

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

108２）メインコントロール
file “Cat261p.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ ポーリング

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

外部変数使用宣言*/

16: /****************************************************************************/
17: extern short

BuzzerHz;/* Buzzer Hz*/

18: extern Uchar

SciStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/

19: extern Uchar

SciSelect;/* ﾎﾞｰﾚｰﾄ選択*/

20: extern Uchar

MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/

21: extern Uchar

MelMode;/* 演奏ﾓｰﾄﾞ*/

22: extern Uchar

MelSelect;/* 自動選曲*/

23: /****************************************************************************/
24: /*

変数宣言*/

25: /****************************************************************************/
26:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

27:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/28: /****************************************************************************/
29: /*_main()*/

30: /****************************************************************************/
31: void_main(void)

32: {
33:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

109

*/

34:

/*

NMI 立下りエッジ

*/

35:

/*

RAME 有効*/36:

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

37:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

38:/* の 1 回リトライ時間分待つ(20 回)

*/

39:

MemInitial();/* ﾒﾓﾘ系初期化

*/

40:

IoInitial();/* I/O 系初期化

*/

41:

while(1) {42:

SigInput();/* Signal Input Process

*/

43:

SoftWait1ms(20);

/*

*/

44:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

45:

AllLcdDisp();/* LCD*/46:

SigOutput();/* Signal Output Process(LED 点灯)

47:

ﾎﾟｰﾘﾝｸﾞ用 20ms ﾁｬﾀ取り

全画面表示

*/

}

48: }
49: /****************************************************************************/
50: /*

Ｍｅｍ初期化*/

51: /****************************************************************************/
52: void

MemInitial(void)

53: {
54:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

55:

Shift = 0;/* Led Disp Patan Initial

*/

57:

PioMemInitial();/* PIOMem 初期化*/

58:

LcdMemInitial();/* LCDMem 初期化*/

59:

TimMemInitial();/* TIM

Mem 初期化*/

60:

SciMemInitial();/* SCIMem 初期化*/

61:

MelMemInitial();/* Melody Mem 初期化

*/

56:

62: }
63: /****************************************************************************/
64: /*

Ｉ／Ｏ初期化*/

65: /****************************************************************************/
66: void

IoInitial(void)

67: {
68:

PioIoInitial();/* PIOI/O 初期化*/

69:

LcdIoInitial();/* LCDI/O 初期化

*/

110

70:

TimIoInitial();/* TIMI/O 初期化*/

71:

SciIoInitial();/* SCII/O 初期化*/

72:

MelIoInitial();/* Melody I/O 初期化

*/

73: }
74: /****************************************************************************/
75: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

76: /****************************************************************************/
77: void

ModeCntrol()

78: {
79:

if (GetUpPort(1) & 0x1) {80:

if (ModeStep < 10)81:/* PB[PA0] ON?(立上)Goto TEST*/

else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST

*/

82:

else if (ModeStep < 30) ModeStep = 30;/* SCI*/83:

else if (ModeStep < 40) ModeStep = 40;/* Demo Melody

*/

84:

else

/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

85:

Buzzer(0);/* 強制 OFF*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* PIOTEST*//* Timer TEST

*/

86:

}

87:

switch(ModeStep) {88:case 0:ModeStep = 10;

ModeStep = 0;89:

GotoxyMemSet(0,0,"CAT261&AH6000 by");90:

GotoxyMemSet(0,1,"Polling

91:

ModeStep++;

92:

break;

93:

RunRun();95:

break;[PA0]");

case 10:97:

GotoxyMemSet(0,0,"PIO

98:

GotoxyMemSet(0,1,"SW[P47]->SW[P40]");99:

ModeStep++;100:

break;

101:

PioDemo();103:

break;

105:");

case 11:

102:

104:

Goto TEST

case 1:

94:

96:/* PIO*/case 20:
GotoxyMemSet(0,0,"Timer/Counter

");

111

106:

GotoxyMemSet(0,1,"0000Hz[+PF7-PC5]");107:

BuzzerHz = 0;108:

ModeStep++;

109:

break;

110:*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* SCI TEST*/

case 21:111:

TimerDemo();112:

RunRun();113:

break;

114:/* Buzzer Hz

case 30:

115:

GotoxyMemSet(0,0,"SCI

116:

GotoxyMemSet(0,1,"09600b[+PF7-PC5]");

117:

SciStep

118:

SciSelect = 1;

119:

ModeStep++;

120:

break;

121:= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* Demo Melody*/

case 31:122:

SciDemo();123:

RunRun();124:

break;

125:

8,n,1[PC2]");case 40:

126:

GotoxyMemSet(0,0,"Melody

127:

GotoxyMemSet(0,1,"PC2[M]F7[ｽ]C5[ｾ]");128:

MelStep= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

129:

MelMode= 0;/* 演奏ﾓｰﾄﾞ

*/

130:

MelSelect = 0;/* 自動選曲*/

131:

ModeStep++;

132:

break;

133:

case 41:

134:

Melody();135:

RunRun();136:

break;

137:

");

}

138: }
139: /****************************************************************************/
140: /*

RunRun()

CPU 走行表示*/

141: /****************************************************************************/

112

142: void

RunRun()143: {
144:

if ((Shift <<= 1) == 0) Shift = 1;

145:

PutOutPort(Shift,'=');/* LED Shift 表示*/

146: }
147: /****************************************************************************/
148: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

149: /****************************************************************************/
150: void

SoftWait1ms(Ushort ms)

151: {
152:

while(ms-- != 0) {153:

Wait1ms();

154:

}

155: }
156: /****************************************************************************/
157: /*

SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/

158: /****************************************************************************/
159: void

SoftWait10us(Ushort us)

160: {
161:

while(us-- != 0) {162:

Wait10us();

163:

}

164: }

113

［リストの説明］

前章のメインコントロールから追加された部分だけ解説します。

２０～２２行：
このモジュールで使用する外部変数宣言を追加しました。
６１行：“ＰｏｌＭｅｌｏｄｙ．ｃ”で使用する変数の初期化関数を呼んでいます。
７２行：“ＰｏｌＭｅｌｏｄｙ．ｃ”で使用するＩ／Ｏを初期化する関数を呼んでいます。
１２５～１３６行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

これで、この章のリスト説明は終わりです。

自動演奏曲“ネコフンジャッタ”を聞いて気がついた方もいらしゃるかと思いますが、半音の登録をしていないため、チョット編曲をしてしまいました。
興味の有る方は、半音登録をして作りなおしてみて下さい。
これも、プログラムに慣れ親しむ方法として、よいことかもしれません。

この章の前半でも説明しましたが、全てポーリングで作成しているため動作および反応が鈍い部分があります。
このままで市場に出したらクレームになってしまいます。
この動作を改善するために、第２部 割込み編より修正を進めていきたいと思います。

114

第２部 割込み編
第１章 タイマ割込み

割り込みモード２は、Ｈ－ｄｅｂａｇｇｅｒがＨ８Ｓ／２６１２のハードトレース機能を使用するにあたり必要なモードです。
（他のモードでは、ハードトレースが機能しません）
それとＣＰＵ内部機能のＰＢＣ（ＰＣブレークコントローラ）とを組み合わせてデバッグ可能にしています。
（割り込みモード０の場合は、ソフトトレースとＰＢＣの組み合わせになります。
）
最初の章からＣＰＵに対して割り込みモード２の設定と割り込み要求マスクレベル（６以下）の設定は済んでいます。
（ＰＢＣ割り込みのプライオリティが７の為）
この章では、割り込みモード２を使用したアプリケーションをどのような手続きで追加するかをリストに沿って説明を進めていきます。
割り込み要因として、
ＴＰＵ＿０での連続コンペアマッチにおける１０ｍｓ毎割り込み例を使用しました。
なお、改造するサンプルの元は、“第１部ポーリング編－第７章総合デモ”で作成したサンプルを使用します。

動作仕様の変更はしませんので、この部より動作説明は省略します。
ＨＥＷの［Ｐｒｏｊｅｃｔ］－［Ｓｅｔ Ｃｕｒｒｅｎｔ Ｐｒｏｊｅｃｔ］－［Ｃａｔ２６１ｉ１］をクリックして、プロジェクトの変更をしておいて下さい。

＜補足説明＞
１）ハードトレースとは、ＣＰＵ機能が持っているトレース割り込みを利用した機能です。ただしこの機能を利用する場合は、割り込みモードを「２」にする必要があります。
２）ソフトトレースとは、ソフトにより次の実行命令を判定した後、ＰＢＣに次命令のアドレスを設定したトレース機能になります。このソフトトレースはＰＢＣ搭載したＣＰＵで、割り込みモー
ド０の場合とハードトレース機能が無い場合に使用します。

115

１．ベクターテーブルをタイマ割り込み用に変更する。

Ｈ８Ｓシリーズは、
すべての割り込み要因に対し独立したベクタアドレスが割り当てられていますので、要因別ベクタテーブルへの登録が必要になります。
又，モジュール別のインタラプトプライオリティレジスタも持っていますのでこの設定も必要になります。
リストの説明に入る前にインタラプトプライオリティレジスタ関連と、割り込み要求マスクレベルとの関係について説明します。

１）割り込みモード２の設定
システムコントロールレジスタ（ＳＹＳＣＲ）
ﾋﾞｯﾄ 名前

初期値

R/W

７

MACS

１

R/W

ＭＡＣサチュレーション

６

-

０

-

リザーブビット

５
４

INTM1
INTM0

０
０

R/W
R/W

００：割り込み制御モード０
０１：禁止
１０：割り込み制御モード２
１１：禁止

３

NMIEG

０

R/W

２
１

-

０
０

-

０：ＮＭＩ立下りで受け付け
１：ＮＭＩ立上りで受け付け
リザーブビットリザーブビット

０

RAME

１

R/W

機能

０：内蔵ＲＡＭ無効
１：内蔵ＲＡＭ有効表［２・１－１－１］

２）割り込み要求マスクレベルの設定
ＣＰＵ内部のエクステンドレジスタ（ＥＸＲ）に設定
ﾋﾞｯﾄ 名前

初期値

R/W

７

T

０

R/W

トレースビット

6~3

-

１

-

リザーブビット

２
１
０

I2
I1
I0

１
１
１

R/W
R/W
R/W

割り込み要求マスクレベル（０～７）を指定します。

機能

表［２・１－１－２］

116３）インタラプトプライオリティの設定
レジスタ名
ＩＰＲＡ

７
０

６～４
ＩＲＱ０ （０～７）の設定

ＩＰＲＢ

０

ＩＲＱ２
ＩＲＱ３ （０～７）の設定

ＩＰＲＣ
ＩＰＲＤ

０
０

ＩＰＲＥ

０

ＩＰＲＦ

ＷＯＶＩ０（０～７）の設定

ビット
３
０
０
０
０

２～０
ＩＲＱ１ （０～７）の設定
ＩＲＱ４
ＩＲＱ５ （０～７）の設定
ＤＴＣ（０～７）の設定

０

ＡＤＩ

０

ＰＣＢ
（７）
の設定
（H-debugger 使用する）
ＴＰＵ＿０（０～７）の設定（０～７）の設定

０

ＴＰＵ＿１（０～７）の設定

ＩＰＲＧ

０

ＴＰＵ＿２（０～７）の設定

０

ＴＰＵ＿３（０～７）の設定

ＩＰＲＨ
ＩＰＲＪ

０
０

ＴＰＵ＿４（０～７）の設定

００ＴＰＵ＿５（０～７）の設定
ＳＣＩ＿０（０～７）の設定

ＩＰＲＫ

０

ＳＣＩ＿１（０～７）の設定

０

ＳＣＩ＿２（０～７）の設定

ＩＰＲＭ

０

ＨＣＡＮ （０～７）の設定

０ＭＭＴ（０～７）の設定

表［２・１－１－３］ ＩＰＲｘ
(1)ＥＸＲレジスタ”６”の状態で、ＰＢＣ以外の割り込みを不許可にしたい場合は、プライオリティ
を”６”もしくは各モジュールで割り込みをマスク状態にして下さい。
(2)ＥＸＲレジスタ”0”にしますと、全割り込み許可状態になります。

４）割り込み制御モード２の割り込み受け付けシーケンス
割り込み発生（要因 インタラプトプライオリティ）｛ｉｆ（割り込み ＝＝ ＮＭＩ）

割り込み受け付け（）；

ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ ７） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ６） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ ６） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ５） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
＜一部省略＞
ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ １） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ０） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
｝
117

１）ベクターテーブルの変更箇所
file “StartupA.asm”
1: ;/****************************************************************************/
2: ;/* ＜サンプル＞ ポーリング*/

3: ;/**/

4: ;/*＜MOD＞

StartupA.asm*/

5: ;/*

＜役割＞

main

*/

6: ;/*

＜タブ＞

４タブ編集

7: ;/*(ルネサス純正Ｃ用)*/

スタートアップ (CAT261-H8S/2612)*/

8: ;/****************************************************************************/
9:.global_StartUp,_non10:.global_Wait1ms,_Wait10us

11:.IMPORT__main

12:.IMPORT_UserTGIA0＜＜＜ 省略 ＞＞＞
25: ;********************************************************
26: ;* ベクターテーブル
27: ;********************************************************
28:.section

VECT,CODE,LOCATE=0

29: _VectorTable:;(共通/213x)(26xx)

30:

VECTOR_StartUp;* VCT( 0) RESET|

31:

VECTOR_non;* VCT( 1) System 予約 1|＜＜＜ 省略 ＞＞＞
60:

VECTOR_non;* VCT( 30) ﾘｻﾞｰﾌﾞ|

61:

VECTOR_non;* VCT( 31) ﾘｻﾞｰﾌﾞ|

62:

VECTOR_UserTGIA0;* VCT( 32) ﾘｻﾞｰﾌﾞ|TPU_0 TGIA_0

63:

VECTOR_non;* VCT( 33) ﾘｻﾞｰﾌﾞ|＜＜＜ 省略 ＞＞＞
192:

.end

［リストの説明］
６２行：
ＴＰＵ＿０のＴＧＩＡ＿０コンペアマッチ割り込み要因処理のＣ言語関数“ＵｓｅｒＴＧＩＡ０（）”のアドレスを登録しました。

118

TGIB_0２）割り込みハンドラモジュールの追加
file “IntrHand.c”
1: /****************************************************************************/
2: /* ＜サンプル＞

割り込み

*/

3: /*

*/

4: /*

＜MOD＞

IntrHand.c

5: /*

＜タブ＞

４タブ編集

6: /*

＜保守ﾂｰﾙ＞ AHE261_HEW.hws

7: /*(ルネサス純正Ｃ用)

*/
*/
*/

割り込みハンドラ (CAT261-H8S/2612)*/

8: /****************************************************************************/
9: #include"io261x.h"

10: /****************************************************************************/
11: /*

UserTGIA0*/

12: /****************************************************************************/
13: #pragma interrupt UserTGIA0
14: #pragma regsave
15: void

UserTGIA0

UserTGIA0()

16: {
17:

TimerA0();

18: }［リストの説明］
１３～１８行：
ＴＧＩＡ＿０コンペアマッチ割り込みハンドラ関数になります。
割り込み例外処理を示す“＃ｐｒａｇｍａ ｉｎｔｅｒｒｕｐｔ”と“＃ｐｒａｇｍａ ｒｅｇｓａｖｅ”を定義することのよ
り、関数の入口／出口に全レジスターの退避／復帰命令が挿入され、かつリターン命令が“ＲＴＥ”になる便利な定義です。
これがＣ言語用記述での割り込みハンドラ雛型になります。

119

２．タイマモジュールを割り込み用に変更する。
ＴＰＵ＿０での連続コンペアマッチにおける１０ｍｓ毎割り込みを使用する場合、ＴＰＵ＿０の初期設定が必要になります。
また、割り込みハンドラから呼ばれる関数“ＴｉｍｅｒＡ０（）”も追加しました。
この関数は、タイマー割り込みを利用した内部ソフトタイマー機能を処理する役割になります。

リストの説明に入る前に、ＴＰＵ＿０関係資料を添付します。
タイマスタートレジスタ（ＴＳＴＲ）
ﾋﾞｯﾄ 名前

初期値

R/W

７
６
５
４
３
２
１
０

０
０
０
０
０
０
０
０

－

リザーブ

R/W
R/W
R/W
R/W
R/W
R/W

ＴＰＵ＿５
ＴＰＵ＿４
ＴＰＵ＿３
ＴＰＵ＿２
ＴＰＵ＿１
ＴＰＵ＿０

－
CST5
CST4
CST3
CST2
CST1
CST0

機能

０：カウンターをストップします
１：カウンターをスタートします表［２・１－２－１］ ＴＳＴＲ
タイマコントロールレジスタ（ＴＣＲ＿０）
ﾋﾞｯﾄ 名前

初期値

R/W

７
６
５

CCLR2
CCLR1
CCLR0

０
０
０

R/W
R/W
R/W

４
３

CKEG1
CKEG0

０
０

R/W
R/W

２
１
０

TPSC2
TPSC1
TPSC0

０
０
０

R/W
R/W
R/W

機能
０００：ＴＣＮＴ＿０のクリア禁止
００１：ＴＧＲＡ＿０のコンペアマッチでＴＣＮＴ＿０クリア
０１０：ＴＧＲＢ＿０のコンペアマッチでＴＣＮＴ＿０クリア
０１１：同期クリア／同期動作をしている他のクリアでクリア
１００：ＴＣＮＴ＿０のクリア禁止
１０１：ＴＧＲＣ＿０のコンペアマッチでＴＣＮＴ＿０クリア
１１０：ＴＧＲＤ＿０のコンペアマッチでＴＣＮＴ＿０クリア
１１１：同期クリア／同期動作をしている他のクリアでクリア
００：立上りエッジでカウント
０１：立下りエッジでカウント
１ｘ：両エッジでカウント
ＴＣＮＴ＿０のカウンタクロックソースの選択
０００：内部 φクロック
００１：
φ／４クロック
０１０：
φ／１６クロック
０１１：
φ／６４クロック
１００：外部 ＴＣＬＫＡ端子入力でカウント
１０１：
ＴＣＬＫＢ端子入力でカウント
１１０：
ＴＣＬＫＣ端子入力でカウント
１１１：
ＴＣＬＫＤ端子入力でカウント

表［２・１－２－２］ ＴＣＲ＿０

120タイマインタラプトイネーブルレジスタ（ＴＩＥＲ＿０）
ﾋﾞｯﾄ 名前

初期値

R/W

７

TTGE

０

R/W

６

－

１

－

５

TCIEU

０

R/W

４

TGIEV

０

R/W

３

TGIED

０

R/W

２

TGIEC

０

R/W

１

TGIEB

０

R/W

０

TGIEA

０

R/W

機能
Ａ／Ｄ変換開始要求イネーブル
０：Ａ／Ｄ変換開始要求禁止
１：Ａ／Ｄ変換開始要求許可
リザーブビット
ＴＰＵ＿１，２，４，５のアンダーフローイネーブル
０：ＴＣＦＵによる要求禁止
１：ＴＣＦＵによる要求許可
オーバーフローイネーブル
０：ＴＣＦＶによる要求禁止
１：ＴＣＦＶによる要求許可
ＴＰＵ＿０，３のＴＧＲＤ割込み要求イネーブル
０：ＴＧＦＤによる要求禁止
１：ＴＧＦＤによる要求許可
ＴＰＵ＿０，３のＴＧＲＣ割込み要求イネーブル
０：ＴＧＦＣによる要求禁止
１：ＴＧＦＣによる要求許可
ＴＧＲＢ割込み要求イネーブル
０：ＴＧＦＢによる要求禁止
１：ＴＧＦＢによる要求許可
ＴＧＲＡ割込み要求イネーブル
０：ＴＧＦＡによる要求禁止
１：ＴＧＦＡによる要求許可表［２・１－２－３］ ＴＩＥＲ＿０
タイマステータスレジスタ（ＴＳＲ＿０）
ﾋﾞｯﾄ 名前

初期値

R/W

７

TCFD

１

R

ＴＣＮＴのカウント方向フラグ
０：ダウンカウント １：アップカウント

６

－

１

－

リザーブビット

５

TCFU

０

R/W

４

TCFV

０

R/W

１（Ｒ）
：アンダーフローによる要求フラグです。
０（Ｗ）：要求フラグ解除になります。
１（Ｒ）：オーバーフローによる要求フラグです。
０（Ｗ）：ＴＣＦＶによる要求解除になります。

３

TGFD

０

R/W

２

TGFC

０

R/W

１

TGFB

０

R/W

０

TGFA

０

R/W

機能

１（Ｒ）
：ＴＰＵ＿０，３のＴＧＲＤによる要求フラグです。
０（Ｗ）：ＴＧＦＤによる要求解除になります。
１（Ｒ）：ＴＰＵ＿０，３のＴＧＲＣによる要求フラグです。
０（Ｗ）：ＴＧＦＣによる要求解除になります。
１（Ｒ）：ＴＧＲＢによる要求フラグです。
０（Ｗ）：ＴＧＦＢによる要求解除になります。
１（Ｒ）：ＴＧＲＡによる要求フラグです。
０（Ｗ）：ＴＧＦＡによる要求解除になります。

表［２・１－２－４］ ＴＳＲ＿０

121１）プログラムリスト
file “IntrTime.c”
1: /****************************************************************************/
3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrTime.c*/

6: /* ＜役割＞

タイマ関係

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.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));122

36: }
37: /****************************************************************************/
38: /*

Ｉ／Ｏ初期化*/

39: /****************************************************************************/
40: void

TimIoInitial(void)

41: {
42:

MSTPCRA &= ~0x20;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ TPU ｽﾀｰﾄ

*/

43:

IPRF

= 0x57;/* TPU_0 ﾌﾟﾗｲｵﾘﾃｨ 5

*/

44:

TCR_0

= 0x21;/*TGRA ｺﾝﾍﾟｱﾏｯﾁで TCNT ｸﾘｱ 001 */

45:

/*

立上りｴｯｼﾞ

00 */

46:

/*

sys/4(5,000,000Hz)

001 */

47:

TIER_0= 1;/*

TGIEA=1 TGRA により割込み

*/

48:

TCNT_0= 0;/*

TCNT=0*/49:

TGRA_0= 50000;/*(20000000/4)/50000=100(Hz) */

50:

TSTR

|= 1;

/*

TCNT0 ｶｳﾝﾄ動作

*/

51: }
52: /****************************************************************************/
53: /*

Buzzer

TPU_3 TIOCA3 出力に Buzzer 接続 sys = 20,000,000Hz*/

54: /****************************************************************************/
55: void

Buzzer(Ushort hz)

56: {
57:

Ushort

cyc;

58:
59:

if ((hz >= BZMIN) && (hz <= BZMAX)) {60:

TCR_3 = 0x21;/* Buzzer ON*//* CNTL TGRA ｺﾝﾍﾟｱﾏｯﾁで TCNT ｸﾘｱ

001 */

61:/*

立上りｴｯｼﾞ

00 */

62:

/*

sys/4(5,000,000Hz)

001 */

63:

TMDR_3 = 0xc2;

64:
65:

TIORH_3 = 3;

66:/* MODE Default

1100 *//*

0010 */PWM ﾓｰﾄﾞ 1/* I/O TGRB 未使用

0000 *//*

0011 */TIOCA3 ﾏｯﾁﾄｸﾞﾙ出力67:

cyc = 5000000 / hz;/* 周期の計算*/

68:

TGRA_3 = cyc / 2;/* 周期設定/2*/

69:

TCNT_3 = 0;/* ｶｳﾝﾄｸﾘｱ

*/

70:

TSTR |= 0x8;/* TCNT_3 ｽﾀｰﾄ

*/

71:

}

123

72:

else {/* Buzzer OFF

*/

73:

TCNT_3 = 0;/* ｶｳﾝﾄｸﾘｱ

*/

74:

TSTR &= ~0x8;/* TCNT_3 ｽﾄｯﾌﾟ

*/

75:

}

76: }
77: /****************************************************************************/
78: /*

TmStart*/79: /****************************************************************************/
80: void

TmStart(short tno,short ms)

81: {
82:

Ushort cnt;

83:
84:

cnt = ms / 10;/* 単位 10ms に修正する

85:

TmUp[tno] = OFF;86:

TmCnt[tno] = cnt;

87:

TmSt[tno] = ON;

*/

88: }
89: /****************************************************************************/
90: /*

TmUpTest

ﾀｲﾏ UP ﾌﾗｸﾞﾃｽﾄ*/

91: /****************************************************************************/
92: Uchar

TmUpTest(short tno)

93: {
94:

return(TmUp[tno]);95: }
96: /****************************************************************************/
97: /*

ＴＭＡ0 タイマー割り込み（10ms） 割り込みハンドラより呼ばれる*/

98: /****************************************************************************/
99: void

TimerA0(void)

100: {
101:

short

i;

103:

TSR_0 &= ~(1);/* TGFA=0(ｺﾝﾍﾟｱﾌﾗｸﾞ Reset)

*/

105:

for(i = 0;i < TMMAX;i++) {/* 内部タイマー処理

*/

106:

if (TmSt[i] == ON) {107:

if (--TmCnt[i] == 0) {108:

TmUp[i] = ON;

109:

TmSt[i] = OFF;

124

110:

}

111:
112:

}
}

113: }
114: /****************************************************************************/
115: /*

TimerDemo

Timer デモ*/116: /****************************************************************************/
117: void

TimerDemo()

118: {
119:

Uchar

port;

120:

Uchar

dec[4+1];

121:
122:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

123:

if (port & 0xc) {/* PB[PC5] | PB[PF7] ON ?

*//* PB[-PC5] ON-立上り*//* PB[+PF7] ON-立上り

*/

124:

if (port & 0x4) {125:

BuzzerHz -= 100;

126:

}

127:

else if (port & 0x8) {128:

BuzzerHz += 100;

129:

}

130:

if (BuzzerHz < BZMIN) BuzzerHz = BZMIN;

131:

if (BuzzerHz > BZMAX) BuzzerHz = BZMAX;

132:

Buzzer(BuzzerHz);

133:

Bin2AdecN(dec,BuzzerHz,4);134:

GotoxyMemSet(0,1,dec);135:/* 表示用データ作成}

136: }

125*/

［リストの説明］ 前章から変更のあった部分をおもに解説します。
２４～２６行：
タイマー割り込みを利用した内部ソフトタイマー処理を追加しましたので、その処理に使用するフラグ
およびカウンタの役目をする変数を宣言する。
３０～３６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
４０～５１行：
タイマ／カウンタを初期化する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ここでは、ＴＰＵ＿０とＩＰＲＦの初期化設定をします。
［４２行］
モジュールストップコントロールレジスタのＴＰＵをオフ（スタート）しています。
［４３行］
ＴＰＵ＿０のインタラプトプライオリティを“５”に設定しています。
別に意味はありません“６”以下でしたら構いません。
表［２・１－１－３］参照［４４行］
タイマコントロールレジスタの初期設定をしています。
１）ＴＧＲＡコンペアマッチでＴＣＮＴ＿０をクリアする。
２）立上りエッジでカウントする。
３）システムクロック（２０ＭＨｚ）の１／４でカウントする
表［２・１－２－２］参照［４７行］
タイマインタラプトイネーブルレジスタの設定をしています。
１）ＴＧＲＡのＴＧＦＡビットによる割り込み要求の許可をセット
表［２・１－２－３］参照［４８行］
カウンタＴＣＮＴ＿０をゼロにしています。
（必要ありませんが念のため）［４９行］
１００Ｈｚ（１０ｍｓ）に１回ＴＧＦＡが立つようにコンペアデータをＴＧＲＡ＿０に設定しています。
設定値（５００００）＝（（２０ＭＨｚ／４）／１００Ｈｚ）［５０行］
ＴＣＮＴ＿０のカウント動作指示をタイマスタートレジスタにセットしています。
表［２・１－２－１］参照

126

８０～８８行：
タイマー割り込みを利用した内部ソフトタイマーのスタート関数です。
９２～９５行：
タイマー割り込みを利用した内部ソフトタイマーのタイムアップしたかを調べる関数です。
９９～１１３行：
タイマー割り込みを利用した内部ソフトタイマー処理関数です。
ＴＰＵ＿０のＴＧＩＡ＿０コンペアマッチ割り込み
タイマＢチャンル２のタイマー割り込み処理で“ＩｎｔｒＨａｎｄ.ｃ”の割り込みハンドラーから呼ばれています。
［１０３行］ＴＧＲＡのＴＧＦＡビットによる割り込み要求解除の意味でタイマーステータスレジスタのＴＧＦＡ
ビットをクリアしています。
連続割り込みが必要な場合は、必ずクリアして下さい。
表［２・１－２－４］参照

127

３．メインコントロール部を割り込み用に変更する。

割り込みを可能にするために必要な変更および、タイマー割り込みを利用した内部ソフトタイマーを利用するために、割り込み許可の挿入とメインループ処理の変更をしています

プログラムに沿って説明します。

１）プログラムリスト
file “Cat261i.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

Cat261i.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include"io261x.h"

13: #include"DemoCtl.h"

14: /****************************************************************************/
15: /*

外部変数使用宣言*/

16: /****************************************************************************/
17: extern short

BuzzerHz;/* Buzzer Hz*/

18: extern Uchar

SciStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/

19: extern Uchar

SciSelect;/* ﾎﾞｰﾚｰﾄ選択*/

20: extern Uchar

MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*/

21: extern Uchar

MelMode;/* 演奏ﾓｰﾄﾞ*/

22: extern Uchar

MelSelect;/* 自動選曲*/

23: /****************************************************************************/
24: /*

変数宣言*/

25: /****************************************************************************/
26:

Uchar

ModeStep;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

128

*/

27:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/28: /****************************************************************************/
29: /*_main()*/

30: /****************************************************************************/
31: void_main(void)

32: {
33:

/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

34:

/*

NMI 立下りエッジ

*/

35:

/*

RAME 有効*/36:

SYSCR = 0x21;

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)

*/

37:

/* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/

38:/* の 1 回リトライ時間分待つ(20 回)

*/

39:

MemInitial();/* ﾒﾓﾘ系初期化

*/

40:

IoInitial();/* I/O 系初期化

*/

41:

TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ

*/

42:

enable();43:

while(1) {44:

if (TmUpTest(TM0) == ON) {45:

TmStart(TM0,20);/* ﾁｬﾀﾘﾝｸﾞ防止ｽﾀｰﾄ

*/

46:

SigInput();/* Signal Input Process

*/

47:

ModeCntrol();/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ

*/

48:

SigOutput();/* Signal Output Process*//* LCD

*/

49:

}

50:

AllLcdDisp();

51:

全画面表示

}

52: }
53: /****************************************************************************/
54: /*

Ｍｅｍ初期化*/

55: /****************************************************************************/
56: void

MemInitial(void)

57: {
58:

ModeStep = 0;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ

*/

59:

Shift = 0;/* Led Disp Patan Initial

*/

61:

PioMemInitial();/* PIOMem 初期化*/

62:

LcdMemInitial();/* LCDMem 初期化

*/

60:

129

63:

TimMemInitial();/* TIM

Mem 初期化*/

64:

SciMemInitial();/* SCIMem 初期化*/

65:

MelMemInitial();/* Melody Mem 初期化

*/

66: }
67: /****************************************************************************/
68: /*

Ｉ／Ｏ初期化*/69: /****************************************************************************/
70: void

IoInitial(void)

71: {
72:

PioIoInitial();/* PIOI/O 初期化*/

73:

LcdIoInitial();/* LCDI/O 初期化*/

74:

TimIoInitial();/* TIMI/O 初期化*/

75:

SciIoInitial();/* SCII/O 初期化*/

76:

MelIoInitial();/* Melody I/O 初期化

*/

77: }
78: /****************************************************************************/
79: /*

ModeCntrol()

ﾓｰﾄﾞｺﾝﾄﾛｰﾙ*/

80: /****************************************************************************/
81: void

ModeCntrol()

82: {
83:

if (GetUpPort(1) & 0x1) {84:

if (ModeStep < 10)85:/* PB[PA0] ON?(立上)Goto TEST*/

else if (ModeStep < 20) ModeStep = 20;/* Timer Goto TEST

*/

86:

else if (ModeStep < 30) ModeStep = 30;/* SCI*/87:

else if (ModeStep < 40) ModeStep = 40;/* Demo Melody

*/

88:

else

/* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

89:

Buzzer(0);/* 強制 OFF*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

*/

90:

}

91:

switch(ModeStep) {92:

case 0:ModeStep = 10;

ModeStep = 0;93:

GotoxyMemSet(0,0,"CAT261&AH6000 by");94:

GotoxyMemSet(0,1,"Interrupt [PA0]");95:

ModeStep++;

96:

break;

97:
98:/* PIO*/

Goto TEST

case 1:
RunRun();

130

99:
100:

break;
case 10:/* PIOTEST*//* Timer TEST

*/

101:

GotoxyMemSet(0,0,"PIO

102:

GotoxyMemSet(0,1,"SW[P47]->SW[P40]");103:

ModeStep++;

104:

break;

105:

case 11:106:

PioDemo();107:

break;

108:");

case 20:

109:

GotoxyMemSet(0,0,"Timer/Counter

110:

GotoxyMemSet(0,1,"0000Hz[+PF7-PC5]");111:

BuzzerHz = 0;112:

ModeStep++;

113:

break;

114:/* Buzzer Hz*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* SCI TEST*/

case 21:

115:

TimerDemo();

116:

RunRun();117:

break;

118:");

case 30:

119:

GotoxyMemSet(0,0,"SCI

120:

GotoxyMemSet(0,1,"09600b[+PF7-PC5]");

121:

SciStep

122:

SciSelect = 1;

123:

ModeStep++;

124:

break;

125:= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS*//* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* Demo Melody*/

case 31:126:

SciDemo();127:

RunRun();128:

break;

129:

8,n,1[PC2]");case 40:130:

GotoxyMemSet(0,0,"Melody

");

131:

GotoxyMemSet(0,1,"PC2[M]F7[ｽ]C5[ｾ]");132:

MelStep= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

133:

MelMode= 0;/* 演奏ﾓｰﾄﾞ

*/

134:

MelSelect = 0;/* 自動選曲

*/

131

135:

ModeStep++;

136:

break;

137:

case 41:

138:

Melody();139:

RunRun();140:

break;

141:}

142: }
143: /****************************************************************************/
144: /*

RunRun()

CPU 走行表示*/

145: /****************************************************************************/
146: void

RunRun()147: {
148:

if ((Shift <<= 1) == 0) Shift = 1;

149:

PutOutPort(Shift,'=');/* LED Shift 表示*/

150: }
151: /****************************************************************************/
152: /*

SoftWait1ms()

1ms 単位 ｿﾌﾄﾀｲﾏｰ*/

153: /****************************************************************************/
154: void

SoftWait1ms(Ushort ms)

155: {
156:

while(ms-- != 0) {157:

Wait1ms();

158:

}

159: }
160: /****************************************************************************/
161: /*

SoftWait10us() 10us 単位 ｿﾌﾄﾀｲﾏｰ*/

162: /****************************************************************************/
163: void

SoftWait10us(Ushort us)

164: {
165:

while(us-- != 0) {166:

Wait10us();

167:

}

168: }

132

［リストの説明］ 前章から変更のあった部分をおもに解説します。
４１行：
チャタリング防止タイマーに、タイマー割り込みを利用した内部ソフトタイマーの利用に変更しますので、ここでスタートをかけておきます。
４２行：
ここで、割り込み許可“ｅｎａｂｌｅ（）”をします。
割り込み要求マスクレベルをゼロ（０）にしています。 “ｉｏ２６１ｘ．ｈ”を参照
逆を言えば、ここに来るまでに割り込み関数で使用するＩ／Ｏおよび変数は初期化ずみであることが必要になります。
４４～４５行：
チャタリング防止タイマがタイムアップするのを待ちます。
いままで使用していたソフトタイマと違い、待っている間は他処理の実行が可能になっています。
４６～最終行：変更なし。

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

ＤＥＦでダウンロード後、プログラム実行をして下さい。
￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ２＿Ｉｎｔｅｒｒｕｐｔ￥ＮＯ１＿Ｔｉｍｅｒ＿Ｉｎｔｅｒｒｕｐｔ￥Ｃａｔ２６１ｉ１￥“Ｃａｔ２６１ｉ１．ｍｏｔ”です

次章は、ＳＣＩ割り込みに挑戦します。

133

第２章 ＳＣＩ割込み

ここの章では、ＳＣＩの送受信を割り込みで処理する場合どのような手続きが必要かをリストに沿って説明を進めていきます。
また、送受信フォームを文字列通信に変更しましたので、文字列扱いを容易にするため簡単なプロトコル
での通信仕様にしました。

［プロトコル仕様］

ＳＴＸ“文字列～１４文字まで”ＥＴＸ ＳＴＸ＝０ｘ０２（スタート）
ＥＴＸ＝０ｘ０３（エンド）ＳＣＩ０（文字列送信）―＞ＳＣＩ１（文字列受信）ＳＣＩ１（文字列送信）―＞ＳＣＩ０（文字列受信） の方式でループバック通信を繰り返します。

ＨＥＷの［Ｐｒｏｊｅｃｔ］－［Ｓｅｔ Ｃｕｒｒｅｎｔ Ｐｒｏｊｅｃｔ］－［Ｃａｔ２６１ｉ２］をクリックして、プロジェクトの変更をしておいて下さい。

134

１．ベクターテーブルをＳＣＩ割り込み用に変更する。

１）ベクターテーブルの変更箇所
file “StartupA.asm”
1: ;*******************************************************************************＜＜＜ 省略 ＞＞＞
28: ;********************************************************
29: ;* ベクターテーブル
30: ;********************************************************
32: _VectorTable:;(共通/213x)(26xx)＜＜＜ 省略 ＞＞＞
113:

VECTOR_UserRXI0;* VCT( 80) SCI0 ERI0 |114:

VECTOR_UserRXI0;* VCT( 81)

RXI0 |

115:

VECTOR_UserTXI0;* VCT( 82)

TXI0 |

116:

VECTOR_non;* VCT( 83)

TEI0 |

117:

VECTOR_UserRXI1;* VCT( 84) SCI1 ERI1 |118:

VECTOR_UserRXI1;* VCT( 85)

RXI1 |

119:

VECTOR_UserTXI1;* VCT( 86)

TXI1 |＜＜＜ 省略 ＞＞＞
154:

.end

［リストの説明］
１１３～１１４行：
ＳＣＩ０のＥＲＩ０（受信エラー）とＲＸＩ０（受信完了）の割り込み要因処理時のＣ言語関数“Ｕｓ
ｅｒＲＸＩ０（）”のアドレスを登録しました。
１１５行：
ＳＣＩ０のＴＸＩ０（送信データエンプティ）の割り込み要因処理時のＣ言語関数“ＵｓｅｒＴＸＩ０（）”のアドレスを登録しました。
１１７～１１８行：
ＳＣＩ１のＥＲＩ１（受信エラー）とＲＸＩ１（受信完了）の割り込み要因処理時のＣ言語関数“Ｕｓ
ｅｒＲＸＩ１（）”のアドレスを登録しました。
１１９行：
ＳＣＩ１のＴＸＩ１（送信データエンプティ）の割り込み要因処理時のＣ言語関数“ＵｓｅｒＴＸＩ１（）”のアドレスを登録しました。

135２）割り込みハンドラの変更
file “IntrHand.c”
1: /****************************************************************************/
2: /* ＜サンプル＞

割り込み

*/

3: /*

*/

4: /*

＜MOD＞

IntrHand.c

5: /*

＜タブ＞

４タブ編集

6: /*

＜保守ﾂｰﾙ＞ AHE261_HEW.hws

7: /*(ルネサス純正Ｃ用)

*/
*/
*/

割り込みハンドラ (CAT261-H8S/2612)*/

8: /****************************************************************************/
9: #include"io261x.h"

10: /****************************************************************************/
11: /*

UserTGIA0*/

12: /****************************************************************************/
13: #pragma interrupt UserTGIA0
14: #pragma regsave
15: void

UserTGIA0

UserTGIA0()

16: {
17:

TimerA0();

18: }
19: /****************************************************************************/
20: /*

UserRXI0*/

21: /****************************************************************************/
22: #pragma interrupt UserRXI0
23: #pragma regsave
24: void

UserRXI0

UserRXI0()

25: {
26:

Rxi0();

27: }
28: /****************************************************************************/
29: /*

UserTXI0*/

30: /****************************************************************************/
31: #pragma interrupt UserTXI0
32: #pragma regsave
33: void

UserTXI0

UserTXI0()

136

34: {35:

Txi0();

36: }
37: /****************************************************************************/
38: /*

UserRXI1*/

39: /****************************************************************************/
40: #pragma interrupt UserRXI1
41: #pragma regsave
42: void

UserRXI1UserRXI1()

43: {
44:

Rxi1();

45: }
46: /****************************************************************************/
47: /*

UserTXI1*/

48: /****************************************************************************/
49: #pragma interrupt UserTXI1
50: #pragma regsave
51: void

UserTXI1

UserTXI1()

52: {
53:

Txi1();

54: }［リストの説明］
２２～２７行：
ＳＣＩ０のＥＲＩ０（受信エラー）とＲＸＩ０（受信完了）の割り込みハンドラ関数です。
３１～３６行：
ＳＣＩ０のＴＸＩ０（送信データエンプティ）の割り込みハンドラ関数です。
４０～４５行：
ＳＣＩ１のＥＲＩ１（受信エラー）とＲＸＩ１（受信完了）の割り込みハンドラ関数です。
４９～５４行：
ＳＣＩ１のＴＸＩ１（送信データエンプティ）の割り込みハンドラ関数です。

137

２．ＳＣＩモジュールを割り込み用に変更する。

割り込みに対応するため、割り込み用送受信関数が必要になります。
また、ポーリング時は１文字での送受信ループバック動作でしたが、今回は割り込みサンプルですので、文字列での送受信ループバック連続動作をさせてみます。

プログラムに沿って説明します。

１）プログラムリスト
file “IntrSci.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrSci.c*/

6: /* ＜役割＞

SCI(SIO) 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-204-KC5C8012 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.h"

14: #include"DemoCtl.h"

15: /****************************************************************************/
16: /*SCI ボレート計算+etc

17: /*

Sys = 20000000Hz

18: /*

32*/*/= 64*2(0-1)*/

19: /****************************************************************************/
20: #define CLOCK(20000000/32)/* 調歩同期 n=0 時の計算式*/

21: #define BRRN(b)((CLOCK/b)-1)

22: #define NON

0/* ﾊﾟﾘﾃｨ

NON*/

23: #define EVEN

1

/*

EVEN

*/

24: #define ODD

2

/*

ODD

*/

25: #define STX

0x2/* 送信スタートコード

138

*/

26: #define ETX

0x3/* 送信ストップコード*/

27: /****************************************************************************/
28: /*

変数宣言*/

29: /****************************************************************************/
30:

Uchar

SciStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

31:

Uchar

SciSelect;/* ﾎﾞｰﾚｰﾄ選択

*/

32:

Uchar

TxDat0[16];/* SCI0 送信ﾃﾞｰﾀ

*/

33:

Uchar

TxIdx0;/*

送信中 ｲﾝﾃﾞｯｸｽ

*/

34:

Uchar

TxCnt0;/*

送信残 ｶｳﾝﾀ

*/

35:

Uchar

RxDat0[16];/*受信ﾃﾞｰﾀ

*/

36:

Uchar

RxIdx0;/*

受信中 ｲﾝﾃﾞｯｸｽ

*/

37:

Uchar

RxEnd0;/*受信終了ﾌﾗｸﾞ

*/

38:

Uchar

TxDat1[16];/* SCI1 送信ﾃﾞｰﾀ

*/

39:

Uchar

TxIdx1;/*

送信中 ｲﾝﾃﾞｯｸｽ

*/

40:

Uchar

TxCnt1;/*

送信残 ｶｳﾝﾀ

*/

41:

Uchar

RxDat1[16];/*受信ﾃﾞｰﾀ

*/

42:

Uchar

RxIdx1;/*

受信中 ｲﾝﾃﾞｯｸｽ

*/

43:

Uchar

RxEnd1;/*

受信終了ﾌﾗｸﾞ*/

44: const

UshortBpsTbl[] =

45: {
46:

4800,

47:

9600,

48:

19200,

49:

31250,

50:

38400,

51:0,52: };
53: /****************************************************************************/
54: /*

Ｍｅｍ初期化*/

55: /****************************************************************************/
56: void

SciMemInitial(void)

57: {
58:

SciStep= 0;59:

SciSelect = 1;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS

*/

60: }
61: /****************************************************************************/

13962: /*

Ｉ／Ｏ初期化*/

63: /****************************************************************************/
64: void

SciIoInitial(void)

65: {
66:

RsOpen0(9600,8,NON);/* SCI0 Open

*/

67:

RsOpen1(9600,8,NON);/* SCI1 Open

*/

68: }
69: /****************************************************************************/
70: /* RS232C(SCI0) Open bps= ﾎﾞﾚｰﾄ[4800,*9600,19200,31250,38400]*/

71: /*ch= ｷｬﾗｸﾀ[7,*8]*/

72: /*

pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/

73: /**= ﾃﾞﾌｫﾙﾄ

*/74: /*

固定= x1 STOP=1bit*/

75: /****************************************************************************/
76: void

RsOpen0(Ushort bps,Uchar ch,Uchar pty)

77: {
78:

Uchar

bck;

79:

Uchar

smr;

80:
81:

MSTPCRB &= ~0x80;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ SCI0 ｽﾀｰﾄ

*/

82:

IPRJ

/* SCI0 ﾌﾟﾗｲｵﾘﾃｨ 6

*/

83:

SCMR_0 = 0xf2;/* ｽﾏｰﾄ SMIF=0 Non ｽﾏｰﾄ

*/

85:

smr = 0;/* ﾓｰﾄﾞ ｷｬﾗｸﾀ[8bit] ﾊﾟﾘﾃｨ[NON]

*/

86:

if (ch == 7)

smr |= 0x40;/*

ｷｬﾗｸﾀ[7bit]

*/

87:

if (pty == EVEN)

smr |= 0x20;/*

ﾊﾟﾘﾃｨ[EVEN]

*/

88:

else if (pty == ODD) smr |= 0x30;/*

ﾊﾟﾘﾃｨ[ODD]

*/

89:

SMR_0 = smr;

= 0x76;

84:

90:
91:

if (bps == 4800)

bck = BRRN(4800);92:else if (bps == 9600)

bck = BRRN(9600);

93:else if (bps == 19200) bck = BRRN(19200);

94:else if (bps == 31250) bck = BRRN(31250);

95:else if (bps == 38400) bck = BRRN(38400);96:

BRR_0 = bck;/* ﾎﾞｰﾚｰﾄｼﾞｪﾈﾚｰﾄ設定

*/

97:

Wait1ms();/* 1bit 経過待ち 2400BPS(0.42ms+a)

*/

140

98:

SSR_0 &= 0x87;/* RDRF+ResetStatus

*/

99:

SCR_0 = 0x70;/* RIE(RX ｲﾝﾀﾗﾌﾟﾄｲﾈｰﾌﾞﾙ)+TE+RE*/

100: }
101: /****************************************************************************/
102: /* RS232C(SCI1) Open bps= ﾎﾞﾚｰﾄ[4800,*9600,19200,31250,38400]*/

103: /*ch= ｷｬﾗｸﾀ[7,*8]*/

104: /*

pty= ﾊﾟﾘﾃｨ[*0=NON 1=EVEN 2=ODD]*/

105: /**= ﾃﾞﾌｫﾙﾄ

*/106: /*

固定= x1 STOP=1bit*/

107: /****************************************************************************/
108: void

RsOpen1(Ushort bps,Uchar ch,Uchar pty)

109: {
110:

Uchar

bck;

111:

Uchar

smr;

112:
113:

MSTPCRB &= ~0x40;/* ﾓｼﾞｭｰﾙｽﾄｯﾌﾟ SCI1 ｽﾀｰﾄ

*/

114:

IPRK

/* SCI1 ﾌﾟﾗｲｵﾘﾃｨ 6

*/

115:

SCMR_1 = 0xf2;/* ｽﾏｰﾄ SMIF=0 Non ｽﾏｰﾄ

*/

117:

smr = 0;/* ﾓｰﾄﾞ ｷｬﾗｸﾀ[8bit] ﾊﾟﾘﾃｨ[NON]

*/

118:

if (ch == 7)

smr |= 0x40;/*

ｷｬﾗｸﾀ[7bit]

*/

119:

if (pty == EVEN)

smr |= 0x20;/*

ﾊﾟﾘﾃｨ[EVEN]

*/

120:

else if (pty == ODD) smr |= 0x30;/*

ﾊﾟﾘﾃｨ[ODD]

*/

121:

SMR_1 = smr;

= 0x67;

116:

122:
123:

if (bps == 4800)

bck = BRRN(4800);124:

else if (bps == 9600)

bck = BRRN(9600);

125:

else if (bps == 19200) bck = BRRN(19200);

126:else if (bps == 31250) bck = BRRN(31250);

127:

else if (bps == 38400) bck = BRRN(38400);128:

BRR_1 = bck;/* ﾎﾞｰﾚｰﾄｼﾞｪﾈﾚｰﾄ設定

*/

129:

Wait1ms();/* 1bit 経過待ち 2400BPS(0.42ms+a)

*/

130:

SSR_1 &= 0x87;/* RDRF+ResetStatus

*/

131:

SCR_1 = 0x70;/* RIE(RX ｲﾝﾀﾗﾌﾟﾄｲﾈｰﾌﾞﾙ)+TE+RE*/

132: }
133: /****************************************************************************/

141

134: /*

TxStart0

SCI0 文字列送信(TXI0 割込み準備)*/

135: /****************************************************************************/
136: void

TxStart0(Uchar *tx,Uchar cnt)

137: {
138:

TxDat0[0] = STX;/* スタートコード

*/

139:

memcpy(&TxDat0[1],tx,cnt);/* 送信ﾊﾞｯﾌｧｰに記憶

*/

140:

TxDat0[cnt+1] = ETX;/* ストップコード

*/

141:

TxIdx0 = 1;/* 送信中ｲﾝﾃﾞｯｸｽ

*/

142:

TxCnt0 = cnt+1;/* 送信残ｶｳﾝﾀ

*/

144:

TDR_0 = TxDat0[0];/* 送信ﾃﾞｰﾀｾｯﾄ

*/

145:

SSR_0 &= ~(0x80);/* TDRE=0

*/

146:

SCR_0 |= 0x80;/* TIE=1 TX ｲﾝﾀﾗﾌﾟﾄｲﾈｰﾌﾞﾙ

*/

143:

147: }
148: /****************************************************************************/
149: /*

TxStart1

SCI1 文字列送信(TXI1 割込み準備)*/

150: /****************************************************************************/
151: void

TxStart1(Uchar *tx,Uchar cnt)

152: {
153:

TxDat1[0] = STX;/* スタートコード

*/

154:

memcpy(&TxDat1[1],tx,cnt);/* 送信ﾊﾞｯﾌｧｰに記憶

*/

155:

TxDat1[cnt+1] = ETX;/* ストップコード

*/

156:

TxIdx1 = 1;/* 送信中ｲﾝﾃﾞｯｸｽ

*/

157:

TxCnt1 = cnt+1;/* 送信残ｶｳﾝﾀ

*/

159:

TDR_1 = TxDat1[0];/* 送信ﾃﾞｰﾀｾｯﾄ

*/

160:

SSR_1 &= ~(0x80);/* TDRE=0

*/

161:

SCR_1 |= 0x80;/* TIE=1 TX ｲﾝﾀﾗﾌﾟﾄｲﾈｰﾌﾞﾙ

*/

158:

162: }
163: /****************************************************************************/
164: /*Txi0

TXI0 割込み

割り込みハンドラより呼ばれる*/

165: /****************************************************************************/
166: void

Txi0()

167: {
168:

if (TxCnt0 == 0) SCR_0 &= ~0x80;

169:else {/* TIE=0 TX ｲﾝﾀﾗﾌﾟﾄﾃﾞｨｾｰﾌﾞﾙ

142

*/

170:

TDR_0 = TxDat0[TxIdx0];/* 送信ﾃﾞｰﾀｾｯﾄ

*/

171:

SSR_0 &= ~(0x80);/* TDRE=0 TSR へ転送

*/

172:

++TxIdx0;173:--TxCnt0;

174:}

175: }
176: /****************************************************************************/
177: /*Txi1

TXI1 割込み

割り込みハンドラより呼ばれる*/

178: /****************************************************************************/
179: voidTxi1()

180: {181:

if (TxCnt1 == 0) SCR_1 &= ~0x80;

182:

else {/* TIE=0 TX ｲﾝﾀﾗﾌﾟﾄﾃﾞｨｾｰﾌﾞﾙ

*/

183:

TDR_1 = TxDat1[TxIdx1];/* 送信ﾃﾞｰﾀｾｯﾄ

*/

184:

SSR_1 &= ~(0x80);/* TDRE=0 TSR へ転送

*/

185:

++TxIdx1;

186:--TxCnt1;

187:}

188: }
189: /****************************************************************************/
190: /*

Rxi0

RXI0 割込み

割り込みハンドラより呼ばれる*/

191: /****************************************************************************/
192: void

Rxi0()

193: {
194:

Uchar dt;

195:
196:

dt = RDR_0;

/* 受信

*/

197:

if (SSR_0 & 0x38) {/* SCI OE+FE+PE Error

*/

198:

SSR_0 &= 0x87;/* RDRF+Error Reset

*/

199:

RxIdx0 = 0;/* 正常受信*//* RDRF=0

*/

200:

}

201:

else {

202:

SSR_0 &= ~(0x40);

203:

if (dt == STX)

RxIdx0 = 0;/* スタートコード

*/

204:

else if (dt == ETX) RxEnd0 = ON;/* 受信終了ﾌﾗｸﾞｾｯﾄ

*/

205:

else {/* 受信データ

143

*/

206:

RxDat0[RxIdx0++] = dt;

207:

if (RxIdx0 >= sizeof(RxDat0)) RxIdx0 = 0;

208:
209:

/* ﾊﾞﾌｧｰｵｰﾊﾞｰの防止 */}}210: }
211: /****************************************************************************/
212: /*

Rxi1

RXI0 割込み

割り込みハンドラより呼ばれる*/

213: /****************************************************************************/
214: void

Rxi1()

215: {
216:

Uchar dt;

217:
218:

dt = RDR_1;

/* 受信

*/

219:

if (SSR_1 & 0x38) {/* SCI OE+FE+PE Error

*/

220:

SSR_1 &= 0x87;/* RDRF+Error Reset

*/

221:

RxIdx1 = 0;/* 正常受信*//* RDRF=0

*/

222:

}

223:

else {

224:

SSR_1 &= ~(0x40);

225:

if (dt == STX)

RxIdx1 = 0;/* スタートコード

*/

226:

else if (dt == ETX) RxEnd1 = ON;/* 受信終了ﾌﾗｸﾞｾｯﾄ

*/

227:

else {/* 受信データ*/

228:

RxDat1[RxIdx1++] = dt;229:

if (RxIdx1 >= sizeof(RxDat1)) RxIdx1 = 0;/* ﾊﾞﾌｧｰｵｰﾊﾞｰの防止 */

230:
231:

}
}

232: }
233: /****************************************************************************/
234: /*

SciDemo()

ＵＳＡＲＴデモ*/235: /****************************************************************************/
236: void

SciDemo()237: {
238:

Uchar

dec[2+1];

239:

short

stat;

240:
241:

SciSequence();/* SCI 操作ｺﾝﾄﾛｰﾙ

144

*/

242:

switch(SciStep) {243:

case 0:244:
245:

break;
case 1:

246:

RsOpen0(BpsTbl[SciSelect],8,NON);/* RS232C(SCI0) Open

*/

247:

RsOpen1(BpsTbl[SciSelect],8,NON);/* RS232C(SCI1) Open

*/

248:

GotoxyMemSet(0,0,"xxxxxxxxxxx");

249:

SciStep++;

250:

break;

251:

case 2:

252:

RxEnd1 = OFF;/* SCI1 受信終了ﾌﾗｸﾞ

*/

253:

TmStart(TM1,500);/*

ﾀｲﾑｵｰﾊﾞｰ管理

*/

254:

TxStart0(" n e r p S ",11);/* SCI0 送信/受信割込み開始

*/

255:

SciStep++;

256:

break;/* SCI1 受信終了を待つ

*/

/*

*/

257:
258:

case 3:if (RxEnd1 == ON) {259:

RxDat1[RxIdx1] = 0;260:

GotoxyMemSet(0,0,RxDat1);

261:

SciStep++;

確認用の表示データ作成

262:

}

263:

else if (TmUpTest(TM1) == ON) { /* SCI1 ﾀｲﾑｵｰﾊﾞｰ264:

GotoxyMemSet(0,0,"ﾀｲﾑｵｰﾊﾞｰ S0 ");265:

SciStep++;

266:

}

267:

break;

268:*//* Error 表示*/

case 4:269:

RxEnd0 = OFF;/* SCI0 受信終了ﾌﾗｸﾞ

*/

270:

TmStart(TM1,500);/*

ﾀｲﾑｵｰﾊﾞｰ管理

*/

271:

TxStart1("I t r u t C",11);/* SCI1 送信/受信割込み開始

*/

272:

SciStep++;273:

break;/* SCI0 受信終了を待つ

*/

/*

*/

274:
275:

case 5:if (RxEnd0 == ON) {276:

RxDat0[RxIdx0] = 0;277:

GotoxyMemSet(0,0,RxDat0);145

確認用の表示データ作成

278:

SciStep = 2;

279:

}

280:

else if (TmUpTest(TM1) == ON) { /* SCI1 ﾀｲﾑｵｰﾊﾞｰ281:

GotoxyMemSet(0,0,"ﾀｲﾑｵｰﾊﾞｰ S1 ");282:

SciStep = 2;

283:

}

284:

break;

285:/* Error 表示

*/
*/

}

286: }
287: /****************************************************************************/
288: /*

SciSequence()

Usart 操作ｺﾝﾄﾛｰﾙ*/

289: /****************************************************************************/
290: void

SciSequence()

291: {
292:

Uchar

port;

293:

Uchar

dec[5+1];

294:
295:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

296:

if (port & 0xe) {/* PB[P31]->PB[P33] ON(立上) ?

*//* PB[PC2] ON ? 送信ｽﾀｰﾄ/ｽﾄｯﾌﾟ

*/

297:

if (port & 0x2) {298:

if (SciStep == 0) SciStep = 1;

299:

else

300:

}

301:

if (SciStep == 0) {302:

SciStep = 0;

if (port & 0x4) {303:/* 停止中のみ受け付ける*//* PB[PC5] ON ? ﾎﾞﾚｰﾄ下げ?

*/

if (SciSelect != 0) --SciSelect;

304:

}

305:

else if (port & 0x8) {306:/* PB[PF7] ON ? ﾎﾞﾚｰﾄ上げ?

if (BpsTbl[SciSelect+1] != 0) ++SciSelect;

307:

}

308:

Bin2AdecN(dec,BpsTbl[SciSelect],5); /* 表示用データ作成

309:

GotoxyMemSet(0,1,dec);

310:
311:

*/

}
}

312: }

146*/

［リストの説明］ 前章に変更を加えた個所を説明します。
２５～２６行：
文字列データの最初と最後を示すコードのシンボル定義です。
３２～３７行：
ＳＣＩ０の送受信割り込み関数で使用する変数の宣言です。
３８～４３行：
ＳＣＩ１の送受信割り込み関数で使用する変数の宣言です。
８２行：
ＳＣＩ０のインタラプトプライオリティを“６”に設定しています。表［２・１－１－３］参照
９９行：
ＳＣＩ０の送受信を割り込み処理にする場合、初期化の段階では送信はディセーブル状態にしておく必要があります。
１１４行：
ＳＣＩ１のインタラプトプライオリティを“６”に設定しています。表［２・１－１－３］参照
１３１行：
ＳＣＩ１の送受信を割り込み処理にする場合、初期化の段階では送信はディセーブル状態にしておく必要があります。
１３６～１４７行：
ＳＣＩ０の送受信割り込みを開始させる関数です。
１３８～１４２行は、文字列送信を割り込みで処理するための準備です。
準備が終了後、最初の１文字を“ＴＤＲ”にセットし、“ＴＤＲＥ＝０”によりＴＳＲに転送後、“ＴＩＥ＝１”により送信データエンプティ割り込み要求を許可しています。
あと残りの文字列データは、送信データエンプティ割り込み処理内で要求が発生するたびに１文字ごと送信をさせます。
１５１～１６２行：
ＳＣＩ１の送受信割り込みを開始させる関数です。ＳＣＩ０の仕様と同じですので省略します。
１６６～１７５行：
ＳＣＩ０の１バイト毎の送信データエンプティ割り込みのハンドラより呼ばれる関数です。
１バイト毎に“ＴＤＲ”にセットし、“ＴＤＲＥ＝０”によりＴＳＲに転送後、内部管理変数を調整して終了しています。
送信するデータがなくなった場合は、送信データエンプティ割り込み要求を禁止して割り込みを止めています。
１７９～１８８行：
ＳＣＩ１の１バイト毎の送信データエンプティ割り込みのハンドラより呼ばれる関数です。
ＳＣＩ０の仕様と同じですので省略します。

147

１９２～２１０行：
ＳＣＩ０の受信エラーと受信完了の割り込みハンドラより呼ばれる関数です。
１バイト毎の受信完了もしくは受信エラー発生で割り込みが発生します。
シリアルステータスレジスタを監視をおこない、正常時の受信データ処理をします。
受信データがＳＴＸ“￥ｘ０２”の場合、テキストスタートと判断して、内部インデックスをゼロ（０）にします。
受信データがＥＴＸ“￥ｘ０３”の場合、テキスト終了と判断して、受信終了フラグを立てます。
その他の受信データは、内部受信バッファーにセットしていきます。
エラーが発生時は、エラーリセット後内部インデックスカウンタをクリアにしています。
２１４～２３２行：
ＳＣＩ１の受信エラーと受信完了の割り込みハンドラより呼ばれる関数です。
ＳＣＩ０の仕様と同じですので省略します。
２３６～２８６行：
ＳＣＩ０とＳＣＩ１の動作確認用の関数です。
文字列送信後、文字列受信の終了を待ち,終了後ＬＣＤに表示させています。
この動作を、ＰＢ［ＰＣ２］ＯＮか、もしくはエラー発生するまで繰り返します。
無応答判定も、タイマー割り込みを利用した内部ソフトタイマを使用しましたので、ポーリング時に使用していたループソフトタイマを排除しました。

以上の３ファイルの変更で、ＳＣＩ割り込み対応のシステムに変貌したわけです。
ＤＥＦでダウンロード後、プログラム実行をしてみて下さい。
￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ２＿Ｉｎｔｅｒｒｕｐｔ￥ＮＯ２＿ＳＣＩ＿Ｉｎｔｅｒｒｕｐｔ￥Ｃａｔ２６１ｉ２￥

送信データは、“ＩｎｔｅｒｒｕｐｔＳＣ”の文字列を 1 文字ずつ空けて分けて送信しています。
［ＳＣＩ０＝“Ｉ ｔ ｒ ｕ ｔ Ｃ”］

［ＳＣＩ１＝“ ｎ ｅ ｒ ｐ Ｓ ”］

各チャンネルでの受信データは、ＬＣＤの１行目に表示しますので、正常受信していますと重なり合い文字として読み取れるようになっていると思います。
ここまでの変更では、メロディの割り込み対応は済んでいません。
次章は、メロディの割り込み対応にし、より良いシステムに変貌させたいと思います。
148

第３章 割込み総合デモ（メロディ）

いよいよ、前章までに築き上げた割り込みシステムを利用した、応用例として割込み総合デモ（メロディ♪♪）のアプリケーション作り上げの最終解説となりました。

リストに沿って説明を進めていきます。
ＨＥＷの［Ｐｒｏｊｅｃｔ］－［Ｓｅｔ Ｃｕｒｒｅｎｔ Ｐｒｏｊｅｃｔ］－［Ｃａｔ２６１ｉ］をクリックして、プロジェクトの変更をしておいて下さい。

１．総合デモ（メロディ）を割り込み対応にする。

ここで残された問題は、リズム（音の長さ）を調整している部分が、いまだにソフトタイマー（ループ式）を利用していることです。
これがシステムの反応（スイッチ入力反応）を鈍らせている原因です。ここを改善します。

１）プログラムリスト
file “IntrMelody.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrMelody.c*/

6: /* ＜役割＞

デモ メロディー関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

AHE261_HEW.hws*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/10: /**/

11: /****************************************************************************/
12: #include<string.h>

13: #include"io261x.h"

14: #include"DemoCtl.h"

15: /****************************************************************************/
16: /*

音階 Hz*/

17: /****************************************************************************/
18: #define dO

262/* _ド */

149

19: #define rE

293/* _ﾚ */

20: #define mI330/* _ﾐ */

21: #define fhA

349/* _ﾌｧ */22: #define sO392/* _ｿ */

23: #define rA

440/* _ﾗ */

24: #define sI494/* _ｼ */

25: #define do523/* ド */

26: #define re

587

/* ﾚ

*/

27: #define mi

659

/* ﾐ

*/

28: #define fha

698/* ﾌｧ */

29: #define so

784

/* ｿ

*/

30: #define ra

880

/* ﾗ

*/

31: #define si

987

/* ｼ

*/

32: #define Do

1047/* ド */

32/* 楽譜テーブルの最大数

33:
34: #define SCMAX*/

35: /****************************************************************************/
36: /*

変数宣言*/

37: /****************************************************************************/
38:

Uchar

MelStep;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

39:

Uchar

MelMode;/* 演奏ﾓｰﾄﾞ

*/

40:

Uchar

MelSelect;/* 自動選曲*/

41:

UshortMelodyHz;/* Melody Hz

*/

42:

Uchar

Music;/* 自動演奏ｶｳﾝﾀｰ

*/

43:

UshortDoremi[SCMAX];/* ﾄﾞﾚﾐ音階周波数(Hz)の RAM 側

*/

44:

UshortRhythm[SCMAX];/* ﾘｽﾞﾑ(msec)*/

45: const

UshortDoremiTbl[] =/* ﾄﾞﾚﾐ音階周波数(Hz)

*/

47:

do,

/* ド */48:

re,/* ﾚ */

49:mi,/* ﾐ */

50:fha,/* ﾌｧ */

51:so,/* ｿ */

52:ra,/* ﾗ */

53:si,/* ｼ */

54:

Do,/* ド */

46: {

150

55:

0

56: };
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

UshortRhythmTbl[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();/* ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ

151

*/

91:

if (MelMode == 0) ManualMelody();/* 手動演奏

*/

92:

else

/* 自動演奏*/

AutoMelody();

93: }94: /****************************************************************************/
95: /*

MelodySequence()

ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ*/

96: /****************************************************************************/
97: void

MelodySequence()

98: {
99:

Uchar

port;

100:
101:

port = GetUpPort(1);/* PB[PA0]->PB[PF7]

*/

102:

if (port & 0xe) {/* PB[PC2]->PB[PF7] ON(立上) ?

*/

103:

Buzzer(0);/* Buzer OFF

*/

104:

if (port & 0x2) {/* PB[PC2] ON ? ﾓｰﾄﾞ変更

*/

105:

MelStep = 0;/* 強制停止*/106:

if (MelMode == 0) {/* 現在手動 ?

*//* 自動に変更*//* 自動選曲*//* 現在自動 ?

*//* 手動に変更*//* 自動選曲*//* 自動 ?

*//* PB[PC5] ON ? 選曲*//* 強制停止*/

107:

MelMode108:

MelSelect = 1;

109:

}

110:

else {= 1;

111:

MelMode112:

MelSelect = 0;

113:

= 0;

}

114:

}

115:

if (MelMode != 0) {116:

if (port & 0x4) {117:

MelStep = 0;118:

if (++MelSelect > 3) MelSelect = 1;

119:

}

120:

if (port & 0x8) {/* PB[PF7] ON ? 自動演奏開始

*/

121:

if (MelStep == 0) MelStep = 1;

/* 開始

*/

122:

else

/* 停止

*/

123:

Music

/* 手動表示*/124:

MelStep = 0;
= 0;

}

125:

}

126:

if (MelMode == 0) GotoxyMemSet(4,1,"M");

152

127:

else

128:

GotoxyMemSet(7,0,(Uchar *)MelodyTblA[MelSelect]);

129:

GotoxyMemSet(4,1,"A");/* 自動表示/* 曲名表示*/*/}130: }
131: /****************************************************************************/
132: /*

Ｍｅｍ初期化*/133: /****************************************************************************/
134: void

MelMemInitial(void)

135: {
136:

MelStep= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

137:

MelMode= 0;/* 演奏ﾓｰﾄﾞ

*/

138:

MelSelect = 0;/* 自動選曲*/

139:

MelodyHz = 0;/* Melody Min Hz*/

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:

MelodyHz = 0;

159:

MelStep++;

160:

break;

161:
162:/* ﾄﾞﾚﾐ音階周波数(初期準備)*//* Melody Min Hz*//* P40->P47 どれかがＯＮしたか？

*/case 1:
if (GetInPort(0) & 0xff) {

153

163:

port = GetUpPort(0);164:

if (port & 0x1) {

165:

*/

Buzzer(MelodyHz = Doremi[7]);

166:

}

167:

else if (port & 0x2) {168:/* SW[P41] 立上がり ON (レ)*/Buzzer(MelodyHz = Doremi[6]);

169:

}

170:

else if (port & 0x4) {171:/* SW[P42] 立上がり ON (ミ)*/Buzzer(MelodyHz = Doremi[5]);

172:

}

173:

else if (port & 0x8) {174:/* SW[P43] 立上がり ON (ファ)*/Buzzer(MelodyHz = Doremi[4]);

175:

}

176:

else if (port & 0x10) {177:/* SW[P44] 立上がり ON (ソ)*/Buzzer(MelodyHz = Doremi[3]);

178:

}

179:

else if (port & 0x20) {180:/* SW[P45] 立上がり ON (ラ)*/Buzzer(MelodyHz = Doremi[2]);

181:

}

182:

else if (port & 0x40) {183:/* SW[P46] 立上がり ON (シ)*/Buzzer(MelodyHz = Doremi[1]);

184:

}

185:

else if (port & 0x80) {186:/* SW[P47] 立上がり ON (ド)*/Buzzer(MelodyHz = Doremi[0]);

187:

}

188:

}

189:

else if (MelodyHz != 0) {190:

Buzzer(MelodyHz = 0);

191:

}

192:

break;

193:/* SW[P40] 立上がり ON (ド)/* Buzzer 停止*/}

194: }
195: /****************************************************************************/
196: /*

AutoMelody

自動ﾒﾛﾃﾞｨｰ演奏*/

197: /****************************************************************************/
198: void

AutoMelody()154

199: {
200:

switch(MelStep) {201:

case 0:

202:
203:

break;
case 1:204:_strcpyW(Doremi,(Ushort *)&MusicTbl[MelSelect-1][0]);205:_strcpyW(Rhythm,(Ushort *)&RhythmTbl[MelSelect-1][0]);206:++MelStep;

207:

break;

208:

case 2:

209:

MelodyHz = Doremi[Music];

/* 楽譜

*/

210:

if (MelodyHz != 0) {/* 演奏中*/211:

Buzzer(MelodyHz);212:

TmStart(TM2,Rhythm[Music]); /* <-リズム開始 */213:++MelStep;

214:

}

215:

else {

216:

Buzzer(0);217:Music = 0;

218:

TmStart(TM2,500);

219:

MelStep = 4;

220:

}

221:

break;

222:

case 3:223:*/

if (TmUpTest(TM2) == ON) {Music++;

225:

MelStep = 2;

226:

}

227:

break;
case 4:229:/* <-連続時の間 */if (TmUpTest(TM2) == ON) {230:

MelStep = 2;

231:

}

232:

break;

233:*//* <-連続時の間 *//* <-リズム

224:

228:

/* 停止

}

234: }

155

［リストの説明］ 前章に変更を加えた個所を説明します。

２１２行： ２１８行： ２２３行： ２２９行：
自動演奏のソフトタイマ使用部分を、タイマ割り込みを利用した内部ソフトタイマに変更しました。
これで、通常動作時のソフトタイマ（ループ方式）使用は、全て排除したかたちになりました。

どの程度、動作がスムーズになったか、動かして確認して見ましょう。
ＤＥＦでダウンロード後、プログラム実行をして下さい。
￥ＡＨＥ２６１＿ＨＥＷ￥Ｓ２＿Ｉｎｔｅｒｒｕｐｔ￥ＮＯ３＿Ｄｅｍｏ＿Ｍｅｌｏｄｙ＿Ｉｎｔｅｒｒｕｐｔ￥Ｃａｔ２６１ｉ￥

いかがですか？
自動演奏を実行した時にＬＥＤが止まらないでしょう！
（止まるのも味があるのですが、今回の目的とは違います）
それに、いつＰＢ［Ｐｎｎ］を押しても即反応するでしょう！
これでシステムの反応が良くなりました。これが割り込み処理を導入したことによるメリットです。
しかし、このシステムは改造する部分（半音が入っていない等…）が、まだあると思います。
どうぞ改造にチャレンジして、より良いシステムに構築してみて下さい！！ 期待しています。

これで、この解説テキストの終了とします。
この内容で満足して頂いたとは思いませんが、皆様のご協力で成長させていきたいと思っています。
メールで頂いたご意見、ご質問を、出来る限り反映させ、より良い解説テキストにしていきたいと考えていますので、ご指導の程よろしくお願い致します。

２００２年 ４月 著者

156