アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

その中に、

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

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

#define P5DDR *0xfffc8

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

A 回答 (2件)

#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です。
    • good
    • 0
この回答へのお礼

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

お礼日時:2006/12/22 14:57

例えば、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がノイズで壊れないようにするために。
    • good
    • 0
この回答へのお礼

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

お礼日時:2006/12/22 14:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!