こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

H8マイコン C言語でのプログラミング *((volatile unsigned char *)ってなんですか??

現在、ある参考書に載っている、マイコンを用いてマザーボード上のLEDを点滅させるCのプログラムを勉強のために見ています。

その中に、

#define P5DDR (*(volatile unsigned char *)0xfffc8)

という一行があるんですが、この中の*(volatile unsigned char *)という表現を見たことがなくて困っております。これは簡単に言うと、

#define P5DDR *0xfffc8

と、『P5DDRを0xfffc8のポインタで置き換える』と言い換えていいのでしょうか??

投稿日時 - 2006-12-20 22:29:29

QNo.2615434

すぐに回答ほしいです

質問者が選んだベストアンサー

#define P5DDR (*(unsigned char *)0xfffc8)
なら、解りますか?

P5DDR = 0x00ff;
とかかれた場合、H8のPort5 DDRに0x00ffを書き込めという意味になります。
0xfffc8番地に0x00ffを書けというのと等価ですね。

さて、volatileのほうなのですが、「最適化をするな」という意味になります。

int i;

for (i = 0; i < 10; i++) {
P5DDR = 0x00ff;
}
と書いた場合、賢いコンパイラーは、この3行を
P5DDR = 0x00ff;
だけに置き換えてしまいます。
ハードウエアレジスタの場合、意味あって複数回同じ値を書かせる場合もあるのに、コンパイラーのほうが気を利かせて、論理的に無駄な部分を省略してしまうのです。
この動作を禁止するのが、volatileです。

投稿日時 - 2006-12-20 22:54:29

お礼

分かりやすい説明をありがとうございます。
Cはほとんど初心者なものですから助かりました。

投稿日時 - 2006-12-22 14:57:22

ANo.1

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

例えば、P5DDR = 0xff; とすると、0xfffc8番地に0xffを書き込むという意味になります。

#define P5DDR *0xfffc8
はだめですよ。P5DDR=0xff; とした場合にP5DDR番地がワードなのかバイトなのかわからない。ワードの場合はfffc8とfffc9番地の2つの番地に書き込むことになってしまいます。また、unsigned が付いているのは、符号付charだと0xffは-1となってしまうから。0x80以上の値を代入してワーニングやコンパイルエラーを出さずに代入出来るようにする為にはunsignedは必要になります。また、ビット演算の & や | 、及び、シフト演算 <<や>>を使う場合もunsigned とするのが基本です。
例えば、
signed char a, b;
a = -1; b = 0;
if(a == 0xff){b = 1;}else{b = 2;}
上記の場合は、コンパイラにもよるにかもしれないけど、普通はb=2になってしまいます。
volatileが付いているのは通常のメモリでなく、値を代入しなくても値が変わってしまうかもしれない制御レジスタだから。こういった制御レジスタを「メモリマップトI/O」といい普通は最適化しないようにvolatileを付けます。

DDRはビット単位でポート入出力のモードの設定するレジスタです。0が入力、1が出力となります。そしてDRが入出力のデータになります。

DDRは確か(たぶん)書き込みONLYのレジスタだと思うから、P5DDR |= 1;といった記述は出来なかったと思います。

P5DRのレジスタは書き込んだ値がそのまま読めるレジスタだからP5DR |= 1;といった記述が可能です。

初期設定で、未使用のプルアップがされていない(オープン)端子のポートは出力モードに割り当てるのが普通です。CPUがノイズで壊れないようにするために。

投稿日時 - 2006-12-21 02:21:26

お礼

詳しく教えていただいてありがとうございます。
まだまだ勉強不足で、なんとなくしか分かりませんが理解できるように勉強をがんばります!!

投稿日時 - 2006-12-22 14:59:39

あなたにオススメの質問