評価ボード
アセンブラ・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
３．保守ツール（Ｍａｋｅｆｉｌｅ）............................................................................................20
第２章 ｇｃｃによるスタートアップ................................................................................................28
１．動かしてみましょう ..................................................................................................................28
２．プログラムリスト ......................................................................................................................29
３．保守ツール（Ｍａｋｅｆｉｌｅ）............................................................................................43
第３章 ＰＩＯ .....................................................................................................................................45
１．動かしてみましょう ..................................................................................................................45
２．プログラムリスト ......................................................................................................................47
第４章 ＰＩＯの応用（ＬＣＤ） .......................................................................................................57
１．動かしてみましょう ..................................................................................................................57
２．プログラムリスト ......................................................................................................................58
第５章 タイマ／カウンタ...................................................................................................................72
１．動かしてみましょう ..................................................................................................................73
２．プログラムリスト ......................................................................................................................74
第６章 ＳＣＩ .....................................................................................................................................87
１．動かしてみましょう ..................................................................................................................87
２．プログラムリスト ......................................................................................................................88
第 7 章 総合デモ（メロディ）........................................................................................................ 107
１．動かしてみましょう ............................................................................................................... 107

1２．プログラムリスト ................................................................................................................... 108
第２部 割込み編 ................................................................................................................................123
第１章 タイマ割込み ....................................................................................................................... 123
１．ベクターテーブルとスタートアップを割り込み用に変更する。 ........................................ 124
２．タイマモジュールを割り込み用に変更する。 ...................................................................... 127
３．メインコントロール部を割り込み用に変更する。............................................................... 136
第２章 ＳＣＩ割込み ....................................................................................................................... 143
１．ベクターテーブルとスタートアップをＳＣＩ割り込み用に変更する。............................. 144
２．ＳＣＩモジュールを割り込み用に変更する。 ...................................................................... 147
第３章 割込み総合デモ（メロディ）............................................................................................. 158
１．総合デモ（メロディ）を割り込み対応にする。 .................................................................. 158

2

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

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

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

評価ボード ＡＨＥ２６１

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

ﾎﾟｰﾄｼﾝﾎﾞﾙ

ピン番号CN1-14A
1-14B
1-15A
1-15B
1-16A
1-16B
1-17A
1-17B

P1DR

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

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

信号名
LED1
LED2
LED3
LED4
LED5
LED6
LED7
LED8

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

ﾎﾟｰﾄｼﾝﾎﾞﾙ
TGRA_3

ピン番号
CN2-10A

ﾋﾟﾝｼﾝﾎﾞﾙ
PB0/TIOCA3

ピン番号
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

仕様
ＰＷＭモード パルス出力

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

ﾎﾟｰﾄｼﾝﾎﾞﾙ
POATA
PORTC

0xffffbe

POATF

方向
入力
入力
入力
入力

信号名
SW12 PB[PA0]
SW13 PB[PC2]
SW14 PB[PC5]SW15 PB[PF7]トグルスイッチ関係
ﾎﾟｰﾄｱﾄﾞﾚｽ0xffffb3

ﾎﾟｰﾄｼﾝﾎﾞﾙ

PORT４

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

信号名
SW16 SW[P40]
SW17 SW[P41]
SW18 SW[P42]
SW19 SW[P43]
SW20 SW[P44]
SW21 SW[P45]
SW22 SW[P46]
SW23 SW[P47]

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

1

２．２Ｋ

2

CN13-2A(GND)

ＢＺ(PKM13EPY-4002-B0)

6

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

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

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

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

テーマ“メロディ♪♪”のＨＥＸファイルは、“￥評価ボード￥第 2 部割込み編￥第 3 章割込み総合デモ（メロディ）\Cat261i.mot“です。

（ダウンロードの方法は、ＤＥＦのＨＥＬＰを参照）
１０）ダウンロードが終了しましたら、プログラムの実行をして下さい。
（ＤＥＦのショートＰＢのＧＯをクリック）

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

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

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

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

０−４−２図 ＰＩＯ表示

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

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

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

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

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

8

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

10

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

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

まずは、ＤＥＦのダウンロードで￥評価ボード￥第１部ポーリング編￥第１章スタートアップ￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう
移動したディレクトリの中に、“Ｃａｔ２６１ｐ１．ｍｏｔ”というＨＥＸファイルがあります。
これをダウンロードしますと、このようなメッセージがでますが、ここでのプログラムはアセンブラ
ーで作成しているため、C ソースがありませんとのメッセージです。

無視して“OK”をクリックして下さい。
プログラム実行してみて下さい。
（ＤＥＦ画面左下のＧｏをクリック）

動作としては、なにかＬＥＤがパラパラ表示しているはずです。
このソフトは単純に２０ｍｓ毎にＬＥＤを１ビット左シフトしながら点灯させているだけのソフトです。
それでは、プログラムリストを見てみましょう！

11

２．プログラムリスト

１） まずは、ベクターテーブルの設定のリスト例を示します。
file “vectorA.asm”
1: ;*******************************************************************************
2: ;*
3: ;* Ｈ８Ｓ デバッカモニター用ベクターテーブル(GNU/as)
4: ;*TYPE: H8S/2132.2134.2138.2612.2633F-ZTAT

5: ;*MODE: Advanced

6: ;*2002/03/14 by AONE M.Hasegawa

7: ;*******************************************************************************
8:.h8300s9:.extern

̲StartUp

10:.extern̲non.section.vector

11:
12:
13:
14: ;********************************************************
15: ;* マクロ宣言

Normal = .word Advanced = .long

16: ;********************************************************
17:.macro VECTOR p

18:
19:

.long

\p

.endm

20: ;********************************************************
21: ;* ベクターテーブル
22: ;********************************************************
23: ̲VectorTable:;(共通/213x)(26xx)

24:

VECTOR

̲StartUp;* VCT( 0) RESET

25:

VECTOR̲non;* VCT( 1) System 予約 1|

26:

VECTOR̲non;* VCT( 2)

2|

27:

VECTOR̲non;* VCT( 3)

3|

28:

VECTOR̲non;* VCT( 4)

4|

29:

VECTOR̲non;* VCT( 5)

5|

30:

VECTOR̲non;* VCT( 6) 直接推移|

31:

VECTOR̲non;* VCT( 7) NMI

|

12

|

32:

VECTOR̲non;* VCT( 8) TRAP0|33:

VECTOR̲non;* VCT( 9) TRAP1|

34:

VECTOR̲non;* VCT( 10) TRAP2|

35:

VECTOR̲non;* VCT( 11) TRAP3|

36:

VECTOR̲non;* VCT( 12) System 予約 1|

37:

VECTOR̲non;* VCT( 13)

2|

38:

VECTOR̲non;* VCT( 14)

3|

39:

VECTOR̲non;* VCT( 15)

4|

40:

VECTOR̲non;* VCT( 16) IRQ0|41:

VECTOR̲non;* VCT( 17) IRQ1|

42:

VECTOR̲non;* VCT( 18) IRQ2|

43:

VECTOR̲non;* VCT( 19) IRQ3|

44:

VECTOR̲non;* VCT( 20) IRQ4|45:

VECTOR̲non;* VCT( 21) IRQ5|

46:

VECTOR̲non;* VCT( 22) IRQ6|47:

VECTOR̲non;* VCT( 23) IRQ7|48:

VECTOR̲non;* VCT( 24) DTC

END

49:

VECTOR̲non;* VCT( 25) WDG

WOVI0 |

50:

VECTOR̲non;* VCT( 26) WOVI1|

51:

VECTOR̲non;* VCT( 27) PCB|

52:

VECTOR̲non;* VCT( 28) A/D

53:

VECTOR̲non;* VCT( 29) ﾘｻﾞｰﾌﾞ|

54:

VECTOR̲non;* VCT( 30) ﾘｻﾞｰﾌﾞ|

55:

VECTOR̲non;* VCT( 31) ﾘｻﾞｰﾌﾞ|

56:

VECTOR̲non;* VCT( 32) ﾘｻﾞｰﾌﾞ|TPU̲0 TGIA̲0

57:

VECTOR̲non;* VCT( 33) ﾘｻﾞｰﾌﾞ|

TGIB̲058:

VECTOR̲non;* VCT( 34) ﾘｻﾞｰﾌﾞ|

TGIC̲059:

VECTOR̲non;* VCT( 35) ﾘｻﾞｰﾌﾞ|

TGID̲060:

VECTOR̲non;* VCT( 36) ﾘｻﾞｰﾌﾞ|

TCIV̲061:

VECTOR̲non;* VCT( 37) ﾘｻﾞｰﾌﾞ|

62:

VECTOR̲non;* VCT( 38) ﾘｻﾞｰﾌﾞ|

63:

VECTOR̲non;* VCT( 39) ﾘｻﾞｰﾌﾞ|

64:

VECTOR̲non;* VCT( 40) ﾘｻﾞｰﾌﾞ|TPU̲1 TGIA̲1

65:

VECTOR̲non;* VCT( 41) ﾘｻﾞｰﾌﾞ|

TGIB̲1

66:

VECTOR̲non;* VCT( 42) ﾘｻﾞｰﾌﾞ|

TGIV̲1

67:

VECTOR̲non;* VCT( 43) ﾘｻﾞｰﾌﾞ|

TGIU̲1

13

ADI

|

|

68:

VECTOR̲non;* VCT( 44) ﾘｻﾞｰﾌﾞ|TPU̲2 TGIA̲2

69:

VECTOR̲non;* VCT( 45) ﾘｻﾞｰﾌﾞ|

TGIB̲2

70:

VECTOR̲non;* VCT( 46) ﾘｻﾞｰﾌﾞ|

TGIV̲2

71:

VECTOR̲non;* VCT( 47) ﾘｻﾞｰﾌﾞ|

TGIU̲2

72:

VECTOR̲non;* VCT( 48) FRTICIA |TPU̲3 TGIA̲373:

VECTOR̲non;* VCT( 49)

ICIB |TGIB̲3

74:

VECTOR̲non;* VCT( 50)

ICIC |TGIC̲375:

VECTOR̲non;* VCT( 51)

ICID |TGID̲376:

VECTOR̲non;* VCT( 52)

OCIA |

TCIV̲077:

VECTOR̲non;* VCT( 53)

OCIB |

78:

VECTOR̲non;* VCT( 54)

FOVI |

79:

VECTOR̲non;* VCT( 55) ﾘｻﾞｰﾌﾞ|

80:

VECTOR̲non;* VCT( 56) ﾘｻﾞｰﾌﾞ|TPU̲4 TGIA̲4

81:

VECTOR̲non;* VCT( 57) ﾘｻﾞｰﾌﾞ|

TGIB̲482:

VECTOR̲non;* VCT( 58) ﾘｻﾞｰﾌﾞ|

TGIV̲483:

VECTOR̲non;* VCT( 59) ﾘｻﾞｰﾌﾞ|

TGIU̲484:

VECTOR̲non;* VCT( 60) ﾘｻﾞｰﾌﾞ|TPU̲5 TGIA̲585:

VECTOR̲non;* VCT( 61) ﾘｻﾞｰﾌﾞ|

TGIB̲586:

VECTOR̲non;* VCT( 62) ﾘｻﾞｰﾌﾞ|

TGIV̲587:

VECTOR̲non;* VCT( 63) ﾘｻﾞｰﾌﾞ|

TGIU̲588:

VECTOR̲non;* VCT( 64) TMR0 CMIA0 |89:

VECTOR̲non;* VCT( 65)

CMIB0 |

90:

VECTOR̲non;* VCT( 66)

OVI0 |

91:

VECTOR̲non;* VCT( 67) ﾘｻﾞｰﾌﾞ

92:

VECTOR̲non;* VCT( 68) TMR1 CMIA1 |93:

VECTOR̲non;* VCT( 69)

CMIB1 |

94:

VECTOR̲non;* VCT( 70)

OVI1 |

95:

VECTOR̲non;* VCT( 71) ﾘｻﾞｰﾌﾞ

96:

VECTOR̲non;* VCT( 72) TMRXY CMIAY |97:

VECTOR̲non;* VCT( 73)

CMIBY |

98:

VECTOR̲non;* VCT( 74)OVIY |

99:

VECTOR̲non;* VCT( 75)

ICIX |

100:

VECTOR̲non;* VCT( 76)IBF1 |

101:

VECTOR̲non;* VCT( 77)IBF2 |

102:

VECTOR̲non;* VCT( 78) ﾘｻﾞｰﾌﾞ

|

103:

VECTOR̲non;* VCT( 79) ﾘｻﾞｰﾌﾞ

|

14

|

|

104:

VECTOR̲non;* VCT( 80) SCI0 ERI0 |105:

VECTOR̲non;* VCT( 81)

RXI0 |

106:

VECTOR̲non;* VCT( 82)

TXI0 |

107:

VECTOR̲non;* VCT( 83)

TEI0 |

108:

VECTOR̲non;* VCT( 84) SCI1 ERI1 |109:

VECTOR̲non;* VCT( 85)

RXI1 |

110:

VECTOR̲non;* VCT( 86)

TXI1 |

111:

