◆ PTA3 と PTA1 を使うための回路構成を決める
実際に使ってみるにあたって、回路構成を決める必要があります。せっかくここまで順番に勉強してきているので、前回の最後に提示した構成でいくことにします。回路を再掲します。
PTA3 は内部プルアップを有効にする
上記の回路はプッシュ・スイッチ/LED/抵抗を各1個ととても簡単なので、ユニバーサル基板(穴開き基板)でもブレッドボードでもすぐに準備できると思います。しかし、ちょっと待ってください。HC08スタータ・ボード・キットには、ボード上にこれらの部品が用意されているのでした。 HC08スタータ・ボードの回路図から該当する部分を抜き出したものを下図に示します。 よくみるとプルアップ抵抗に相当するものが付いていますが、練習のためにマイコン内部のプルアップ抵抗を有効にして使うことにします。このくらいの抵抗値なら外部と内部の両方に付けても問題ありません。
ジャンパJP5 と JP6 は普段からジャンパ・リンクを取り付けてショートさせてあると思います。プッシュ・スイッチと直列に 1kΩの抵抗が入っていますが、内部プルアップ抵抗の約26kΩ(Min 16kΩ,Max 36kΩ)と外部の RA1 との合成抵抗を考慮しても、問題ない程度に小さいので気にしなくてもよいです。どうしてもこの 1kΩの抵抗を入れてある意味を知りたい方は、第6回 の最後で理由を説明してあるので参照してみてください。
HC08スタータ・ボードの全回路図 をまだ出していなかったので、ここで掲載しておきます(クリックで拡大)。第4回 で紹介したキットの製作マニュアル 9ページの回路図と同じものです。
HC08スタータ・ボードの全回路図
用意されたジャンパを使ってボード上のデバイスを有効/無効と使い分けることができます。また、CN2, CN3 の拡張用コネクタ(未実装)を利用して外部の回路へ接続する場合はボード上のデバイスが接続されていないほうが都合がよいこともあるので、それにも対応できるようになっています。
◆ ポートAを使うためのレジスタ操作を覚える
回路構成が決まったところで、次はレジスタの操作を学習しましょう。ここからはプログラミングの話になりますので、具体的な動作仕様を決めて取り掛かったほうがやりやすくなります。というわけで、次の 【 仕様1 】 で進めることにします。
【 仕様1 】
プッシュ・スイッチを押していないときは LED が消灯。
プッシュ・スイッチを押しているときは LED が点灯。
先ほどの回路構成と合わせて要求分析をすると、次のようになります。
【 要求分析1 】
初期設定を行う。
PTA3 を入力ポートにして、内部プルアップを有効にする。
PTA1 を出力ポートにする。
処理・・・・・以下を繰り返す。
PTA3 が 1 ならば PTA1 を 1 にする。
PTA3 が 0 ならば PTA1 を 0 にする。
ここまでよろしいでしょうか? 次は、これを元にしてプログラミングを行います。慣れてしまえばアセンブリ言語よりもC言語のほうが読み書きがラクですから、C言語で説明することにします。 やり方が何通りかあります。 もう気付いている方も多いでしょうが、一つはすでに紹介したもので、第6回のテスト・プログラムがそれに当たります。入出力ポートの操作に関しては、ここでしっかり理解しておきましょう。
【 プログラム例1A 】
void main( void ){
EnableInterrupts;
PTAPUE_PTAPUE3 = 1; // ← PTA3 プルアップ有効
DDRA_DDRA1 = 1; // ← PTA1 を出力に設定
for ( ; ; ){
__RESET_WATCHDOG( );
PTA_PTA1 = PTA_PTA3; // ← 値をコピー
}
}
今回はプログラム・リスト中の黒い文字で書かれた部分は説明しません。
それでは最初に、初期設定に当たる部分から説明します。 第16回 のレジスタの説明を復習しながら読んでください。
PTAPUE レジスタのビット3 は、PTAPUE_PTAPUE3 と記述します(MC68HC908QY4A.h ヘッダ・ファイルで定義されている)。そのビットを 1 にするには、PTAPUE_PTAPUE3 = 1; と書きます。セミコロンを忘れないようにしてください。 その他のビットはリセット後の状態(つまり 0)になっています。これで PTA3 の内部プルアップ抵抗が有効になります。
DDRA レジスタのビット 1 は、DDRA_DDRA1 と記述します。そのビットを 1 にするには、DDRA_DDRA1 = 1; と書きます。その他のビットはリセット後の状態(つまり 0)になっています。 これで PTA1 が出力ポートになります。
次は for 文(フォーぶん)で繰り返す部分です。
PTA レジスタは、各ビットに対応するピン(端子)が入力ポートでも出力ポートでも、読み書きすることができます。その内容と動作は、第16回ですでに説明したとおりです。
PTA レジスタのビット1 は PTA_PTA1 と記述します。同様に PTA レジスタのビット3 は PTA_PTA3 と記述します。 PTA3 が 1 のとき PTA1 を 1 にして、PTA3 が 0 のとき PTA1 を 0 にするということは、単純に値をコピーすればよいということになります。そこで、PTA_PTA1 = PTA_PTA3; と書くことができます。右辺から左辺へコピーされます。
ほかの書き方の例を見ておきましょう。こんなふうにも書けます。
【 プログラム例1B 】
void main( void ){
EnableInterrupts;
PTAPUE = 0x08; // ← PTA3 プルアップ有効
DDRA = 0x02; // ← PTA1 を出力に設定
for ( ; ; ){
__RESET_WATCHDOG( );
if ( PTA_PTA3 == 1 ){ // ← PTA3 が 1 ならば
PTA_PTA1 = 1;
} else { // そうでないならば
PTA_PTA1 = 0;
}
}
}
初期設定の部分をビット単位ではなくバイト単位で書き込むようにしました。 PTAPUE = 0x08; というのは二進数でいえば 00001000b を入れることになるので、レジスタの説明を読めば意味がわかるはずです(一般に二進数の末尾には binary の b を付ける習慣がある)。 同様に DDRA = 0x02; というのは二進数でいえば 00000010b を入れることになるので、これもレジスタの説明を読めば意味がわかるはずです。 ちなみに正式な(ANSI 準拠の) C言語では二進数表記はできません。コンパイラによっては許しているものもありますが、特別な理由がある場合を除いてあまり使わないほうがよいでしょう。
さて次の部分は、ずいぶん形が変わりましたね。if 文(イフぶん)が出てきました。if 文の使い方は 大雑把にいえば 次の2パターンになります。
if ( 式 ){
文;
}
式 を評価して、それが 真(しん) であれば、その後の 文 を実行します。 偽(ぎ) であれば、その 文 を実行しません。
もう一つのパターンは、このようなものです。
if ( 式 ){
文1;
} else {
文2;
}
式 を評価して、それが 真 であれば、文1 を実行し、 文2 は実行しません。 偽 であれば、 文1 は実行せず、 文2 を実行します。
ほかに else if ( ) のような書き方もありますが、これも後者の分類に含めることができます。
いきなり 真 とか 偽 といわれても困るでしょうから、簡単に説明しておきます。 このプログラムのように、if ( A == B ) と書いた場合は、カッコの中は比較の意味になります。そして、A と B が等しいときに 真 となります。等しくないときは 偽 となります。
また、== などのようなものがなく、 if ( A ) と書かれていた場合は、カッコの中の A の値そのものを評価します。この場合は、 A が 0 のとき 偽 となり、0 以外のときは 真 となります。 1 だけでなく、3 とか -1 のときも真になるので注意が必要です。
そんなわけで、プログラム例1Bの
if ( PTA_PTA3 == 1 ){
PTA_PTA1 = 1;
} else {
PTA_PTA1 = 0;
}
の部分は、次のようにも書けます。
if ( PTA_PTA3 == 0 ){
PTA_PTA1 = 0;
} else {
PTA_PTA1 = 1;
}
あるいは、
if ( PTA_PTA3 ){
PTA_PTA1 = 1;
} else {
PTA_PTA1 = 0;
}
否定の演算子 「 ! 」 (真・偽を反対にする)を使って、
if ( !PTA_PTA3 ){
PTA_PTA1 = 0;
} else {
PTA_PTA1 = 1;
}
とも書けます。 ついでにもう一つ、
if ( PTA & 0x08 ){
PTA |= 0x02;
} else {
PTA &= 0xFD;
}
と書くこともできます。最後の方法は一応紹介しましたが、ちょっとした仕様変更ですぐにバグを作ってしまう可能性があるのであまりお勧めしません。いずれにしても少し説明が必要だと思うのですが、それはまたいつか別な機会ということにしましょう。
【 ちょっとした応用の話 】
否定の演算子を使って、
PTA_PTA1 = PTA_PTA3; // ← 値をコピー
というのを
PTA_PTA1 = !PTA_PTA3; // ← 値を反転してコピー
のように変更して使うこともできます。ただしこの場合は動作が変わり、スイッチを押していないときに LED が点灯します(下記の仕様2に相当)。
今回はいろいろな方法を説明しました。第6回と第7回のテスト・プログラムを少し変更して、実際に動かして試してみてください。また、次のような 【 仕様2 】 について、いくつかの方法で実現してみてください。
【 仕様2 】
プッシュ・スイッチを押していないときは LED が点灯。
プッシュ・スイッチを押しているときは LED が消灯。
ここでちょっとおことわり・・・この連載はC言語教室ではありませんから、厳密な部分の話はわざと避けて書いています。あいまいな記述がある点はご容赦ください。
次回は、もうちょっと実践的な内容を予定しています。エレキジャックNo.8 付録のブレッド・ボードを使って、ポートBにいろいろな物(DIPスイッチ,複数のLED,LCDモジュール)を接続して動かす実験を行います。
『参考文献』
「試しながら学ぶHC08マイコン入門」 (CQ出版)
第1章 マイコン電子工作を始めよう
第10章 統合開発環境CodeWarriorを使ってみる
Appendix F KMC908QY4Aユーザ・モード・モニタ入りマイコンの知識
筆者のホームページ 『マイコン工作の実験室』
組み込みエンジニア 川野亮輔
