ポートを使いこなし、いざ制御プログラミングの世界へ:イチから作って丸ごと学ぶ! H8マイコン道(8)(3/3 ページ)
制御システムの基本といえるスイッチとLEDによる入出力回路の動作を理解したうえで、C言語によるポート制御を行う!!
――C言語によるポート制御ができるようになって、健一君もいろいろと興味がわいてきたようです。でも、健一君のいうとおり、プログラムの先頭にある「#define」が分からないと完全理解とはいえません。そこには、C言語の「ポインタ(pointer)」テクニックが生かされているのです。
ポインタでメモリの操作は自由自在
ここまでの解説で、H8マイコンのポート操作はポートコントロールレジスタとポートデータレジスタの2種類のI/Oレジスタにより行われることが分かりました。では、これらのI/Oレジスタはどこにあるのでしょうか?
そう、その答えは「メモリ」です。
H8/3664のハードウェア・マニュアルを調べてみると、図5のようなメモリマップが見つかります。このメモリマップには、H8マイコンに内蔵されているROMやRAMが、メモリのどの番地にあるかが示されています。
H8/3664Fの場合、(0)16番地から(7FFF)16番地までがROM領域、(F780)16番地から(FF7F)16番地までがRAM領域です。そして、(FF80)16番地からの内蔵I/Oレジスタ領域に、ポートなどの周辺機能を操作するI/Oレジスタが配置されています。つまり、ポートコントロールレジスタとポートデータレジスタはここにあるのです。
H8マイコンのように、メモリ空間の一部分にI/Oレジスタを配置することを「メモリマップドI/O」と呼びます。メモリマップドI/Oの利点は、I/Oレジスタをメモリと同等にアクセスできることです。つまり、I/OレジスタのアクセスにC言語のポインタが使えます。
実際に各ポートへアクセスするために、H8Tiny-USBで使用するポートコントロールレジスタとポートデータレジスタの番地を表2に示します。
レジスタ名称 | 略称 | ビット数 | アドレス |
---|---|---|---|
ポートデータレジスタ1 | PDR1 | 8 | FFD4 |
ポートデータレジスタ5 | PDR5 | 8 | FFD8 |
ポートデータレジスタ8 | PDR8 | 8 | FFDB |
ポートコントロールレジスタ1 | PCR1 | 8 | FFE4 |
ポートコントロールレジスタ5 | PCR5 | 8 | FFE8 |
ポートコントロールレジスタ8 | PCR8 | 8 | FFED |
表2 H8Tiny-USBで使用するポートのI/Oレジスタ |
それでは、I/Oレジスタのアクセス方法を解説します。
例えば、ポートデータレジスタ1は、FFD4番地のバイト領域です。C言語で「0xFFD4」は、単なる整数なのでキャスト演算子により、バイト領域へのポインタに型変換します。
(char *)0xFFD4
これで「0xFFD4番地のバイト領域」を指すポインタができました。続いて、このメモリ領域にアクセスするには、
*((char *)0xFFD4)
と「参照演算子(*)」を使えばよいのです。
また、「ポート1の状態を変数dataに入力する」には、
data = *((char *)0xFFD4);
と変数「data」に代入すればよいのです。
このように、ポインタによるI/Oレジスタのアクセスを毎回コーディングするのは厄介です。そこで、プログラムの先頭部分で「#define」を使って、ポート定義をしているのです。
最後に、ポート定義で使われている「volatile」について説明しましょう。
I/Oレジスタの内容は、プログラムの処理とは別に内容が変わることがあります。例えば、入力ポートのポートデータレジスタの内容は、外部からの信号値が入っています。このようなことをCコンパイラに教えるために、「volatile」修飾子が用意されているのです。
コラム(1): C言語と2進数
データ型 | サイズ | 数値の範囲 |
---|---|---|
char(signed char)型 | 8ビット | −128 〜 127 |
short(signed short int)型 | 16ビット | −32768 〜 32767 |
long(signed long int)型 | 32ビット | −2147483648 〜 2147483647 |
unsigned char型 | 8ビット | 0 〜 255 |
unsigned short(unsigned short int)型 | 16ビット | 0 〜 65535 |
unsigned long(unsigned long int)型 | 32ビット | 0 〜 4294967295 |
表3 整数型のバリエーション |
コラム(2): ポインタによるメモリ参照
ここまでちゃんと理解できたかしら健一君?
制御プログラミングって、いろいろ大変なのよ。
そうですね。
でも、C言語の理解にとっても役立つなー。
あら、今回はまだやる気が残っているようね。
そんな健一君のために、また宿題を出してあげるわ。
ゲッ!!
(やはり、そうくるか……)
このワタシとデートしたかったら、今度はしっかり解いておくのよ。
あっ、いけない! ワタシ、今日合コンの約束があるんだった。
じゃ、バイバーイ!!
えーーーっ!!
(ガックリ)
晴子さんからの宿題(2)
SW1を押した回数を、7セグメントLEDに表示するプログラムを作ってね。ただし、カウンタの初期値は「0」よ。それと、「9」の次のカウントで最初の「0」に戻ること!
実際のH8マイコン制御プログラミングでは、メーカーが用意するヘッダファイルをインクルードすることで、I/Oレジスタを変数のように使うことができます。しかし、本連載では、C言語による制御プログラムの完全理解を目指し、あえてゼロから解説しました。いかがでしたか?
さて次回は、スイッチ入力プログラムについて、さらに考察してみたいと思います。また、コンパイルの途中で「GCC(GNU Compiler Collection)」のC言語ライブラリが必要になりますので、こちらも併せて解説します。ご期待ください!(次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.