VECTOR̲non;* VCT( 87)

TEI1 |

112:

VECTOR̲non;* VCT( 88) SCI2 ERI2 |113:

VECTOR̲non;* VCT( 89)

RXI2 |

114:

VECTOR̲non;* VCT( 90)

TXI2 |

115:

VECTOR̲non;* VCT( 91)

TEI2 |

116:

VECTOR̲non;* VCT( 92) IIC0 IICI0 |TMR2 CMIA2117:

VECTOR̲non;* VCT( 93)

DDCSW1|

CMIB2

118:

VECTOR̲non;* VCT( 94) IIC1 IICI1 |

OVI2

119:

VECTOR̲non;* VCT( 95) ﾘｻﾞｰﾌﾞ

|

120:

VECTOR̲non;* VCT( 96) ﾘｻﾞｰﾌﾞ|TMR3 CMIA3

121:

VECTOR̲non;* VCT( 97) ﾘｻﾞｰﾌﾞ

|

CMIB3

122:

VECTOR̲non;* VCT( 98) ﾘｻﾞｰﾌﾞ

|

OVI3

123:

VECTOR̲non;* VCT( 99) ﾘｻﾞｰﾌﾞ

|

124:

VECTOR̲non;* VCT(100) ﾘｻﾞｰﾌﾞ|IIC0 IICI0125:

VECTOR̲non;* VCT(101) ﾘｻﾞｰﾌﾞ

|

126:

VECTOR̲non;* VCT(102) ﾘｻﾞｰﾌﾞ|IIC1 IICI1

127:

VECTOR̲non;* VCT(103) ﾘｻﾞｰﾌﾞ

|

128:

VECTOR̲non;* VCT(104) ﾘｻﾞｰﾌﾞ|HCAN ERS0,OVR0129:

VECTOR̲non;* VCT(105) ﾘｻﾞｰﾌﾞ

|

RM0

130:

VECTOR̲non;* VCT(106) ﾘｻﾞｰﾌﾞ

|

RM1

131:

VECTOR̲non;* VCT(107) ﾘｻﾞｰﾌﾞ

|

SLE0

132:

VECTOR̲non;* VCT(108) ﾘｻﾞｰﾌﾞ

|MMT

TGIMN

133:

VECTOR̲non;* VCT(109) ﾘｻﾞｰﾌﾞ

|

TGINN

134:

VECTOR̲non;* VCT(110) ﾘｻﾞｰﾌﾞ

|

POEIN

135:

VECTOR̲non;* VCT(111) ﾘｻﾞｰﾌﾞ

|

136:

VECTOR̲non;* VCT(112) ﾘｻﾞｰﾌﾞ

|

137:

VECTOR̲non;* VCT(113) ﾘｻﾞｰﾌﾞ

|

138:

VECTOR̲non;* VCT(114) ﾘｻﾞｰﾌﾞ

|

139:

VECTOR̲non;* VCT(115) ﾘｻﾞｰﾌﾞ|

15

DDCSW1

140:

VECTOR̲non;* VCT(116) ﾘｻﾞｰﾌﾞ

|

141:

VECTOR̲non;* VCT(117) ﾘｻﾞｰﾌﾞ

|

142:

VECTOR̲non;* VCT(118) ﾘｻﾞｰﾌﾞ

|

143:

VECTOR̲non;* VCT(119) ﾘｻﾞｰﾌﾞ

|

144:

VECTOR̲non;* VCT(120) ﾘｻﾞｰﾌﾞ|SCI̲3 ERI2

145:

VECTOR̲non;* VCT(121) ﾘｻﾞｰﾌﾞ

|

RXI2

146:

VECTOR̲non;* VCT(122) ﾘｻﾞｰﾌﾞ

|

TXI2

147:

VECTOR̲non;* VCT(123) ﾘｻﾞｰﾌﾞ

|

TEI2

148:

VECTOR̲non;* VCT(124) ﾘｻﾞｰﾌﾞ|SCI̲3 ERI2

149:

VECTOR̲non;* VCT(125) ﾘｻﾞｰﾌﾞ

|

RXI2

150:

VECTOR̲non;* VCT(126) ﾘｻﾞｰﾌﾞ

|

TXI2

151:

VECTOR̲non;* VCT(127) ﾘｻﾞｰﾌﾞ

|

TEI2

152:

.end

［リストの説明］
１〜７行：
コメントです。
８行：CPU タイプの擬似命令です。
Ｈ８Ｓの場合は、“．ｈ８３００ｓ” Ｈ８／３００Ｈの場合は、“．ｈ８３００”と置きます。
９〜１０行：
外部参照の宣言です。
１２行：
ベクターテーブルのセクション名を、“．ｖｅｃｔｏｒ”と定義します。
１７〜１９行：
ベクターテーブルに置くアドレス値を、ノーマルモードは２バイト“．ｗｏｒｄ”でアドバンスド
は４バイト“．ｌｏｎｇ”になりますので、ここのマクロを変更することによりアドレス長を変えられるよう工夫がしてあります。
１３〜１５１行：
ベクターテーブルです。今回は１３行目のリセットベクターのみにアドレスを置いています。
１５２行：アセンブラファイルの最後には、この擬似命令“．ｅｎｄ”を置いて下さい。

16

２） つぎに、スタートアップのリスト例を示します。
file “StartupA.asm”
1: ;/****************************************************************************/
2: ;/* ＜サンプル＞ ポーリング*/

3: ;/**/

4: ;/*＜MOD＞

StartupA.asm*/

5: ;/*

＜役割＞

main

*/

6: ;/*

＜タブ＞

４タブ編集

7: ;/*

GNU/as*/

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

8: ;/****************************************************************************/
9:.h8300s

10:.section

.text

11:

.global̲StartUp,̲non

13:;--------

I/O------14:.EQU

SYSCR,

0xfffde5; ｼｽﾃﾑｺﾝﾄﾛｰﾙ

15:

.EQU

P1DDR,

0x0FFFE30; Moniter Port DIR

16:

.EQU

P1DR,

0x0FFFF00; Moniter Port Out

12:

17: ;/****************************************************************************/
18: ;/*

スタートアップ*/

19: ;/****************************************************************************/
20: ̲StartUp:
21:

mov.l

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

*/

22:

ldc.b

#0x6,exr;* disable() PBC の割込の為

*/

23:

jmp

̲main

;* Main24:
25: ̲non:26:;* 未使用割り込み

*/

rte

27: ;/****************************************************************************/
28: ;/*

メイン*/

29: ;/****************************************************************************/
30: ̲main:
31:

bset

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

*/

32:

bclr

#4,@SYSCR

;*

*/

33:

bclr

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

*/

34:

bset

#1,@SYSCR;*RAME 有効

*/

36:

mov.b

#0xff,r0l;* MoniterPort All Out

*/

37:

mov.b

r0l,@P1DDR

;*

"

*/

38:

mov.b

#1,r1l;* LED

表示パターン

*/

40:

mov.b

r1l,r0l;* LED

点灯

*/

41:

not.b

r0l

;*

0=点灯のため

*/

42:

mov.b

r0l,@P1DR;*

出力（LED 点灯）

*/

43:

mov.b

#20,r0l;* 20msWait

45:

bsr

Wait1ms

46:

dec.b

r0l

47:

bne

wait20ms

48:

rotl.b

r1l

49:

bra

loop

35:

39: loop:*/

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

50: ;/****************************************************************************/
51: ;/*

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

52: ;/****************************************************************************/
53: Wait1ms:
54:

push.w

r0

55:

mov.w

#5000,r0

57:

dec.w

#1,r0

;* 1 clock

58:

bne

wait:16;* 3 clock

59:

pop.w

r0

60:

rts

61:

.end

56: wait:18

［リストの説明］
１０行：
プログラムであることを示すセクション宣言です。
“．ｔｅｘｔ”は一般的ですので、このセクシ
ョン名を使うことをお勧めします。
なお、Ｃ言語で記述した場合も、このセクション名になります。
１１行：
外部参照が必要なシンボルは、このグローバル宣言をする必要があります。
“＿ＳｔａｒｔＵＰ”と“＿ｎｏｎ”は、“ｖｅｃｔｏｒＡ．ａｓｍ”で使用しています。
１１行：
Ｉ／Ｏレジスタアドレスをシンボル化するための宣言です。
シンボル名の最後の“，”（カンマ）をお忘れなく！
２０行：
電源ＯＮ時およびリセット時にプログラムはココから実行を始めるようにベクターテーブルに設定してあります。
２１行：
電源ＯＮ時およびリセット時にまず実行させる命令は、このスタックポインタの設定です。
定石ですので必ず守って下さい。
なお、理由はＣＰＵハードウェアマニュアルに記載されています。
２２行：
Ｈ８Ｓ／２６１２のＰＣブレーク例外処理の割り込みプライオリティが“７”になっていますので、ＰＣブレーク例外処理を有効にさせるために、この命令を置いています。
他の割り込み例外処理のプライオリティを“６”以下にする必要があります。
２３行：
メインプログラムへのジャンプエントリです。
２５〜２６行：
未使用割り込みのベクター値を置くためのプログラムです。
実際には、このプログラムが実行されることは通常状態である限りありえません。
ここまでがポーリングで済む場合の、世でいう“スタートアップ”になるわけです。
どうです簡単でしょう！！

３０行目以降は、このサンプルソフトが動作しているかを目で確かめるために用意したソフトです。
ＬＥＤ点灯部分等は、後章ＰＩＯ編で説明しますので、ここでは省略します。

19

３．保守ツール（Ｍａｋｅｆｉｌｅ）
コンパイル・アセンブリ・リンケージエディタを管理／制御する保守ツールは、ｍａｋｅ．ｅｘｅ）を使いました。
“Ｍａｋｅｆｉｌｅ”にこのプロジェクト（テーマ）の定義をしておけば、“ｍａｋｅ”とコマンドを打つだけで、自動で修正したソースだけを探して、コンパイル・アセンブリ・リンクを実行してくれる便利なツールです。
Ｍａｋｅｆｉｌｅの仕様を、簡単ではありますが、ここで説明をしておきます。

１）この章のサンプルで使用したＭａｋｅｆｉｌｅの中身
file “Makefile”
1: AS= h8300-hms-coff-as

2: CC= h8300-hms-coff-gcc

3: LD= h8300-hms-coff-ld

4: OBJCOPY = h8300-hms-coff-objcopy
5: SYM= coffext

6:
7: TARGET= Cat261p1.mot

8: OBJS= vectorA.o StartupA.o

9: LOCATE= h8s261x.x

10:
11: LIBDIR= /usr/local/h8/h8300-hms-coff/lib/h8300s/

12: INCLUDE = -I/usr/local/h8/h8300-hms-coff/include/
13: LIBC= $(LIBDIR)libm.a $(LIBDIR)libc.a $(LIBDIR)libgcc.a

14: CCFLAGS = -S -ms -g -nostartfiles
15: # LDFLAGS = -v -t
16:
17: .SUFFIXES: .coff .o .c .s .asm .h .mot
18:
19: $(TARGET): $(OBJS)
20:$(LD) $(LDFLAGS) -o $*.coff -Map $*.map -T $(LOCATE) $(OBJS) $(LIBC)

21:$(OBJCOPY) -O srec $*.coff $*.mot

22:$(SYM) $*.coff

23:
24: .asm.o:25:$(AS) -o $*.o $*.asm
20

26:
27: .c.o:28:$(CC) $(CCFLAGS) $(INCLUDE) $*.c29:$(AS) -o $*.o $*.s

30:

21

［Ｍａｋｅｆｉｌｅの説明］
１行：
環境変数“ＡＳ”に、アセブラコマンド名を登録しています。
２行：
環境変数“ＣＣ”に、Ｃコンパイラコマンド名を登録しています。
３行：
環境変数“ＬＤ”に、リンクエディタコマンド名を登録しています。
４行：
環境変数“ＯＢＪＣＯＰＹ”に、ＨＥＸファイル作成コマンド名を登録しています。
５行：
環境変数“ＳＹＭ”に、デバッガ用シンボルコンバータコマンド名を登録しています。
７行：
環境変数“ＴＡＲＧＥＴ”に、プロジェクト（ＨＥＸファイル）名を登録しています。
８行：
環境変数“ＯＢＪ”に、プロジェクトを作成するにあたり、必要なプログラムモジュールのオブジェクト（コンパイル／アセンブリが作成する）名を登録しています。
ＧＮＵ／ｇｃｃでは、“＊．ｏ”になります。
９行：
環境変数“ＬＯＣＡＴＥ”に、番地の割り振り（ロケート）に必要なセグメント別番地情報を定義したスクリプトファイル名を登録しています。
このファイルの中については、後で説明します。
１１行：
環境変数“ＬＩＢＤＩＲ”に、コンパイラが使用するライブラリのディレクトリ位置を登録しています。
ＧＮＵコマンドを走らせる環境に“ｃｙｇｗｉｎ”を使用していますので、ｌｉｎｕｘ風になるわけです。
ｃｙｇｗｉｎのルールとして、￥ｃｙｇｗｉｎの中をｒｏｏｔ（“／”）としていますので、このような設定になります。
対比するために、Ｗｉｎｄｏｗｓ風に書きますと、“￥ｃｙｇｗｉｎ￥ｕｓｒ￥ｌｏｃａｌ￥ｈ８￥ｈ８３００−ｈｍｓ−ｃｏｆｆ￥ｌｉｂ￥ｈ８３００ｓ￥”となります。

