- ベストアンサー
マイコンのC言語プログラムの構造体の宣言とvolatileの必要性について
hashioogiの回答
- hashioogi
- ベストアンサー率25% (102/404)
Q.通常は、構造体の宣言(struct st_hudi aなど)を行わないと使えないと思うのですが… A.プリプロセサが HUDI.SDIR.WORD = 0; を (*(volatile struct st_hudi *)0xFFFE2000).SDIR.WORD = 0; にしますので翻訳のエラーは出ません。 Q.アドレスを明記しているため、volatileがなくても正常に動きそうな気がします A.volatileは、マルチタスクで動作していたり、割り込みが動作するような場合は誰がいつアドレス0xFFFE2000の内容を書き換えるかわからないのでこのアドレスをアクセスする場合は最適化をしないで下さいという指定です。ですからvolatileを外したら正常に動かなくなる場合があります。
関連するQ&A
- [C言語]変数のアドレスを直接指定する構文
C言語でのマイコン開発環境に付属しているヘッダーファイルにはレジスタを共用体と構造体でアクセスできるようにしてあります。 アドレスを割り付ける部分の記述は一行ですが、意味を考えた時に構文が複雑すぎて躓いてしまいました。 #define PD (*(volatile struct st_pd *)0xFFFF83A0) /* PD Address*/ 後ろの"*"はst_pdのポインタ型だとして前の"*"はどういう効果になっているのでしょうか? また、複数行に分解して同じ効果を書くこと(例えば変数unsigned long valにアドレス0xFFFF83A0を割り付け)は出来るのでしょうか? 理解を助けるためにお願いします。
- ベストアンサー
- C・C++・C#
- H8マイコン C言語でのプログラミング *((volatile unsigned char *)ってなんですか??
現在、ある参考書に載っている、マイコンを用いてマザーボード上のLEDを点滅させるCのプログラムを勉強のために見ています。 その中に、 #define P5DDR (*(volatile unsigned char *)0xfffc8) という一行があるんですが、この中の*(volatile unsigned char *)という表現を見たことがなくて困っております。これは簡単に言うと、 #define P5DDR *0xfffc8 と、『P5DDRを0xfffc8のポインタで置き換える』と言い換えていいのでしょうか??
- ベストアンサー
- C・C++・C#
- プログラム(C)
#include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・ ・ }; struct BMPINFOHEADER { ・ ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。
- 締切済み
- C・C++・C#
- マイコンH8-3664 走行カー C言語プログラム改良
SW0がONで3秒間前進して停止 SW0がOFFの後、再度ONで3秒間前進して停止 するプログラムです! これを、 3秒間前進後、3秒右旋回(右モーターのみ回転)後、3秒間前進、3秒右旋回を繰り返し、元の位置に戻るというプログラムに改良せよ!というのですが? /**************************************************************/ #include <stdio.h> #include <sysio.h> /*タイマーA*/ #define TMA (*((volatile unsigned char *)0xFFA6) /*割り込み*/ #define IENR1 (*((volatile unsigned char *)0xFFF4)) #define IRR1 (*((volatile unsigned char *)0xFFF6)) #define PDR8 (*((volatile unsigned char *)0xFFDB)) #define PCR8 (*((volatile unsigned char *)0xFFEB)) long count = 0; long x = 0; void interrupt timer( ) { IRR1 &= ~0x40 ; if( count == 300 ) { x = 1 ; count = 0 ; } else { count++; } } void main( ) { unsigned char a; TMA = 0x03 ; IENR1 |= 0x40 ; PCR8 = 0x0f ; while(1){ a = PDR8 >> 4 ; if( x == 0 && a == 0x0e ) { PDR8 = 0x0a ; _ei( ) ; } else if( x == 1 ) [ PDR8 = 0x00; _di( ) : if (( PDR8 >> 4) == 0x0f) { x = 0 ; } } } } /**************************************************************/ 尚、SW はプルアップされている!
- ベストアンサー
- C・C++・C#
- 共用体のアドレスを取得したい
SH7047のプログラムです。 何をしたいのかと言うと、P_PORTD.PDDRL.BIT.PD4DR等を関数の中で変化させたいのです。 うまく行かない理由はおそらく「P_PORTD.PDDRL.BIT.PD4DRのアドレスは渡すことが出来ない」だとおもいます。 まぁそれも当然な話だと思うのですが、どうにかならないでしょうか? 個人的には「unsigned short* port」→「bit* port」の様に出来れば理想的なのですが。 何か良い方法を教えてください。よろしくお願いします。 #define P_PORTD (*(volatile struct st_portd *)0xFFFF83A2)/* PORTD Address */ struct st_portd { /* struct PORTD */ union { /* PDDRL */ unsigned short WORD; /* Word Access */ struct { /* Bit Access */ unsigned short :7; /* */ unsigned short PD8DR:1; /* PD8DR */ unsigned short PD7DR:1; /* PD7DR */ unsigned short PD6DR:1; /* PD6DR */ unsigned short PD5DR:1; /* PD5DR */ unsigned short PD4DR:1; /* PD4DR */ unsigned short PD3DR:1; /* PD3DR */ unsigned short PD2DR:1; /* PD2DR */ unsigned short PD1DR:1; /* PD1DR */ unsigned short PD0DR:1; /* PD0DR */ } BIT; /* */ } PDDRL; /* */ }; /* */ void main(void) { output(&P_PORTD.PDDRL.BIT.PD4DR,0xff); output(&P_PORTD.PDDRL.BIT.PD5DR,0xff); output(&P_PORTE.PEDRL.BIT.PE12DR,0xff); } void output(unsigned short* port,int data) { P_PORTE.PEIORL.WORD = 0x3fff; P_PORTE.PEDRL.WORD = data & 0xff; *port = 1; *port = 0; P_PORTE.PEIORL.WORD = 0x3f00; }
- ベストアンサー
- C・C++・C#
- C言語 #defineについて
C言語でどの様に考えれば良いか分からない事があるので、教えて下さい。 以下の様な行が出てきたのですが、どういう意味なのでしょうか? #define SYSTEM (*(volatile struct st_system *)0x80000) 現状分かっている事は 1.#define ABC 100 ならこれ以降で出てくるABCは100と読み替える。 2.volatileはコンパイラの最適化を抑制する様な意味。 とい事です。 以上、宜しくお願い致します。
- ベストアンサー
- C・C++・C#
- C言語構造体についてです。
C言語、π=PI 3.14159265で構造体を用いてmensekiを呼び出して 半径と面積を計算して出力するプログラムです。下の空白を埋めてもらえますか? /* 構造体のプログラム */ #include <stdio.h> #include <math.h> #define PI 3.14159265 struct Data { /* 半径rと面積areaをdoubleで宣言 */ }; void menseki(struct ... 構造体のポインタを引数とする ){ /* 面積を計算する際に構造体のアドレスから計算する */ circle->area=PI* .....; } main(){ struct Data example[2]; //構造体配列 int i; /* 半径rを構造体配列を用いて2例入力する */ /* 2例の各々について mensekiを呼び出して 半径と面積を計算して出力する */ } よろしくお願いします。
- ベストアンサー
- C・C++・C#
- H8 外部バスのデータアクセス
H8 外部バスのデータアクセス ルネサスのH8マイコン初心者です。(C言語も初心者です) 外部バスのCS1(0x200000)に512KBのSRAMが繋がっているのですが、 HEWのセクションを変更せず、直接SRAMに対して読み書きしたいと思っています。 バスコントローラは設定済みという前提で以下の(A)~(C)のように 宣言すればデータの読み書きは出来ると思うのですが、 (A)~(C)を配列や構造体として扱いたい場合、どのように宣言すれば 良いのでしょうか? (A) #define SRAM1 (*(volatile unsigned int*)(0x200000)) (B) #define SRAM2 (*(volatile unsigned int*)(0x200002)) (C) #define SRAM3 (*(volatile unsigned int*)(0x200004)) (D) SRAM1 = 1; (E) SRAM2 = 2; (F) SRAM2 = 3; よろしくお願いします。
- ベストアンサー
- その他(プログラミング・開発)
- C言語のプログラムで...
下のプログラムは参考書にあったサンプルプログラムなのですが /* 関数の宣言 */ int print_struct(struct person dat); のところはなぜint型なのですか? #include <stdio.h> #include <string.h> /* 構造体の定義 */ struct person { char name[20]; /* 名前 */ double height; /* 身長 */ double weight; /* 体重 */ int bpl; /* 最低血圧 */ int bph; /* 最高血圧 */ }; /* 関数の宣言 */ int print_struct(struct person dat); /* main関数 */ int main(void) { /* 変数の宣言 */ struct person dat; /* 構造体のメンバーに値を代入 */ strcpy(dat.name,"山田太郎"); dat.height = 173.5; dat.weight = 63.0; dat.bpl = 98; dat.bph = 113; /* struct person関数を実行 */ print_struct(dat); return 0; } /* print_struct関数 */ int print_struct(struct person dat) { /* 画面に出力 */ printf("%s\n",dat.name); printf("%f\n",dat.height); printf("%f\n",dat.weight); printf("%d\n",dat.bpl); printf("%d\n",dat.bph); return 0; }
- ベストアンサー
- C・C++・C#
- マイコンとフラッシュメモリの接続について
マイコンとフラッシュメモリの接続について 2点質問があります。 質問1 マイコンH8S、フラッシュはスパンションの http://www.spansion.com/Support/Datasheets/S29AL008D_00_A11_e.pdf を使用しています。 ワードモードでマイコン側A0-A18、rom側A0-A18で接続したのですが、 どうもワードモードだとマイコン側A1-A19、rom側A0-A18とアドレスを1つ ずらして接続するのが普通のようなのですが、マイコン側A0-A18、rom側A0-A18では アクセスできないのでしょうか?必ず1つずらして接続しないとだめなのでしょうか? 実際デバイスIDのコマンドを実行してみたのですが、リードできませんでした。 (*(volatile short *)0x400555) = 0xAA; (*(volatile short *)0x4002aa) = 0x55; (*(volatile short *)0x400555) = 0x90; a = (*(volatile short *)0x400002); a=0xFFFFとなりました。 質問2 マイコン側A0-A18、rom側A0-A18ではデバイスIDがリードできなかったので、改造して マイコン側A1-A19、rom側A0-A18としたところ、 (*(volatile short *)0x400aaa) = 0xAA; (*(volatile short *)0x400554) = 0x55; (*(volatile short *)0x400aaa) = 0x90; a = (*(volatile short *)0x400002); でデバイスID0x22DAを読むことができました。 ここで質問ですが、フラッシュのマニュアル26PだとデバイスIDの4回目のコマンドは、 ワードモードだとX01となっています。 しかし (*(volatile short *)0x400aaa) = 0xAA; (*(volatile short *)0x400554) = 0x55; (*(volatile short *)0x400aaa) = 0x90; a = (*(volatile short *)0x400001); としたところ0x400000の製造メーカIDの0x0001がよめるだけでした。 そもそも0x400001だと奇数アドレスなのでH8Sはアクセスできないので 当然な気がするのですが、マニュアルのX01とはどういう意味なのでしょうか? コンパイラに起因する問題でしょうか?
- ベストアンサー
- その他([技術者向] コンピューター)
補足
1.(*(volatile struct st_hudi *)0xFFFE2000)この部分の考え方は (volatile struct st_hudi *)が明示的なキャストを示しているのでしょうか? そして、*がついているので、0xFFFE2000の中身を表すということで合っていますか? 2.納得できました。