現在、ある参考書に載っている、マイコンを用いてマザーボード上のLEDを点滅させるCのプログラムを勉強のために見ています。
その中に、
#define P5DDR (*(volatile unsigned char *)0xfffc8)
という一行があるんですが、この中の*(volatile unsigned char *)という表現を見たことがなくて困っております。これは簡単に言うと、
#define P5DDR *0xfffc8
と、『P5DDRを0xfffc8のポインタで置き換える』と言い換えていいのでしょうか??
No.1ベストアンサー
- 回答日時:
#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です。
No.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がノイズで壊れないようにするために。
詳しく教えていただいてありがとうございます。
まだまだ勉強不足で、なんとなくしか分かりませんが理解できるように勉強をがんばります!!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- その他(プログラミング・Web制作) Pythonでの不均一なサイコロをつくるプログラミングがわかりません 4 2022/06/07 13:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語について コマンドラインで >変数 12.00 (char型) と、小数点付きの値を共用体に渡 1 2022/04/22 16:56
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
フォートランで行列の計算
-
繰り返し1行~28行までを順順に...
-
!(否定)演算子について
-
MATLABにおける行の挿入方法
-
Excel・Word リサーチ機能を無...
-
特定のPCだけ動作しないVBAマク...
-
UserForm1.Showでエラーになり...
-
教えて下さい
-
一つのTeratermのマクロで複数...
-
配列数式の解除
-
メッセージボックスのOKボタ...
-
エクセルで特定の列が0表示の場...
-
On ErrorでエラーNoが0
-
String""から型'Double'への変...
-
ExcelのVBA。public変数の値が...
-
Excel マクロ VBA プロシー...
-
エクセルに張り付けた写真のフ...
-
【VBAエラー】Nextに対するFor...
-
VBAでfunctionを利用しようとし...
-
お助けください!VBAのファイル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
繰り返し1行~28行までを順順に...
-
H8マイコン C言語でのプロ...
-
!(否定)演算子について
-
C言語で余りがマイナスになる場合
-
MATLABのデータ抽出についてお...
-
mathematicaの質問です
-
MATLABの参考書
-
c言語
-
パイソンのプログラミングにつ...
-
≪C言語≫キー入力の判断について
-
Matlabのspdiags関数
-
cのプログラミングで虚数を含...
-
OPENCVを使ったエピポーラ幾何...
-
フォートラン77での微分と行列
-
Numpyのrandom.multivariate_no...
-
収束計算
-
MATLABにおける行の挿入方法
-
フランク行列の逆行列を求める...
-
BLASのレベル3の『ssyrk』や『s...
-
Z80のフラグレジスタについて
おすすめ情報