１２行：
環境変数“ＩＮＣＬＵＤＥ”に、ｇｃｃの標準ライブラリ用ヘッダーファイルのディレクトリ場所を登録しています。

22

１３行：
環境変数“ＬＩＢＣ”に、ｇｃｃの標準ライブラリ名を登録しています。
１４行：
環境変数“ＣＣＦＬＡＧＳ”に、ｇｃｃコンパイラスイッチを登録しています。
このコンパイラスイッチは、最低限必要なスイッチです。他に必要な場合は、ｇｃｃのマニュアル
をＷｅｂから入手してお使い下さい。
１５行：
リンカスイッチで、詳細情報を出力させるスイッチです。
チョットうるさいのでコメントアウトしてあります。
１７行：“.SUFFIXES”は、中で使用する拡張子の登録です。
注意としては、小文字で登録した場合は、小文字で記述して下さい。
１９行：“$(TARGET) : $(OBJS)”は、前に登録した（プロジェクト名）と（オブジェクト名リスト）の作
成時期の関係を調べます。
（プロジェクト名）のほうが古い（昔にできた）場合、次行のリンクコマンド等を実行させるための判定文です。
“このへんが自動で判断してくれるのでヒジョウに便利です。
”
２０行：
リンクコマンド行です。注意事項として、行の先頭は、<TAB>送りをしてください。
２１行：
ＨＥＸファイル作成コマンド行です。注意事項として、行の先頭は、<TAB>送りをしてください。
２２行：
デバッガ用シンボルコンバタコマンド行です。注意事項として、行の先頭は、<TAB>送りをしてく
ださい。
２４行：
“.asm.o:”は、Ａｓｍソースファイル“．ａｓｍ”とオブジェクトファイル“．ｏ”の作成時期の関係を調べます。
この場合も、オブジェクトが古い（昔にできた）場合、次行のアセンブリコマンドを実行します。
２７行：“.c.o:”は、Ｃソースファイル“．ｃ”とオブジェクトファイル“．ｓｏｆ”の作成時期の関係を調べます。
この場合は、オブジェクトが古い（昔にできた）場合、次行のコンパイルコマンドを実行します。
今後、新規プロジェクトを開発することになり、Ｍａｋｅｆｉｌｅを作成する必要になった場合、このＭａｋｅｆｉｌｅの７、８、９行の変更で対応することが出来ると思いますので参考にして頂ければ幸いです。
23２）LD コマンド用スクリプトファイル
セクション事のグループ指定および、アドレスを指定する定義ファイルです。
このファイルは、ＬＤコマンド（リンクエディタ）の時に使用します。
file “h8s261x.x”
1: OUTPUT̲FORMAT("coff-h8300")
2: OUTPUT̲ARCH(h8300S)
3:
4: SECTIONS
5: {
6:

.vect

0x0

: { *(.vector) ; }

7:

.rom

0x800

: { *(.text) *(.rodata) *(.string) ̲etext = . ; }8:.const.

: { *(.data) ̲edata = . ;}

9:

.bss

0xffe000 : { *(.bss) *(COMMON) *(.stack) ̲end = . ; }

10: }
11:

［説明］
１行：
ＬＤコマンドでの出力オブジェクトタイプの指定です。
Ｈ８／３００Ｈ ――――＞ OUTPUT_FORMAT("coff-h8300")
Ｈ８Ｓシリーズ ――――＞ OUTPUT_FORMAT("coff-h8300")
ＳＨ−２ ―――――――＞ OUTPUT_FORMAT("coff-sh")
２行：ＣＰＵアーキテクチャの指定です。
Ｈ８／３００Ｈ ――――＞ OUTPUT_ARCH(h8300H)
Ｈ８Ｓシリーズ ――――＞ OUTPUT_ARCH(h8300Ｓ)
ＳＨ−２ ―――――――＞ OUTPUT_ARCH(sh)４〜５行：セクション指定の始まりを意味します。
６行：“vectorA.asm”で宣言したセクション名のアドレス指定です。必ずゼロ（０）にして下さい。
７行：
プログラムの開始アドレスの指定です。必ず（０ｘ８００）にして下さい。
この指定により、モニタエリアの０ｘ２００〜０ｘ７ｆｆが確保されることになります。
＊（．ｔｅｘｔ） ＝ プログラムセクション名
24

＊（．ｒｏｄａｔａ） ＝ ｃｏｎｓｔ宣言をしたセクション名＊（．ｓｔｒｉｎｇ） ＝ プログラム中に文字列記述“ｘｘｘｘ”したセクション名＿ｅｔｅｘｔ＝ ．ｒｏｍグループの最後を示します

８行：
変更可能な初期化変数指定をした場合のセクションになります。
例 ｃｈａｒ ａ＝１０
ただし、ＲＯＭ化システムの場合は、使用しないで下さい。
＊（．ｄａｔａ） ＝ 変更可能な初期化変数宣言をしたセクション名＿ｅｄａｔａ＝ ＲＯＭエリア確保の最終を示します。

９行：
ＲＡＭエリアの開始アドレスを指定します。
＊（．ｂｓｓ）＝ ｓｔａｔｉｃ宣言をしたセクション名＊（ＣＯＭＭＯＮ） ＝ グロバール変数のセクション名＊（．ｓｔａｃｋ） ＝ スタックセクション名＿ｅｎｄ＝ ＲＡＭエリア確保の最終を示します

１０行：
セクション指定の最終を示します。

25３）ｍａｋｅの実行
一度、ｍａｋｅの便利さを実感して見ましょう。
このサンプルでＬＥＤを２０ｍｓ毎にシフト表示しているのを１００ｍｓ毎に変更してみましょう。
まずは、何かのファイラーで“￥評価ボード￥第１部ポーリング編￥第１章スタートアップ￥”のディレクトリに移動します。

“ＳｔａｒｔｕｐＡ．ａｓｍ”をエディタで開き
43:

mov.b

#20,r0lbsr

Wait1ms;* 20msWait*/

44: wait20ms:
45:

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

mov.b

#100,r0l;* 100msWait

変更後、保存終了して下さい。

26*/

保存終了が済みましたら、“ｍａｋｅ”を実行してみて下さい。

このような実行結果が表示されるはずです。

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

27

第２章 ｇｃｃによるスタートアップ

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

まずは、ＤＥＦのダウンロードで￥評価ボード￥第１部ポーリング編￥第２章ｇｃｃによるスタートアップ￥にディレクトリの移動をしておいて下さい。

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

28

２．プログラムリスト

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

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

29*１）Ｃ言語によるスタートアップ（プログラム）

重要！！ このモジュールのリンク順番は、“ｖｅｃｔｏｒＡ．ｏ”（１番目）の次（２番目）に置いて下さい。
file “Startup.c”
1: /****************************************************************************/
2: /* ＜サンプル＞

ポーリング

*/

3: /*

*/

4: /*

＜MOD＞

Startup.c

5: /*

＜タブ＞

４タブ編集

6: /*

*/
GNU/gcc

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

7: /****************************************************************************/
8: /****************************************************************************/
9: /*StartUp*/

10: /****************************************************************************/
11: voidStartUp()

12: {
13:

asm("mov.l #0xffefbe,sp");/* ｽﾀｯｸﾎﾟｲﾝﾀ 設定

*/

14:

asm("jmp/* void ̲main()*/̲̲main");

15: }
16: /****************************************************************************/
17: /*

non*/

18: /****************************************************************************/
19: #pragma interrupt
20: void

non()

21: {
22: }

30

［リストの説明］
内容説明については、前章の“ＳｔａｒｔｕｐＡ．ａｓｍ”と重複している部分もあります。
１〜７行：
コメントです。
１1 行：
電源ＯＮ時およびリセット時にプログラムはココから実行を始めるようにベクターテーブルに設定してあります。
１3 行：
電源ＯＮ時およびリセット時にまず実行させる命令は、このスタックポインタの設定です。
定石ですので必ず守って下さい。
なお、理由はＣＰＵハードウェアマニュアルに記載されています。
１4 行：
メインプログラムへのジャンプエントリです。
１9 行：
割り込み例外処理を示す“＃ｐｒａｇｍａ ｉｎｔｅｒｒｕｐｔ”定義になります。
この命令を置くことにより、関数の入口／出口に全レジスターの退避／復帰命令が挿入され、かつリターン命令が“ＲＴＥ”になります。
２0〜２2 行：
未使用割り込みのベクター値を置くためのプログラムです。
実際には、このプログラムが実行されることは通常状態である限りありえません。
ここまでがＣ言語記述での“スタートアップ”になるわけです。

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p2.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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:

disable();/* PBC の割込の為

*/

24:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

25:

/*

NMI 立下りエッジ

*/

26:

/*

RAME 有効*/27:

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

*/

28:

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

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

*/

30:

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

*/

31:

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

*/

32:

while(1) {/* 20msWait

*/

33:

SoftWait1ms(20);

32

34:

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

*/

35:

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

*/

36:

}

37: }
38: /****************************************************************************/
39: /*

Ｍｅｍ初期化*/

40: /****************************************************************************/
41: void

MemInitial(void)

42: {
43:

Shift = 0;/* Led Disp Patan Initial

*/

44:

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

45: }
46: /****************************************************************************/
47: /*

Ｉ／Ｏ初期化*/

48: /****************************************************************************/
49: void

IoInitial(void)

50: {
51:

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

52: }53: /****************************************************************************/
54: /*

RunRun()

CPU 走行表示*/

55: /****************************************************************************/
56: void

RunRun()

57: {
58:

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

59:

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

*/

60: }
61: /****************************************************************************/
62: /*

SoftWait1ms()

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

63: /****************************************************************************/
64: void

SoftWait1ms(Ushort ms)

65: {
66:

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

Wait1ms();

68:

}

69: }
33

70: /****************************************************************************/
71: /*

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

72: /****************************************************************************/
73: void

Wait1ms()

74: {
75:

asm("

push.w r0

");

76:

asm("

mov.w

");

77:

asm(" wait:

78:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

79:

asm("

bne

wait:16");/* 3 clock

*/

80:

asm("

pop.w

r0

");

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

");

81: }

34

［リストの説明］
１〜１１行：
コメントです。
１２〜１３行：
後で説明しますが、このテーマで使用する定義文をまとめたヘッダーファイルを使用することをコンパイラに教えるステートメントです。
１７行：
内部使用する変数の宣言文です。
“Uchar”は、“io261x.h”でキーワード宣言してあるため、“unsigned char”と同じ意味を持ちます。
長い文章を入力したく無い場合よく使います。
（キー入力が苦手な日本人特有かも？）
変数名“Shift”の用途は、ＬＥＤ表示バッファーとして使用します。
２１行：“̲main()”関数の先頭を意味する宣言文です。
前に説明した“スタートアップ”から、ここにジャンプして来ます。
標準の“main()”では、“ｖｏｉｄ”タイプ宣言を許可していませんので、あえてアンダーバー“＿”を付けて違う名前にしました。
２３行：“ｉｏ２６１ｘ．ｈ”内に、“ｄｉｓａｂｌｅ（）”のマクロが組んであります。デバッガを使用するにあたり、ディセーブル状態は割り込み例外処理のプライオリティを“６”としています。
これにより、プライオリティ“７”以上の割り込みしか受け付けない命令になります。
つまり、Ｈ８Ｓ／２６１２のＰＣブレーク例外処理の割り込みプライオリティが“７”になっていますので、ＰＣブレーク例外処理を有効にさせるために、この命令必要です。
ＣＰＵタイプによりユーザープライオリティの設定要／不要があります。
１）Ｈ８／３６６４−――――――――――――――― 不要
２）Ｈ８Ｓ／２１３２・２１３４・２１３８――――― 不要
３）Ｈ８Ｓ／２２３８・２６１２・２６３３――――― 要（６以下）４）ＳＨ／７０４５・７０５０・７０５１―――――― 要（１４以下）
２４行：
Ｈ−ｄｅｂｕｇｇｅｒを使用する場合、システムコントローラに対する設定をこのように指示して
下さい。
（定石）
なお、ＣＰＵタイプにより設定内容が違います。
Ｈ８／３６６４の場合
１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）Ｈ８Ｓ／２１３２・２１３４・２１３８の場合
35

１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）Ｈ８Ｓ／２２３８・２２３８・２６３３の場合
１）割り込みモードを“２”にする。
（モード“０”でも良い）
２）ＮＭＩを立下りエッジにする。
（デフォルト）３）内部ＲＡＭ有効にする。
（デフォルト）ＳＨ／７０４５・７０５０・７０５１の場合
１）ＮＭＩを立下りエッジにする。
（デフォルト）２）内部ＲＡＭ有効にする。
（デフォルト）２５行：
Ｈ−ｄｅｂｕｇｇｅｒを使用する場合、この４００ｍｓソフトタイマを入れておいて下さい。
理由は、リセット＋Ｍｏｎコマンド発行時にデバッガは、リセット出力後２００ｍｓ後に２０ｍｓ
毎にターゲットにモニタが存在しているか調査しにいきます。
（リトライ２０回）
この時にモニタが存在した場合、その時点でＰＣ値を０ｘ８００に戻しプログラム停止状態にします。
４００ｍｓタイマーがない場合は、この例ですとＩ／Ｏおよびメモリの初期化が進み、ユーザープ
ログラムが最大２００ｍｓ走行後にプログラム停止状態になってからＰＣ値が０ｘ８００になります。
この動作が嫌な人は、ソフトタイマを付けてください。

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolPio2.c*/

6: /* ＜役割＞

PIO 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

9: /* ＜使用ﾊｰﾄﾞ＞ CAT-261-H8S/2612 エーワン(株)*/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 出力)38*/

34: /****************************************************************************/
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: }［リストの説明］ＰＩＯについては後章で説明しますので、ここでは省略します。

39*１）ヘッダーファイル（１）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: //**********************************************************
17: #define disable()asm("ldc.b #0x6,exr")

18: #define enable()asm("ldc.b #0x0,exr")

19: //**********************************************************
20: //

内部I/O

21: //**********************************************************
22: #define MCR(*(volatile char *)0x0FFF800)

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

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

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

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

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

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

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

41*３）ヘッダーファイル（２）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);*/42

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

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

３．保守ツール（Ｍａｋｅｆｉｌｅ）

１）第１章のＭａｋｅｆｉｌｅとの違いを見る
7: TARGET = Cat261p2.mot
8: OBJS= vectorA.o Startup.o Cat261p2.o PolPio2.o

28: Startup.o: Startup.c
29: $(CC) $(CCFLAGS) -fomit-frame-pointer $*.c
30: $(AS) -o $*.o $*.s
［リストの説明］
７〜８行：
プロジェクト名の変更およびモジュールの追加をしました。
２８〜３０行：
今回は、スタートアップをＣ言語で記述しましたので、各関数ヘッドのフレームポインタ部分を削除するために、コンパイラスイッチ“−ｆｏｍｉｔ−ｆｒａｍｅ−ｐｏｉｎｔｅｒ”を追加しました。
理由としては、Ｓｔａｒｔｕｐ関数の最初の命令をスタックポインタの設定にするためにこのスイッチが必要になりました。
逆アセンブラーで確認して見てください。

後章からは、７，８行の変更と追加のみでアプリケーションに対応していきますので、“Ｍａｋｅｆｉｌｅ”についての説明については、この章で終了とします。
43

２）ｍａｋｅの実行
前章と同じように、２０ｍｓ毎にシフト表示しているのを、１００ｍｓ毎に変更してみましょう“Ｃａｔ２６１ｐ２．ｃ”をエディタで開き
31:

while(1) {32:

SoftWait1ms(20);/* 20msWait

33:

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

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

SoftWait1ms(100);/* 100msWait*/

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

44

第３章 ＰＩＯ

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

まずは、ＤＥＦのダウンロードで￥評価ボード￥第１部ポーリング編￥第３章ＰＩＯ￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

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

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

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

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

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

どうです？ＬＥＤが対角線上で点灯したはずです。

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

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

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

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

46

２．プログラムリスト

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

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

“ＰｏｌＰｉｏ．ｃ”

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolPio.c*/

6: /* ＜役割＞

PIO 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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

Ｍｅｍ初期化

*/47

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

PioMemInitial(void)

28: {
29:

OutPort = 0;/* OUT Port 初期化

*/

30:

memset(InPort, 0,sizeof(InPort));/* IN

Port 現 Buffer

*/

31:

memset(UpPort, 0,sizeof(UpPort));/* IN

Port 立上り Buffer

*/

32:

memset(InBack, 0,sizeof(InBack));/* IN

Port 一ヶ前 Buffer

*/

33:

memset(In20ms, 0,sizeof(In20ms));/* IN

Port 20ms 前 Buffe

*/

34:

memset(InNows, 0,sizeof(InNows));/* IN

Port 生 Buffer

*/

35: }
36: /****************************************************************************/
37: /*

Ｉ／Ｏ初期化*/

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;

InNows[1] |= 1;

InNows[1] |= 2;

48

*/

62:

else

InNows[1] |= 4;

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]の読み取り
49*/

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

50

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

０ｍｓ

２０ｍｓ

４０ｍｓ

６０ｍｓ

８０ｍｓ

１００ｍｓ

時間軸

ハーﾄﾞ信号

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

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

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

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

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

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

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p3.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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:

disable();/* PBC の割込の為

*/

25:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

26:

/*

NMI 立下りエッジ

*/

27:

/*

RAME 有効*/28:

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

*/

29:

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

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

*/

31:

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

*/

32:

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

*/

33:

while(1) {
53

34:

SigInput();/* Signal Input Process

*/

35:

SoftWait1ms(20);

/*

*/

36:

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

*/

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

PioMemInitial();/* PIO

*/

47:
48:

Mem 初期化

49: }
50: /****************************************************************************/
51: /*

Ｉ／Ｏ初期化*/

52: /****************************************************************************/
53: void

IoInitial(void)

54: {
55:

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

56: }
57: /****************************************************************************/
58: /*

ModeCntrol()

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

59: /****************************************************************************/
60: void

ModeCntrol()

61: {
62:

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

if (ModeStep < 10)

ModeStep = 10;/* PIO

Goto TEST

*/

64:

else

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

*/

65:

}

66:

switch(ModeStep) {67:

case 0:68:

ModeStep++;

69:

break;/* PB[P30] ON?(立上)

54

*/

70:

case 1:

71:

RunRun();72:

break;

73:

case 10:/* PIO

74:

ModeStep++;

75:

break;

76:

*/

TEST

*/

case 11:77:

PioDemo();78:

break;

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

}

80: }
81:
82: /****************************************************************************/
83: /*

RunRun()

CPU 走行表示*/

84: /****************************************************************************/
85: void

RunRun()

86: {
87:

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

88:

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

*/

89: }
90: /****************************************************************************/
91: /*

SoftWait1ms()

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

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

SoftWait1ms(Ushort ms)

94: {
95:

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

Wait1ms();

97:

}

98: }
99: /****************************************************************************/
100: /*

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

101: /****************************************************************************/
102: void

Wait1ms()

103: {
104:

asm("

push.w r0

");

105:

asm("

mov.w

");

#5000,r055/* 5000*4=20000cyc */106:asm(" wait:

");

107:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

108:

asm("

bne

wait:16");/* 3 clock

*/

109:

asm("

pop.w

r0

");

110: }［リストの説明］

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

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

保守ツールについては、もうご理解したと思いますので、この章以降説明は省略します。
このサンプルで変更したい部分がありましたら各自変更をし、“ｍａｋｅ”を実行してみて下さい。

56

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

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

まずは、ＤＥＦのダウンロードで￥評価ボード￥第１部ポーリング編￥第４章ＰＩＯの応用（ＬＣＤ）￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

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

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

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

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

57

２．プログラムリスト

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

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

“ＰｏｌＰｉｏ．ｃ”

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

“ＰｏｌＬｃｄ．ｃ”

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

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolLcd.c*/

6: /* ＜役割＞

LCD 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

Makefile 参照*/

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

19: #define EMDCD

0x6

/*

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

20: #define FUKCD

0x38

/*

ﾌｧﾝｸｼｮﾝｾｯﾄ

*/21: #define DISON

0xc

/*

表示ｵﾝ

*/

22: #define DISOFF

0x8

/*

表示ｵﾌ

*/

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

変数宣言*/

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

Uchar

LcdBuf[2][16];/* LCD 表示 Buffer

*/

27:

Uchar

LcdReq;/**/

表示 要求ﾌﾗｸﾞ

28: /****************************************************************************/
29: /*

Ｍｅｍ初期化*/

30: /****************************************************************************/
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: /****************************************************************************/
5955: /*AllLcdDisp()

全画面表示

*/

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

91: void

Gotoxy(Uchar x,Uchar y)

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: {61

127:

PCDR |= 0x40;/* LCD RS

ON

*/

128:

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

129:

LcdCmd(data);

130:

PCDR &= ~0x40;/* LCD RS

OFF

*/

131:

SoftWait10us(4);/*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: }

62*/

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

機能

Ｄ０−Ｄ７

入出力

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

Ｅ

入力

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

Ｒ／Ｗ

入力

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

ＲＳ

入力

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

ＶＯ

電源

ＶＤ

電源

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

ＶＳ

電源

グランド端子：０Ｖ

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

ＲＳ

Ｔａｓ
Tas

：Ｍｉｎ ４０ｎｓ

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

Ｒ／Ｗ

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

Ｅ

Tdsw

Ｄ０−Ｄ７

有効データ

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

TcycE

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

63

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15 16

１行目 0001 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
図［４−２−３］ ＤＤ ＲＡＭアドレスマップ
コード
インストラクション

R/W

D7 D6 D5 D4 D3 D2 D1 D0

機能

実行時間
(max)

０ ０

0 0 0 0 0 0 0 1

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

1.64ms

RS

表示クリア
０ ０

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 の
内容は変化しません
データの書き込みおよび読み出し時に、カーソルの
進む方向、表示をシフトかの設定をする。

Ｂ＝１：カーソルオン

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

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

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

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

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

40us

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

ファンクションセット

４．１ｍｓ以上待つ

ファンクションセット

１００ｕｓ以上待つ

ファンクションセット

ファンクションセット

表示オフ

表示クリア

エントリーモードセット

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

65

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p4.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ Makefile 参照*/

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:

disable();/* PBC の割込の為

*/

25:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

26:

/*

NMI 立下りエッジ

*/

27:

/*

RAME 有効*/28:

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

*/

29:

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

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

*/

31:

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

*/

32:

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

*/

33:

while(1) {
67

34:

SigInput();/* Signal Input Process

*/

35:

SoftWait1ms(20);

/*

*/

36:

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

*/

37:

AllLcdDisp();/* LCD*/

38:

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

39:

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

全画面表示

*/

}

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

Ｍｅｍ初期化*/

43: /****************************************************************************/
44: void

MemInitial(void)

45: {
46:

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

*/

47:

Shift = 0;/* Led Disp Patan Initial

*/

49:

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

LcdMemInitial();/* LCDMem 初期化

*/

48:

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

Ｉ／Ｏ初期化*/

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

IoInitial(void)

56: {
57:

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

58:

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

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

ModeCntrol()

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

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

ModeCntrol()

64: {
65:

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

if (ModeStep < 10)

ModeStep = 10;/* PIO

Goto TEST

*/

67:

else

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

*/

68:

}

69:

switch(ModeStep) {/* PB[PA0] ON?(立上)

68

*/

70:

case 0:71:

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

GotoxyMemSet(0,1,"Polling73:

ModeStep++;

74:

break;

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

case 1:

76:

RunRun();77:

break;

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

case 10:/* PIO

79:

GotoxyMemSet(0,0,"PIO

80:

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

ModeStep++;

82:

break;

83:

*/

");

case 11:84:

PioDemo();85:

break;

86:

TEST

}

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

RunRun()

CPU 走行表示*/

90: /****************************************************************************/
91: void

RunRun()

92: {
93:

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

94:

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

*/

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

SoftWait1ms()

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

98: /****************************************************************************/
99: void

SoftWait1ms(Ushort ms)

100: {
101:

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

Wait1ms();

103:

}

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

106: /*

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

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

SoftWait10us(Ushort us)

109: {
110:

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

Wait10us();

112:

}

113: }
114: /****************************************************************************/
115: /*

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

116: /****************************************************************************/
117: void

Wait1ms()

118: {
119:

asm("

push.w r0

");

120:

asm("

mov.w

");

121:

asm(" wait:

122:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

123:

asm("

bne

wait:16");/* 3 clock

*/

124:

asm("

pop.w

r0

");

#5000,r0/* 5000*4=20000cyc */");125: }
126: /****************************************************************************/
127: /*

Wait10us()

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

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

Wait10us()

130: {
131:

asm("

push.w r0

");

132:

asm("

mov.w

");

133:

asm(" wait1:

134:

asm("

dec.w

#1,r0

135:

asm("

bne

136:

asm("

pop.w

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

*/

");

/* 1 clock*/

wait1:16");/* 3 clock

*/

r0

");

");

137: }

70

［リストの説明］

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

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

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

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

71

第５章 タイマ／カウンタ

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

まずは、ＤＥＦのダウンロードで￥評価ボード￥第１部ポーリング編￥第５章タイマ／カウンタ￥にディレクトリの移動をしておいて下さい。

72

１．動かしてみましょう

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

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

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

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

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

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

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

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

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

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

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

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

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

73

２．プログラムリスト

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

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

“ＰｏｌＰｉｏ．ｃ”

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

“ＰｏｌＬｃｄ．ｃ”

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

“ＰｏｌＴｉｍｅ．ｃ”

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

“ＣａｔＳｕｂ．ｃ”

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolTime.c*/

6: /* ＜役割＞

タイマ関係

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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

23:

short

BuzzerHz;/* Buzzer Hz*/

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

BuzzerTPU̲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 ｽﾀｰﾄ

*/

58:

}
75

59:

else {/* Buzzer OFF

*/

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: }

76

*/

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

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

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

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

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

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

５０％

５０％

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

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

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

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

になります
77

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

CatSub.c*/

6: /* ＜役割＞

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

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照

*/

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--) {
79

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;

80

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p5.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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:

disable();/* PBC の割込の為

*/

29:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

30:

/*

NMI 立下りエッジ

*/

31:

/*

RAME 有効

*/

32:
33:

SoftWait1ms(400);/* 400msWait(ﾘｾｯﾄ遅延時間ﾊｰﾄﾞ)*//* H-ﾃﾞﾊﾞｯｶﾞ<->Target 通信可能に成るまで*/
82

34:

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

*/

35:

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

*/

36:

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

*/

37:

while(1) {38:

SigInput();/* Signal Input Process

*/

39:

SoftWait1ms(20);

/*

*/

40:

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

*/

41:

AllLcdDisp();/* LCD*/

42:

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

43:

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

全画面表示

*/

}

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

Ｍｅｍ初期化*/

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

MemInitial(void)

49: {
50:

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

*/

51:

Shift = 0;/* Led Disp Patan Initial

*/

53:

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

54:

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

55:

TimMemInitial();/* TIM

Mem 初期化

*/

52:

56: }
57: /****************************************************************************/
58: /*

Ｉ／Ｏ初期化*/

59: /****************************************************************************/
60: void

IoInitial(void)

61: {
62:

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

63:

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

64:

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

65: }
66: /****************************************************************************/
67: /*

ModeCntrol()

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

68: /****************************************************************************/
69: void

ModeCntrol()8370: {
71:

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

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

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

*/

74:

else

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

*/

75:

Buzzer(0);/* 強制 OFF*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

76:

}

77:

switch(ModeStep) {78:

case 0:ModeStep = 10;

ModeStep = 0;79:

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

GotoxyMemSet(0,1,"Polling

81:

ModeStep++;

82:

break;

83:[PA0]");

case 1:

84:

RunRun();85:

break;

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

case 10:/* PIO*//* Timer TEST*/

GotoxyMemSet(0,0,"PIO

88:

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

ModeStep++;90:

break;");

case 11:92:

PioDemo();93:

break;

94:

case 20:95:

GotoxyMemSet(0,0,"Timer/Counter96:

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

BuzzerHz = 0;98:

ModeStep++;

99:

break;

100:");/* Buzzer Hz*/

case 21:101:

TimerDemo();102:

RunRun();103:

break;

104:

*/

TEST

87:

91:

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

105: }
84*/106: /****************************************************************************/
107: /*

RunRun()

CPU 走行表示*/

108: /****************************************************************************/
109: void

RunRun()110: {
111:

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

112:

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

113: }
114: /****************************************************************************/
115: /*

SoftWait1ms()

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

116: /****************************************************************************/
117: void

SoftWait1ms(Ushort ms)

118: {
119:

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

Wait1ms();

121:

}

122: }
123: /****************************************************************************/
124: /*

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

125: /****************************************************************************/
126: void

SoftWait10us(Ushort us)

127: {
128:

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

Wait10us();

130:

}

131: }
132: /****************************************************************************/
133: /*

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

134: /****************************************************************************/
135: void

Wait1ms()

136: {
137:

asm("

push.w r0

");

138:

asm("

mov.w

");

139:

asm(" wait:

140:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

141:

asm("

bne

wait:16");/* 3 clock*/#5000,r0/* 5000*4=20000cyc */

");

85

142:

asm("

pop.w

r0

");

143: }
144: /****************************************************************************/
145: /*

Wait10us()

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

146: /****************************************************************************/
147: void

Wait10us()148: {
149:

asm("

push.w r0

");

150:

asm("

mov.w

");

151:

asm(" wait1:

152:

asm("

dec.w

#1,r0

153:

asm("

bne

154:

asm("

pop.w

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

*/

");

/* 1 clock*/

wait1:16");/* 3 clock

*/

r0

");

");

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

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

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

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

86

第６章 ＳＣＩ

ここの章では、ＳＣＩのイニシャルとＳＣＩ使用サンプルの解説をします。
ＳＣＩ使用サンプルは、ポーリング送／受信の１バイトのループバック通信です。
ＳＣＩ０（送信）―＞ＳＣＩ１（受信）ＳＣＩ１（送信）―＞ＳＣＩ０（受信） の方式でループバックします。
まずは、ＤＥＦのダウンロードで、￥評価ボード￥第１部ポーリング編￥第６章ＳＣＩ￥にディレクトリの移動をしておいて下さい。

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

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

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

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

ＬＣＤ画面

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

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

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

“ＰｏｌＰｉｏ．ｃ”

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

“ＰｏｌＬｃｄ．ｃ”

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

“ＰｏｌＴｉｍｅ．ｃ”

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

“ＣａｔＳｕｂ．ｃ”

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

“ＰｏｌＳｃｉ．ｃ”

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

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

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolSci.c*/

6: /* ＜役割＞

SCI(SIO) 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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

*/

88

22: #define ODD

2

/*

ODD

*/

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: /*= ｷｬﾗｸﾀ[7,*8]

*/

ch

89

58: /*

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

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)90

94: {
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)
91

130: {
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) {/* RDRF+OE+FE+PE
92

ON ?

*/

166:

SoftWait1ms(1);/* 1ms*/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;
93

202:

case 3: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:

if (port & 0x4) {SciStep = 0;/* 停止中のみ受け付ける*//* PB[PC5] ON ? ﾎﾞﾚｰﾄ下げ?

*/

94

238:

if (SciSelect != 0) --SciSelect;

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: }

95*/

リストの説明に入る前に、ＳＣＩ関係資料を添付します。
チャネル

端子名

入出力

０

ＲＸＤ０
ＴＸＤ０
ＲＸＤ１
ＴＸＤ１

入力
出力
入力
出力

１

チャネル
０

機能
チャネル０の受信データ入力端子
チャネル０の送信データ出力端子
チャネル１の受信データ入力端子
チャネル１の送信データ出力端子

名 称

シンボル

シリアルモードレジスタ０
ビットレートレジスタ０
シリアルコントロールレジスタ０
トランスミットデータレジスタ０
シルアルステータスレジスタ０
レシーブデータレジスタ０
シリアルモードレジスタ１
ビットレートレジスタ１
シリアルコントロールレジスタ１
トランスミットデータレジスタ１
シルアルステータスレジスタ１
レシーブデータレジスタ１

１

ＳＭＲ＿０
ＢＲＲ＿０
ＳＣＲ＿０
ＴＤＲ＿０
ＳＳＲ＿０
ＲＤＲ＿０
ＳＭＲ＿１
ＢＲＲ＿１
ＳＣＲ＿１
ＴＤＲ＿１
ＳＳＲ＿１
ＲＤＲ＿１

アドレス
０ｘｆｆｆｆ７８
０ｘｆｆｆｆ７９
０ｘｆｆｆｆ７ａ
０ｘｆｆｆｆ７ｂ
０ｘｆｆｆｆ７ｃ
０ｘｆｆｆｆ７ｄ
０ｘｆｆｆｆ８０
０ｘｆｆｆｆ８１
０ｘｆｆｆｆ８２
０ｘｆｆｆｆ８３
０ｘｆｆｆｆ８４
０ｘｆｆｆｆ８５

表［６−２−１］ ＳＣＩの端子名とＩ／Ｏマップ
シリアルモードレジスタ（ＳＭＲ＿ｘ）
ﾋﾞｯﾄ 名前

初期値

R/W

７

C/A

０

R/W

６

CHR

０

R/W

５

PE

０

R/W

４

O/E

０

R/W

３

STOP

０

R/W

２

MP

０

R/W

１
０

CKS1
CKS0

０
０

R/W

機能
０：調歩同期モード
１：クロック同期式モード
０：データ長８ビット クロック同期では８ビット固定
１：データ長７ビット LSB ファースト固定
０：パリティディセーブル
１：パリティイネーブル
０：偶数パリティ（EVEN）
１：奇数パリティ（ODD）
０：１ストップビット
１：２ストップビット
０：マルチプロセッサ通信ディセーブル
１：マルチプロセッサ通信イネーブル
内蔵ボーレートジェネレートのクロックソース選択
００：φクロック
０１：φ／４クロック
１０：φ／１６クロック
１１：φ／６４クロック表［６−２−２］ シリアルモードレジスタ96シリアルコントロールレジスタ（ＳＣＲ＿ｘ）
ﾋﾞｯﾄ 名前

初期値

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

マルチプロセッサビットトランスファ機能表［６−２−４］ シリアルステータスレジスタ

97

［リストの説明］
１８〜１９行：
調歩同期式モードでの通信時、指定ボーレートを得るためにビットレートレジスタへ与える数値を求める計算式の定義です。

ＢＲＲ値＝（（システムクロック／３２）／ボーレート）−１［ＳＭＲへの内蔵ボーレートジェネレータのクロックソースをゼロ（φクロック）とする］［システムクロック＝２０．０ＭＨｚ］［ボーレート＝４８００，９６００，１９２００，３１２５０，３８４００］
２６行：
送受信をコントロールする変数宣言です。
２７行：
ボーレートを選択する変数宣言です。
２８行：
送信データを記憶する変数宣言です。
２９行：
受信データを記憶する変数宣言です。
３０〜３８行：
選択できるボーレートテーブルの変数宣言です。
４２〜４６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
５０〜５４行：
ＳＣＩ０を初期化する関数“ＲｓＯｐｅｎ０”を呼んでいます。
ＳＣＩ１を初期化する関数“ＲｓＯｐｅｎ１”を呼んでいます。
デフォルトで、９６００ｂｐｓ、８ビット、パリティＮＯＮの仕様にしています。
メインのＩ／Ｏ初期化の時に呼ばれます。
６２〜８５行：
ＳＣＩ０を初期化する関数です。
重要 モジュールストップコントロールレジスタのＳＣＩ０をオフ（開始）することをお忘れなく！
次にこの関数は、３個の引数を持っています。
第１引数は、ボーレート［２４００，４８００，９６００，１９２００，３８４００］
第２引数は、キャラクタ長［７，８］第３引数は、パリティ［０＝ＮＯＮ（ディセーブル） １＝偶数 ２＝基数］
ストップビットは、１ビット固定とします。
98

［６７行］
モジュールストップコントロールレジスタのＳＣＩ０をオフ（開始）しています。
［６８行］
スマートカードインタフェースをディセーブルにしています。
［７０〜７４行］
シリアルモードレジスタを設定するために、通信フォームの引数を分析して設定データを作成し設定しています。
［７６〜８１行］
ビットレートレジスタを設定するために、調歩同期式モードでの通信ボーレートを得るための数値を求め設定しています。
［８２行］
１ビット送信経過時間以上待っています。
［８３行］
シリアルステータスレジスタの“ＲＤＲＦ”＋“ＯＲＥＲ”＋“ＦＥＲ”＋“ＰＥＲ”をリセット
しています。
［８４行］
シリアルコントロールレジスタの“ＴＥ”＋“ＲＥ”をイネーブルにしています。
９３〜１１６行：
ＳＣＩ１を初期化する関数です。
重要 モジュールストップコントロールレジスタのＳＣＩ１をオフ（開始）することをお忘れな
く！
ＳＣＩ０の初期化と同じですので省略します。
１２０〜１２５行：
ＳＣＩ０の１バイトデータを送信する関数です。
１２９〜１３４行：
ＳＣＩ１の１バイトデータを送信する関数です。
１３８〜１５５行：
ＳＣＩ０の１バイトデータを受信する関数です。
ＲＤＲＦ（受信あり）か、受信エラーが発生するまで待つループには、２０ｍｓのソフトタイマーが入れてあります。
受信エラーが発生した場合は、エラーリセットコマンドを発行後、ｓｈｏｒｔ（−１）を返しています。
正常受信した場合は、受信データを呼び先へ返します。
１５９〜１７６行：
ＳＣＩ１の１バイトデータを受信する関数です。
ＳＣＩ０の１バイトデータを受信と同じですので省略します。
99

１８０〜２２１行：
ＳＣＩ０とＳＣＩ１の動作確認をするための関数です。
ＳＣＩ０／１の設定、１バイト送信、１バイト受信、送受信データの表示等を処理しています。

ＳＣＩ０（１バイト送信） ――――＞ ＳＣＩ１（１バイト受信）
ＳＣＩ１（１バイト送信） ――――＞ ＳＣＩ０（１バイト受信）の繰り返しをしています。
２２５〜２４７行：
ＳＣＩの動作確認をする場合、ＰＢ操作のコントロールを管理する関数です。

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p6.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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:

disable();/* PBC の割込の為

*/

30:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

31:

/*

NMI 立下りエッジ

*/

32:

/*

RAME 有効*/33:

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

*/

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

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*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

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:/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

case 10:/* PIO*//* Timer TEST*/

GotoxyMemSet(0,0,"PIO

92:

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

ModeStep++;

94:

break;");

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:

*/

TEST

91:

95:

/* PIO*/");/* Buzzer Hz

case 21:
TimerDemo();
103

*/

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

case 31:116:

SciDemo();

117:

RunRun();118:

break;

119:

8,n,1[PC2]");/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*/}

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)104

142: {
143:

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

Wait10us();

145:

}

146: }
147: /****************************************************************************/
148: /*

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

149: /****************************************************************************/
150: void

Wait1ms()

151: {
152:

asm("

push.w r0

");

153:

asm("

mov.w

");

154:

asm(" wait:

155:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

156:

asm("

bne

wait:16");/* 3 clock

*/

157:

asm("

pop.w

r0

");

#5000,r0/* 5000*4=20000cyc */");158: }
159: /****************************************************************************/
160: /*

Wait10us()

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

161: /****************************************************************************/
162: void

Wait10us()163: {
164:

asm("

push.w r0

");

165:

asm("

mov.w

");

166:

asm(" wait1:

167:

asm("

dec.w

#1,r0

168:

asm("

bne

169:

asm("

pop.w

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

*/

");

/* 1 clock*/

wait1:16");/* 3 clock

*/

r0

");

");

170: }

105

［リストの説明］ 前章のメインコントロールから追加された部分だけ解説します。
１８〜１９行：
このモジュールで使用する外部変数宣言を追加しました。
５７行：“ＰｏｌＳｃｉ．ｃ”で使用する変数の初期化関数を呼んでいます。
６７行：
ＳＣＩを初期化する関数を呼んでいます。
１０８〜１１８行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

以上で、この章の説明は終わりにします。
次は、ポーリングにおける総合デモ（メロディ）の解説へと進みます。

106

第 7 章 総合デモ（メロディ）

ここの章では、ポーリングでの総合デモ（メロディ）です。
評価ボードに付いているブザーを使い、チョットした演奏をします。

まずは、ＤＥＦのダウンロードで、￥評価ボード￥第１部ポーリング編￥第７章総合デモ（メロディ）￥にディレクトリの移動をしておいて下さい。

１．動かしてみましょう

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

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

もう馴れたと思いますので、ＬＣＤ表示の左上に“Ｍｅｌｏｄｙ”と表示がでるまで、
ＰＢ［ＰＡ０］を押して下さい。
ＬＣＤの下行 ＰＣ２［Ｍ］Ｆ７［ス］Ｃ５［セ］ と表示しているはずです。
ＰＣ２［Ｍ］は、マニュアルの意味です。

ＳＷ［Ｐ４０］−＞ＳＷＰ［４７］を、オン／オフしてみて下さい。
ド、レ、ミ……と音がするはずです。

ＰＢ［ＰＣ２］を押して下さい。
（モード変更）ＰＣ２［Ａ］と表示したはずです。
（Ａｕｔｏ演奏の意味）

107

ＰＢ［ＰＣ５］を押して下さい。
（選曲）
ネコフンジャッタ−＞イヌノオマワリサン−＞アマリリス（好きな曲で止めて下さい）

ＰＢ［ＰＦ７］を押して下さい（開始／停止）
演奏したはずです。
（音痴ですみません）

止めたい時は、どれかＰＢを長く押して下さい。
演奏の音の長さは、ポーリング記述のためソフトタイマを使用しています。
ソフトタイマ使用中は、他の処理は完全に停止してしまうため、ＰＢを長く押す必要があるわけです。
また、演奏中ＬＥＤが止まって見えるはずです、これもソフトタイマの影響です。
この現象を無くす方法は、第２部割込み編 で説明します。
この章では、総合デモ（メロディ）の簡単な説明をしたいと思います。

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

２．プログラムリスト

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

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

“ＰｏｌＰｉｏ．ｃ”

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

“ＰｏｌＬｃｄ．ｃ”

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

“ＰｏｌＴｉｍｅ．ｃ”

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

“ＣａｔＳｕｂ．ｃ”

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

“ＰｏｌＵｓａｒｔ．ｃ”

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

“ＰｏｌＭｅｌｏｄｙ．ｃ” メロディのコントロール部です。
“Ｃａｔ２０４ｐ．ｃ”

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

108１）メロディのコントロール部
file “PolMelody.c”
1: /****************************************************************************/
2: /*

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

PolMelody.c*/

6: /* ＜役割＞

デモ メロディー関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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 dO262/* ̲ド */

19: #define rE293/* ̲ﾚ */

20: #define mI330/* ̲ﾐ */

21: #define fhA

349/* ̲ﾌｧ */22: #define sO392/* ̲ｿ */

23: #define rA440/* ̲ﾗ */

24: #define sI494/* ̲ｼ */

25: #define do523/* ド */

26: #define 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:109

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,
110

*/

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: {
111

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;

}
}
112

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]);
}
113

*/

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 {
114

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: }

115

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

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

*/

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

*/

4: /*

*/

5: /* ＜MOD＞

Cat261p.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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:

disable();/* PBC の割込の為

*/

33:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

117

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 初期化

*/

118

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*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

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]");/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ

case 10:/* PIO*//* Timer TEST*/

GotoxyMemSet(0,0,"PIO

98:

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

ModeStep++;100:

break;

PioDemo();103:

break;

105:");

case 11:

102:

104:

*/

TEST

97:

101:

Goto TEST

case 1:

94:

96:/* PIO*/case 20:
GotoxyMemSet(0,0,"Timer/Counter

119

");

106:

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

BuzzerHz = 0;108:

ModeStep++;

109:

break;

110:

TimerDemo();112:

RunRun();113:

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

case 30:/* SCI TEST

115:

GotoxyMemSet(0,0,"SCI

116:

GotoxyMemSet(0,1,"09600b[+PF7-PC5]");

117:

SciStep

118:

SciSelect = 1;

119:

ModeStep++;

120:

break;

121:

*/

*/

8,n,1[PC2]");= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS*/

case 31:122:

SciDemo();123:

RunRun();124:

break;

125:*/

case 21:

111:

114:

/* Buzzer Hz

case 40:/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ*//* Demo Melody

*/

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

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: }
165: /****************************************************************************/
166: /*

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

167: /****************************************************************************/
168: void

Wait1ms()

169: {
170:

asm("

push.w r0

");

171:

asm("

mov.w

");

172:

asm(" wait:

173:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

174:

asm("

bne

wait:16");/* 3 clock

*/

175:

asm("

pop.w

r0

");

#5000,r0/* 5000*4=20000cyc */");176: }
177: /****************************************************************************/
121

178: /*

Wait10us()

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

179: /****************************************************************************/
180: void

Wait10us()

181: {
182:

asm("

push.w r0

");

183:

asm("

mov.w

");

184:

asm(" wait1:

185:

asm("

dec.w

#1,r0

186:

asm("

bne

187:

asm("

pop.w

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

*/

");

/* 1 clock*/

wait1:16");/* 3 clock

*/

r0

");

");

188: }［リストの説明］

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

２０〜２２行：
このモジュールで使用する外部変数宣言を追加しました。
６１行：“ＰｏｌＭｅｌｏｄｙ．ｃ”で使用する変数の初期化関数を呼んでいます。
７２行：“ＰｏｌＭｅｌｏｄｙ．ｃ”で使用するＩ／Ｏを初期化する関数を呼んでいます。
１２５〜１３６行：
この章のサンプルプログラムを動作させるための制御部分を追加しました。

これで、この章のリスト説明は終わりです。

自動演奏曲“ネコフンジャッタ”を聞いて気がついた方もいらしゃるかと思いますが、半音の登録をしていないため、チョット編曲をしてしまいました。
興味の有る方は、半音登録をして作りなおしてみて下さい。
これも、プログラムに慣れ親しむ方法として、よいことかもしれません。

この章の前半でも説明しましたが、全てポーリングで作成しているため動作および反応が鈍い部分があります。
このままで市場に出したらクレームになってしまいます。
この動作を改善するために、第２部 割込み編より修正を進めていきたいと思います。

122

第２部 割込み編
第１章 タイマ割込み

割り込みモード２は、Ｈ−ｄｅｂａｇｇｅｒがＨ８Ｓ／２６１２のハードトレース機能を使用するにあたり必要なモードです。
（他のモードでは、ハードトレースが機能しません）
それとＣＰＵ内部機能のＰＢＣ（ＰＣブレークコントローラ）とを組み合わせてデバッグ可能にしています。
（割り込みモード０の場合は、ソフトトレースとＰＢＣの組み合わせになります。
）
最初の章からＣＰＵに対して割り込みモード２の設定と割り込み要求マスクレベル（６以下）の設定は済んでいます。
（ＰＢＣ割り込みのプライオリティが７の為）
この章では、割り込みモード２を使用したアプリケーションをどのような手続きで追加するかをリストに沿って説明を進めていきます。
割り込み要因として、ＴＰＵ＿０での連続コンペアマッチにおける１０ｍｓ毎割り込み例を使用しました。なお、改造するサンプルの元は、“第１部ポーリング編−第７章総合デモ”で作成したサンプルを使用します。

動作仕様の変更はしませんので、この部より動作説明は省略しますが、￥評価ボード￥第２部割込み編￥第１章タイマ割込み￥にファイラーでディレクトリの移動をしておいて下さい。

＜補足説明＞
１）ハードトレースとは、ＣＰＵ機能が持っているトレース割り込みを利用した機能です。ただしこの機能を利用する場合は、割り込みモードを「２」にする必要があります。
２）ソフトトレースとは、ソフトにより次の実行命令を判定した後、ＰＢＣに次命令のアドレスを設定したトレース機能になります。このソフトトレースはＰＢＣ搭載したＣＰＵで、割り込み
モード０の場合とハードトレース機能が無い場合に使用します。

123

１．ベクターテーブルとスタートアップを割り込み用に変更する。

Ｈ８Ｓシリーズは、すべての割り込み要因に対し独立したベクタアドレスが割り当てられています
ので、要因別ベクタテーブルへの登録が必要になります。
又，モジュール別のインタラプトプライオリティレジスタも持っていますのでこの設定も必要になります。
リストの説明に入る前にインタラプトプライオリティレジスタ関連と、割り込み要求マスクレベルとの関係について説明します。

１）割り込みモード２の設定
システムコントロールレジスタ（ＳＹＳＣＲ）
ﾋﾞｯﾄ 名前

初期値

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

割り込み要求マスクレベル（０〜７）を指定します。

機能

表［２・１−１−２］

124３）インタラプトプライオリティの設定
レジスタ名
ＩＰＲＡ

７
０

ＩＰＲＢ

０

ＩＰＲＣ
ＩＰＲＤ

０
０

ＩＰＲＥ

０

ＩＰＲＦ

ビット
６〜４
３
ＩＲＱ０ （０〜７）の設定
０
ＩＲＱ２
ＩＲＱ３ （０〜７）の設定
ＷＯＶＩ０（０〜７）の設定

０
０
０

２〜０
ＩＲＱ１ （０〜７）の設定
ＩＲＱ４
ＩＲＱ５ （０〜７）の設定
ＤＴＣ（０〜７）の設定

０

ＡＤＩ

０

ＰＢＣ
（７）
の設定
（H-debugger で使用する）
ＴＰＵ＿０（０〜７）の設定（０〜７）の設定

０

ＴＰＵ＿１（０〜７）の設定

ＩＰＲＧ

０

ＴＰＵ＿２（０〜７）の設定

０

ＴＰＵ＿３（０〜７）の設定

ＩＰＲＨ
ＩＰＲＪ

０
０

ＴＰＵ＿４（０〜７）の設定

００ＴＰＵ＿５（０〜７）の設定
ＳＣＩ＿０（０〜７）の設定

ＩＰＲＫ

０

ＳＣＩ＿１（０〜７）の設定

０

ＳＣＩ＿２（０〜７）の設定

ＩＰＲＭ

０

ＨＣＡＮ （０〜７）の設定

０ＭＭＴ（０〜７）の設定

表［２・１−１−３］ ＩＰＲｘ
(1)ＥＸＲレジスタ”６”の状態で、ＰＢＣ以外の割り込みを不許可にしたい場合は、プライオリティ
を”６”もしくは各モジュールで割り込みをマスク状態にして下さい。
(2)ＥＸＲレジスタ”0”にしますと、全割り込み許可状態になります。

４）割り込み制御モード２の割り込み受け付けシーケンス
割り込み発生（要因 インタラプトプライオリティ）｛ｉｆ（割り込み ＝＝ ＮＭＩ）

割り込み受け付け（）；

ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ ７） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ６） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ ６） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ５） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
＜一部省略＞
ｅｌｓｅ ｉｆ（インタラプトプライオリティ ＝＝ １） ｛ｉｆ （割り込み要求マスクレベル ＜＝ ０） 割り込み受け付け（）
；
ｅｌｓｅ

保留（）
；

｝
｝
125

１）ベクターテーブルの変更箇所
file “vectorA.asm”
1: ;*******************************************************************************
2: ;*
3: ;* Ｈ８Ｓ デバッカモニター用ベクターテーブル(GNU/as)
4: ;*TYPE: H8S/2132.2134.2138.2612.2633F-ZTAT

5: ;*MODE: Advanced

6: ;*2002/03/14 by AONE M.Hasegawa

7: ;*******************************************************************************
8:.h8300s9:.file"vectorA.asm"

10:.extern

̲StartUp

11:.extern̲non

12:.extern

̲UserTGIA0

14:.section.vector＜＜＜ 省略 ＞＞＞
22: ;********************************************************
23: ;* ベクターテーブル
24: ;********************************************************
25: ̲VectorTable:;(共通/213x)(26xx)

26:

VECTOR

̲StartUp;* VCT( 0) RESET|

27:

VECTOR̲non;* VCT( 1) System 予約 1|＜＜＜ 省略 ＞＞＞
56:

VECTOR̲non;* VCT( 30) ﾘｻﾞｰﾌﾞ|

57:

VECTOR̲non;* VCT( 31) ﾘｻﾞｰﾌﾞ|

58:

VECTOR

̲UserTGIA0;* VCT( 32) ﾘｻﾞｰﾌﾞ|TPU̲0 TGIA̲059:

VECTOR̲non;* VCT( 33) ﾘｻﾞｰﾌﾞ|

TGIB̲0̲non;* VCT(127) ﾘｻﾞｰﾌﾞ

|

TEI2

＜＜＜ 省略 ＞＞＞
153:

VECTOR

154:.end［リストの説明］
５８行：
ＴＰＵ＿０のＴＧＩＡ＿０コンペアマッチ割り込み要因処理のＣ言語関数“ＵｓｅｒＴＧＩＡ０（）”のアドレスを登録しました。
126２）スタートアップの変更
file “Startup.c”
1: /****************************************************************************/
2: /* ＜サンプル＞

割り込み

*/

4: /*

＜MOD＞

Startup.c

*/

5: /*

＜タブ＞

４タブ編集

6: /*

GNU/gcc

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

7: /****************************************************************************/
8: /****************************************************************************/
9: /*StartUp*/

10: /****************************************************************************/
11: voidStartUp()

12: {
13:

asm("mov.l #0xffefbe,sp");/* ｽﾀｯｸﾎﾟｲﾝﾀ 設定

*/

14:

asm("jmp/* void ̲main()*/̲̲main");

15: }＜＜＜ 省略 ＞＞＞
25: /****************************************************************************/
26: /*

UserTGIA0*/

27: /****************************************************************************/
28: #pragma interrupt
29: void

UserTGIA0()

30: {
31:

TimerA0();32: }［リストの説明］２８〜３２行：
ＴＧＩＡ＿０コンペアマッチ割り込みハンドラ関数になります。
割り込み例外処理を示す“＃ｐｒａｇｍａ ｉｎｔｅｒｒｕｐｔ”を定義することのより、関数の入口／出口に全レジスターの退避／復帰命令が挿入され、かつリターン命令が“ＲＴＥ”になる便利な定義です。
Ｃ言語用記述での割り込みハンドラ雛型になります。
２．タイマモジュールを割り込み用に変更する。
ＴＰＵ＿０での連続コンペアマッチにおける１０ｍｓ毎割り込みを使用する場合、ＴＰＵ＿０の初127

期設定が必要になります。
また、割り込みハンドラから呼ばれる関数“ＴｉｍｅｒＡ０（）”も追加しました。
この関数は、タイマー割り込みを利用した内部ソフトタイマー機能を処理する役割になります。

リストの説明に入る前に、ＴＰＵ＿０関係資料を添付します。
タイマスタートレジスタ（ＴＳＴＲ）
ﾋﾞｯﾄ 名前

初期値

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

機能
０００：ＴＣＮＴ＿０のクリア禁止
００１：ＴＧＲＡ＿０のコンペアマッチでＴＣＮＴ＿０クリア
０１０：ＴＧＲＢ＿０のコンペアマッチでＴＣＮＴ＿０クリア
０１１：同期クリア／同期動作をしている他のクリアでクリア
１００：ＴＣＮＴ＿０のクリア禁止
１０１：ＴＧＲＣ＿０のコンペアマッチでＴＣＮＴ＿０クリア
１１０：ＴＧＲＤ＿０のコンペアマッチでＴＣＮＴ＿０クリア
１１１：同期クリア／同期動作をしている他のクリアでクリア
００：立上りエッジでカウント
０１：立下りエッジでカウント
１ｘ：両エッジでカウント
ＴＣＮＴ＿０のカウンタクロックソースの選択
０００：内部 φクロック
００１：
φ／４クロック
０１０：
φ／１６クロック
０１１：
φ／６４クロック
１００：外部 ＴＣＬＫＡ端子入力でカウント
１０１：
ＴＣＬＫＢ端子入力でカウント
１１０：
ＴＣＬＫＣ端子入力でカウント
１１１：
ＴＣＬＫＤ端子入力でカウント

表［２・１−２−２］ ＴＣＲ＿０
タイマインタラプトイネーブルレジスタ（ＴＩＥＲ＿０）
ﾋﾞｯﾄ 名前

初期値

R/W

機能
128

７

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

１（Ｒ）
：アンダーフローによる要求フラグです。
０（Ｗ）：要求フラグ解除になります。
１（Ｒ）：オーバーフローによる要求フラグです。
０（Ｗ）：ＴＣＦＶによる要求解除になります。
１（Ｒ）：ＴＰＵ＿０，３のＴＧＲＤによる要求フラグです。
０（Ｗ）：ＴＧＦＤによる要求解除になります。
１（Ｒ）：ＴＰＵ＿０，３のＴＧＲＣによる要求フラグです。
０（Ｗ）：ＴＧＦＣによる要求解除になります。
１（Ｒ）：ＴＧＲＢによる要求フラグです。
０（Ｗ）：ＴＧＦＢによる要求解除になります。
１（Ｒ）：ＴＧＲＡによる要求フラグです。
０（Ｗ）：ＴＧＦＡによる要求解除になります。

機能

表［２・１−２−４］ ＴＳＲ＿０
１）プログラムリスト

129file “IntrTime.c”
1: /****************************************************************************/
3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrTime.c*/

6: /* ＜役割＞

タイマ関係

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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));

36: }
37: /****************************************************************************/
130

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

BuzzerTPU̲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 ｽﾀｰﾄ*//* Buzzer OFF*//* ｶｳﾝﾄｸﾘｱ

*/

71:

}

72:

else {

73:

TCNT̲3 = 0;

131

74:
75:

TSTR &= ~0x8;/* TCNT̲3 ｽﾄｯﾌﾟ

*/

}

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;

110:
111:

}
}
132

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: }

133*/

［リストの説明］ 前章から変更のあった部分をおもに解説します。
２４〜２６行：
タイマー割り込みを利用した内部ソフトタイマー処理を追加しましたので、その処理に使用するフラグおよびカウンタの役目をする変数を宣言する。
３０〜３６行：
このモジュールで使用する変数の初期化関数です。
メインのメモリ初期化の時に呼ばれます。
４０〜５１行：
タイマ／カウンタを初期化する関数です。
メインのＩ／Ｏ初期化の時に呼ばれます。
ここでは、ＴＰＵ＿０とＩＰＲＦの初期化設定をします。
［４２行］
モジュールストップコントロールレジスタのＴＰＵをオフ（スタート）しています。
［４３行］
ＴＰＵ＿０のインタラプトプライオリティを“５”に設定しています。
別に意味はありません“６”以下でしたら構いません。
表［２・１−１−３］参照［４４行］
タイマコントロールレジスタの初期設定をしています。
１）ＴＧＲＡコンペアマッチでＴＣＮＴ＿０をクリアする。
２）立上りエッジでカウントする。
３）システムクロック（２０ＭＨｚ）の１／４でカウントする
表［２・１−２−２］参照［４７行］
タイマインタラプトイネーブルレジスタの設定をしています。
１）ＴＧＲＡのＴＧＦＡビットによる割り込み要求の許可をセット
表［２・１−２−３］参照［４８行］
カウンタＴＣＮＴ＿０をゼロにしています。
（必要ありませんが念のため）［４９行］
１００Ｈｚ（１０ｍｓ）に１回ＴＧＦＡが立つようにコンペアデータをＴＧＲＡ＿０に設定しています。
設定値（５００００）＝（（２０ＭＨｚ／４）／１００Ｈｚ）［５０行］
ＴＣＮＴ＿０のカウント動作指示をタイマスタートレジスタにセットしています。
表［２・１−２−１］参照
134

８０〜８８行：
タイマー割り込みを利用した内部ソフトタイマーのスタート関数です。
９２〜９５行：
タイマー割り込みを利用した内部ソフトタイマーのタイムアップしたかを調べる関数です。
９９〜１１３行：
タイマー割り込みを利用した内部ソフトタイマー処理関数です。
ＴＰＵ＿０のＴＧＩＡ＿０コンペアマッチ割り込み
タイマＢチャンル２のタイマー割り込み処理で“Startup.ｃ”の割り込みハンドラーから呼ばれています。
［１０３行］ＴＧＲＡのＴＧＦＡビットによる割り込み要求解除の意味でタイマーステータスレジスタのＴＧ
ＦＡビットをクリアしています。
連続割り込みが必要な場合は、必ずクリアして下さい。
表［２・１−２−４］参照

135

３．メインコントロール部を割り込み用に変更する。

割り込みを可能にするために必要な変更および、タイマー割り込みを利用した内部ソフトタイマーを利用するために、割り込み許可の挿入とメインループ処理の変更をしています

プログラムに沿って説明します。

１）プログラムリスト
file “Cat261i.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

Cat261i.c*/

6: /* ＜役割＞

main

*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞ makefile 参照*/

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;/* ﾓｰﾄﾞｺﾝﾄﾛｰﾙ用ｽﾃｯﾌﾟ
136

*/

27:

Uchar

Shift;/* shift ﾊﾟﾀｰﾝ*/28: /****************************************************************************/
29: /*

̲main()*/

30: /****************************************************************************/
31: void̲main(void) {32:

disable();/* PBC の割込の為

*/

33:

SYSCR = 0x21;/* ｼｽﾃﾑｺﾝﾄﾛｰﾗ 割込ﾓｰﾄﾞ 2

*/

34:

/*

NMI 立下りエッジ

*/

35:

/*

RAME 有効*/36:

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:

137

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*//* ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ

*/

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();/* ｼﾌﾄ LED 点灯 OUT ﾊﾞｯﾌｧｰにｾｯﾄ
138

*/

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

TimerDemo();

116:

RunRun();117:

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

case 30:/* SCI TEST

119:

GotoxyMemSet(0,0,"SCI

120:

GotoxyMemSet(0,1,"09600b[+PF7-PC5]");

121:

SciStep

122:

SciSelect = 1;

123:

ModeStep++;

124:

break;

125:

*/

*/

8,n,1[PC2]");= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ*//* 9600BPS*/

case 31:126:

SciDemo();127:

RunRun();128:

break;

129:*/

case 21:

115:

118:

");

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

case 40:/* Demo Melody

*/

*/

130:

GotoxyMemSet(0,0,"Melody

");

131:

GotoxyMemSet(0,1,"PC2[M]F7[ｽ]C5[ｾ]");132:

MelStep= 0;/* ｺﾝﾄﾛｰﾙｽﾃｯﾌﾟ

*/

133:

MelMode= 0;/* 演奏ﾓｰﾄﾞ

*/

134:

MelSelect = 0;/* 自動選曲

*/

139

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: }
169: /****************************************************************************/
170: /*

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

171: /****************************************************************************/
172: void

Wait1ms()

173: {
174:

asm("

push.w r0

");

175:

asm("

mov.w

");

176:

asm(" wait:

177:

asm("

dec.w

#1,r0

");

/* 1 clock

*/

178:

asm("

bne

wait:16");/* 3 clock

*/

179:

asm("

pop.w

r0

");

#5000,r0/* 5000*4=20000cyc */");180: }
181: /****************************************************************************/
182: /*

Wait10us()

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

183: /****************************************************************************/
184: void

Wait10us()185: {
186:

asm("

push.w r0

");

187:

asm("

mov.w

");

188:

asm(" wait1:

189:

asm("

dec.w

#1,r0

190:

asm("

bne

191:

asm("

pop.w

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

*/

");

/* 1 clock*/

wait1:16");/* 3 clock

*/

r0

");

");

192: }

141

［リストの説明］ 前章から変更のあった部分をおもに解説します。
４１行：
チャタリング防止タイマーに、タイマー割り込みを利用した内部ソフトタイマーの利用に変更しま
すので、ここでスタートをかけておきます。
４２行：
ここで、割り込み許可“ｅｎａｂｌｅ（）”をします。
割り込み要求マスクレベルをゼロ（０）にしています。 “ｉｏ２６１ｘ．ｈ”を参照
逆を言えば、ここに来るまでに割り込み関数で使用するＩ／Ｏおよび変数は初期化ずみであることが必要になります。
４４〜４５行：
チャタリング防止タイマがタイムアップするのを待ちます。
いままで使用していたソフトタイマと違い、待っている間は他処理の実行が可能になっています。
４６〜最終行：変更なし。

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

ＤＥＦでダウンロード後、プログラム実行をして下さい。

“Ｃａｔ２６１ｉ１．ｍｏｔ”です

次章は、ＳＣＩ割り込みに挑戦します。

142

第２章 ＳＣＩ割込み

ここの章では、ＳＣＩの送受信を割り込みで処理する場合どのような手続きが必要かをリストに沿って説明を進めていきます。
また、送受信フォームを文字列通信に変更しましたので、文字列扱いを容易にするため簡単なプロト
コルでの通信仕様にしました。

［プロトコル仕様］

ＳＴＸ“文字列〜１４文字まで”ＥＴＸ ＳＴＸ＝０ｘ０２（スタート）
ＥＴＸ＝０ｘ０３（エンド）ＳＣＩ０（文字列送信）―＞ＳＣＩ１（文字列受信）ＳＣＩ１（文字列送信）―＞ＳＣＩ０（文字列受信） の方式でループバック通信を繰り返します。

￥評価ボード￥第２部割込み編￥第２章ＳＣＩ割込み￥に、ファイラーでディレクトリ移動をしておいて下さい。

143１．ベクターテーブルとスタートアップをＳＣＩ割り込み用に変更する。
１）ベクターテーブルの変更箇所
file “vectorA.asm”
1: ;*******************************************************************************＜＜＜ 省略 ＞＞＞
26: ;********************************************************
27: ;* ベクターテーブル
28: ;********************************************************
29: ̲VectorTable:;(共通/213x)(26xx)＜＜＜ 省略 ＞＞＞
109:

VECTOR̲non;* VCT( 79) ﾘｻﾞｰﾌﾞ

|

110:

VECTOR

̲UserRXI0;* VCT( 80) SCI0 ERI0 |111:

VECTOR

̲UserRXI0;* VCT( 81)

RXI0 |

112:

VECTOR

̲UserTXI0;* VCT( 82)

TXI0 |

113:

VECTOR̲non;* VCT( 83)

TEI0 |

114:

VECTOR

̲UserRXI1;* VCT( 84) SCI1 ERI1 |115:

VECTOR

̲UserRXI1;* VCT( 85)

RXI1 |

116:

VECTOR

̲UserTXI1;* VCT( 86)

TXI1 |

117:

VECTOR̲non;* VCT( 87)

TEI1 |＜＜＜ 省略 ＞＞＞
154:

.end

［リストの説明］
１１０〜１１１行：
ＳＣＩ０のＥＲＩ０（受信エラー）とＲＸＩ０（受信完了）の割り込み要因処理時のＣ言語関数“Ｕ
ｓｅｒＲＸＩ０（）”のアドレスを登録しました。
１１２行：
ＳＣＩ０のＴＸＩ０（送信データエンプティ）の割り込み要因処理時のＣ言語関数“ＵｓｅｒＴＸＩ０（）”のアドレスを登録しました。
１１４〜１１５行：
ＳＣＩ１のＥＲＩ１（受信エラー）とＲＸＩ１（受信完了）の割り込み要因処理時のＣ言語関数“Ｕ
ｓｅｒＲＸＩ１（）”のアドレスを登録しました。
１１６行：
ＳＣＩ１のＴＸＩ１（送信データエンプティ）の割り込み要因処理時のＣ言語関数“ＵｓｅｒＴＸＩ１（）”のアドレスを登録しました。
144２）スタートアップの変更
file “Startup.c”
1: /****************************************************************************/
2: /* ＜サンプル＞

割り込み

*/

3: /*

*/

4: /*

＜MOD＞

Startup.c

5: /*

＜タブ＞

４タブ編集

6: /*

*/
GNU/gcc

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

7: /****************************************************************************/
8: /****************************************************************************/
9: /*StartUp*/

10: /****************************************************************************/
11: voidStartUp()

12: {
13:

asm("mov.l #0xffefbe,sp");/* ｽﾀｯｸﾎﾟｲﾝﾀ 設定

*/

14:

asm("jmp/* void ̲main()*/̲̲main");

15: }＜＜＜ 省略 ＞＞＞
33: /****************************************************************************/
34: /*

UserRXI0*/

35: /****************************************************************************/
36: #pragma interrupt
37: void

UserRXI0()

38: {
39:

Rxi0();

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

UserTXI0*/

43: /****************************************************************************/
44: #pragma interrupt
45: void

UserTXI0()

46: {
47:

Txi0();

48: }
49: /****************************************************************************/
145

50: /*

UserRXI1*/

51: /****************************************************************************/
52: #pragma interrupt
53: void

UserRXI1()

54: {
55:

Rxi1();

56: }
57: /****************************************************************************/
58: /*

UserTXI1*/

59: /****************************************************************************/
60: #pragma interrupt
61: void

UserTXI1()

62: {
63:

Txi1();

64: }［リストの説明］３６〜４０行：
ＳＣＩ０のＥＲＩ０（受信エラー）とＲＸＩ０（受信完了）の割り込みハンドラ関数です。
４４〜４８行：
ＳＣＩ０のＴＸＩ０（送信データエンプティ）の割り込みハンドラ関数です。
５２〜５６行：
ＳＣＩ１のＥＲＩ１（受信エラー）とＲＸＩ１（受信完了）の割り込みハンドラ関数です。
６０〜６４行：
ＳＣＩ１のＴＸＩ１（送信データエンプティ）の割り込みハンドラ関数です。

146

２．ＳＣＩモジュールを割り込み用に変更する。

割り込みに対応するため、割り込み用送受信関数が必要になります。
また、ポーリング時は１文字での送受信ループバック動作でしたが、今回は割り込みサンプルですので、文字列での送受信ループバック連続動作をさせてみます。

プログラムに沿って説明します。

１）プログラムリスト
file “IntrSci.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrSci.c*/

6: /* ＜役割＞

SCI(SIO) 関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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/* 送信スタートコード147*/

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

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)

*/

149

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

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 ｲﾝﾀﾗﾌﾟﾄﾃﾞｨｾｰﾌﾞﾙ

151

*/

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 {/* 受信データ
152

*/

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 操作ｺﾝﾄﾛｰﾙ
153

*/

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);154

確認用の表示データ作成

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: }

155*/

［リストの説明］ 前章に変更を加えた個所を説明します。
２５〜２６行：
文字列データの最初と最後を示すコードのシンボル定義です。
３２〜３７行：
ＳＣＩ０の送受信割り込み関数で使用する変数の宣言です。
３８〜４３行：
ＳＣＩ１の送受信割り込み関数で使用する変数の宣言です。
８２行：
ＳＣＩ０のインタラプトプライオリティを“６”に設定しています。表［２・１−１−３］参照
９９行：
ＳＣＩ０の送受信を割り込み処理にする場合、初期化の段階では送信はディセーブル状態にしておく必要があります。
１１４行：
ＳＣＩ１のインタラプトプライオリティを“６”に設定しています。表［２・１−１−３］参照
１３１行：
ＳＣＩ１の送受信を割り込み処理にする場合、初期化の段階では送信はディセーブル状態にしておく必要があります。
１３６〜１４７行：
ＳＣＩ０の送受信割り込みを開始させる関数です。
１３８〜１４２行は、文字列送信を割り込みで処理するための準備です。
準備が終了後、最初の１文字を“ＴＤＲ”にセットし、“ＴＤＲＥ＝０”によりＴＳＲに転送後、“Ｔ
ＩＥ＝１”により送信データエンプティ割り込み要求を許可しています。
あと残りの文字列データは、送信データエンプティ割り込み処理内で要求が発生するたびに１文字ごと送信をさせます。
１５１〜１６２行：
ＳＣＩ１の送受信割り込みを開始させる関数です。ＳＣＩ０の仕様と同じですので省略します。
１６６〜１７５行：
ＳＣＩ０の１バイト毎の送信データエンプティ割り込みのハンドラより呼ばれる関数です。
１バイト毎に“ＴＤＲ”にセットし、“ＴＤＲＥ＝０”によりＴＳＲに転送後、内部管理変数を調整して終了しています。
送信するデータがなくなった場合は、送信データエンプティ割り込み要求を禁止して割り込みを止めています。
１７９〜１８８行：
ＳＣＩ１の１バイト毎の送信データエンプティ割り込みのハンドラより呼ばれる関数です。
ＳＣＩ０の仕様と同じですので省略します。

156

１９２〜２１０行：
ＳＣＩ０の受信エラーと受信完了の割り込みハンドラより呼ばれる関数です。
１バイト毎の受信完了もしくは受信エラー発生で割り込みが発生します。
シリアルステータスレジスタを監視をおこない、正常時の受信データ処理をします。
受信データがＳＴＸ“￥ｘ０２”の場合、テキストスタートと判断して、内部インデックスをゼロ（０）にします。
受信データがＥＴＸ“￥ｘ０３”の場合、テキスト終了と判断して、受信終了フラグを立てます。
その他の受信データは、内部受信バッファーにセットしていきます。
エラーが発生時は、エラーリセット後内部インデックスカウンタをクリアにしています。
２１４〜２３２行：
ＳＣＩ１の受信エラーと受信完了の割り込みハンドラより呼ばれる関数です。
ＳＣＩ０の仕様と同じですので省略します。
２３６〜２８６行：
ＳＣＩ０とＳＣＩ１の動作確認用の関数です。
文字列送信後、文字列受信の終了を待ち,終了後ＬＣＤに表示させています。
この動作を、ＰＢ［ＰＣ２］ＯＮか、もしくはエラー発生するまで繰り返します。
無応答判定も、タイマー割り込みを利用した内部ソフトタイマを使用しましたので、ポーリング時に使用していたループソフトタイマを排除しました。

以上の３ファイルの変更で、ＳＣＩ割り込み対応のシステムに変貌したわけです。
ＤＥＦでダウンロード後、プログラム実行をしてみて下さい。

送信データは、“ＩｎｔｅｒｒｕｐｔＳＣ”の文字列を 1 文字ずつ空けて分けて送信しています。
［ＳＣＩ０＝“Ｉ ｔ ｒ ｕ ｔ Ｃ”］

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

各チャンネルでの受信データは、ＬＣＤの１行目に表示しますので、正常受信していますと重なり合い文字として読み取れるようになっていると思います。
ここまでの変更では、メロディの割り込み対応は済んでいません。
次章は、メロディの割り込み対応にし、より良いシステムに変貌させたいと思います。
157

第３章 割込み総合デモ（メロディ）

いよいよ、前章までに築き上げた割り込みシステムを利用した、応用例として割込み総合デモ（メロディ♪♪）のアプリケーション作り上げの最終解説となりました。

リストに沿って説明を進めていきます。
￥評価ボード￥第２部割込み編￥第３章割込み総合デモ（メロディ）￥にディレクトリの移動をしておいて下さい。

１．総合デモ（メロディ）を割り込み対応にする。

ここで残された問題は、リズム（音の長さ）を調整している部分が、いまだにソフトタイマー（ループ式）を利用していることです。
これがシステムの反応（スイッチ入力反応）を鈍らせている原因です。ここを改善します。

１）プログラムリスト
file “IntrMelody.c”
1: /****************************************************************************/
2: /*

*/

3: /* ＜サンプル＞ 割込み

*/

4: /*

*/

5: /* ＜MOD＞

IntrMelody.c*/

6: /* ＜役割＞

デモ メロディー関係*/

7: /* ＜TAB＞

４タブ編集

*/

8: /* ＜保守ﾂｰﾙ＞

makefile 参照*/

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 dO262/* ̲ド */
158

19: #define rE293/* ̲ﾚ */

20: #define mI330/* ̲ﾐ */

21: #define fhA

349/* ̲ﾌｧ */22: #define sO392/* ̲ｿ */

23: #define rA440/* ̲ﾗ */

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: {

159

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();/* ﾒﾛﾃﾞｨｰ操作ｺﾝﾄﾛｰﾙ
160

*/

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");
161

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) {

162

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()163

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: }
164

［リストの説明］ 前章に変更を加えた個所を説明します。

２１２行： ２１８行： ２２３行： ２２９行：
自動演奏のソフトタイマ使用部分を、タイマ割り込みを利用した内部ソフトタイマに変更しました。
これで、通常動作時のソフトタイマ（ループ方式）使用は、全て排除したかたちになりました。

どの程度、動作がスムーズになったか、動かして確認して見ましょう。
ＤＥＦでダウンロード後、プログラム実行をして下さい。

いかがですか？
自動演奏を実行した時にＬＥＤが止まらないでしょう！
（止まるのも味があるのですが、今回の目的とは違います）
それに、いつＰＢ［Ｐｎｎ］を押しても即反応するでしょう！
これでシステムの反応が良くなりました。これが割り込み処理を導入したことによるメリットです。
しかし、このシステムは改造する部分（半音が入っていない等…）が、まだあると思います。
どうぞ改造にチャレンジして、より良いシステムに構築してみて下さい！！ 期待しています。

これで、この解説テキストの終了とします。
この内容で満足して頂いたとは思いませんが、皆様のご協力で成長させていきたいと思っています。
メールで頂いたご意見、ご質問を、出来る限り反映させ、より良い解説テキストにしていきたいと考えていますので、ご指導の程よろしくお願い致します。

２００２年 ４月 著者

165