AVRのC言語についての質問

このQ&Aのポイント
  • AVRのC言語について教えてください。利用しているマイコンは2313です。
  • io.h内での_SFR_IO8()と_SFR_IO16()の働きについて理解できません。printf()関数は使えるのでしょうか?
  • AVRやC言語の機能として使えるのかわからない物で、他にも理解できない部分があります。どなたか教えてください。
回答を見る
  • ベストアンサー

AVRのC言語について幾つか教えてください。

AVRにCでプロプラムしてみようと思い、プログラムしてみています。 検索しても良くわからない事が幾つか有ったので質問させて下さい。 利用しているマイコンは2313です。 io.h内で各ペリフェラルのアドレスのような物を関連付けしている「_SFR_IO8()」っていうのと「_SFR_IO16()」っていう関数?の働きが良くわかりません。 printf()関数とか使えれば試せますが… #define  PORTD  _SFR_IO8(0x12) 等となっているので、 _SFR_IO8(0x11) = 0x7f; _SFR_IO8(0x12) = 0x7f; と書けばエラーを出さずにコンパイル出来ますし実行できます。 ですが関数ですとこういった使い方が出来ないように思うのですが… AVRに限らずC言語の機能の一部なのかも知れませんが今まで使った事が無い物なので無知でして、何方か知恵を貸していただけませんか?

  • DELED
  • お礼率55% (25/45)

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

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

> 一つ気になる事が有るのですが、sfr_defs.hをincludeしていないですし、 > io.h内(io2313.h)にもsfr_defs.hはincludeされていないようです io.h 中に、 #include <avr/sfr_defs.h> と言う記述があります。 あと、ATtiny2313 の場合のI/O設定は iotn2313.h です。io2313.h はAT90S2313の設定ファイル。 iotn1313.hも io.h 中で #elif defined (__AVR_ATtiny2313__) # include <avr/iotn2313.h> といった感じでinlude されています。 また、プロジェクトの設定で ATtiny2313を選んでいると、 自動的に __AVR_ATtiny2313__ がdefineされるため、その時はio.hをincludえすると自動的にiotn2313.hもincludeされます。 そういう流れで、大元のCのプログラムからは、 プログラム側ではCPUの種類を意識することなく #include <avr/io.h> するだけでいいようになっているのです。

DELED
質問者

お礼

io.h内に有りました!! 検索かけて見つからなかったのはio2313.h内でした。 ご教授有難うございます!!

その他の回答 (1)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

AVRでは、I/O もメモリ空間上に割り当てられており(メモリマップドI/Oと言います)、 0x12番地がPORTDになっていますので、 0x12番地への書き込み=ポート出力、0x12からの読み込み=ポート入力になります。 一方、_SFR_IO8 は、さらに sfr_defs.h で #define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET) と定義されています。また、__MIO_BYTE、_SFR_OFFSET は、 #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr)) # define __SFR_OFFSET 0x00 となっているため、 PORTD=0x7f; というコードは、最終的に、 (*(volatile uint8_t *)(0x12)) = 0x7f; というコード、すなわちメモリ0x12番地への書き込みに置き換えられます。 そういう流れで「PORTD=0x7f;」というコードがポート出力処理されるコードになるわけです。 そういうマクロ定義を用意することで、Cのプログラム中で、例えばPORTDへの出力を (*(volatile uint8_t *)(0x12)) = 0x7f; のような意味不明な記述をしなくても、 PORTD=0x7f; という意味がが分かりやすい記述ができるようになっているわけです。

DELED
質問者

お礼

回答有難うございます!! 一つ気になる事が有るのですが、sfr_defs.hをincludeしていないですし、io.h内(io2313.h)にもsfr_defs.hはincludeされていないようですが何処からincludeされているのでしょうか?

関連するQ&A

  • ニュートン法をC言語でプログラム

    方程式 cos^2x-0.5=0 (0<x<π) の解をニュートン法で求める という問題をC言語のプログラムを作り計算したいのですが分かりません。 自分で考えてみたプログラムは以下の通りです。 #include <stdio.h> #include <math.h> #define f1(x) cos(x)*cos(x)-0.5 #define f2(x) sin(2*x) /* ニュートン法による方程式の解 */ main() { double x0,x1,a,b,c,d,g,n; a=1; x0=0.7; n=0; while(a>0.0001){ b=x0; d=f1(b); g=f2(b); x1=x0-d/g; c=x1; a=f1(c); n=n+1; printf(" n= %f x1=%f x0=%f\n",n,x1,x0); printf(" a= %f → 解 x= %f \n", a,x1); x0=x1; } } 自分としてはこれが精一杯で、何故間違ってるのか、何をどうすればいいのか、さっぱり分かりません。どういったところが間違ってるのか可能性だけでも示して頂ければ幸いです。 参考として、ニュートン法によるプログラム例として書かれていたものを上げさせて頂きます。 例: e^x-3=0 の解をニュートン法により計算する。 #include <stdio.h> #include <math.h> #define f1(x) exp(x)-3 #define f2(x) exp(x) /* ニュートン法による方程式の解 */ main() { double x0,x1,e,a,b,c,d,g,n; a=1; x0=3; n=0; while(a>0.0001){ b=x0; d=f1(b); g=f2(b); x1=x0-d/g; c=x1; a=f1(c); n=n+1; printf(" n= %f x1=%f x0=%f\n",n,x1,x0); printf(" a= %f → 解  x= %f \n", a,x1); x0=x1; } }

  • AVRマイコン ビルドエラー

    AVRマイコンを #include <avr/io.h> int main(void) { DDRD =0b11111111; PORTD=0b11111111; } で、ビルドしようとしているのですが、 ../test3.c:0: error: MCU `atmega88p' supported for assembler only と、その後に ../test3.c:5: error: `DDRD' undeclared (first use in this function) 等と、エラーが出てビルド出来ません。 どうすればいいのでしょうか? 回答お願いします。

  • C言語についての質問です

    プログラミング初心者です if関数を使用して二次方程式の解を解くプログムを作成したのですが、この作成した関数をユーザー定義関数を使用しmain 関数の中でユーザー定義関数を呼び出すことにより、 2次方程式の解を求めるプログラムへ変更したいのですが、どのように行えばいいのか分かりません… 私が作成したプログラムはこのようなものになっています #include<stdio.h> #include<stdlib.h> #include<math.h> int main(void) { double a, b, c; /*二次方程式の定数*/ double D, x1, x2, r1, r2; printf("ax^2 + bx + c = 0 の係数 a, b, c を入力してください---> \n"); scanf_s("%lf %lf %lf", &a, &b, &c); printf("2次方程式を解いた結果は次の通りとなる。\n"); if (a == 0.0) { if (b == 0.0) { printf("係数がおかしい\n"); exit(-1); } { x1 = -c / b; printf("解は%f です。\n", x1); exit(0); } } else { D = b * b - 4 * a * c; if (D >= 0) { x1 = (-b + sqrt(D)) / (2.0 * a); x2 = (-b - sqrt(D)) / (2.0 * a); if (D == 0.0) { printf("解は %f です。\n", x1); } else { printf("解は %f と %f です。¥n", x1, x2); } } else { r1 = -b / (2 * a); r2 = sqrt(-D) / (2 * a); printf("解は%.2f+%.2fi と%.2f-%.2fi \n", r1, r2, r1, r2); } } return 0; } よろしくお願いいたします

  • マイコン(AVR)で、ある式を記述すると hex データが跳ね上がってしまう

    サインカーブを算出するために以下の質問をし、計算式を回答していただきました http://okwave.jp/qa4751105.html ですが、別の問題にあたってしまいました 上記回答の計算式をプログラムに書き込むと、コンパイル後の容量が跳ね上がってしまいます 同様の計算式で、x y に直接数字を指定すると容量が跳ね上がることはなさそうです ですが、変数を指定できなければ意味がありません なぜこのようなことが起こるのでしょうか? また、解決方法はありますか? #define F_CPU 800000UL #include <avr/io.h> #define sbi(BYTE,BIT) BYTE|=_BV(BIT) #define cbi(BYTE,BIT) BYTE&=~_BV(BIT) #include <math.h> const int sin_max1 = 127, sin_max2 = 255; int main(void) { DDRA = 0b111; DDRB = 0b11111111; DDRD = 0b1111100; PORTA = 0; PORTB = 0; cbi(PORTD, PD2); cbi(PORTD, PD3); cbi(PORTD, PD4); cbi(PORTD, PD5); cbi(PORTD, PD6); int i = 0; while (1) { sin_get(sin_max1, i); i++; if (i > sin_max1) i = 0; } } void sin_get(const int x, const int y) { int z; z = 127.5 * sin(2 * M_PI * y / x) + 127.5; // y x を直接数字に置き換えると容量は跳ね上がらない PORTB = z; }

  • PIC・AVRのC言語の初心者無向け勉強・参考本

    まずカテゴリーがコンピュータのC C++になっていますが、PIC・AVRもこのカテゴリーで良いのか分からなかったので、間違いでしたらご指摘下さい。 PIC・AVRのC言語の初心者無向け勉強・参考本・シンプルなフリーコンパイラをご紹介頂きたく思います。 現在PICは、ほとんどがPIC Basic Proでプログラミングしています。 あとは、フリーで公開されているアセンブラ(ASM)をNotepadで自分の仕様に修正してコンパイルしています。 しかし、PIC24Fシリーズ以降はPIC Basic Proは対応しておらず、フリーで公開されているプログラムのほとんどがC言語です。 一様、PIC24Fシリーズが出た頃にHI-TECH C CompilerとPIC-Cで試しにコンパイルできるかやって見たのですが、多分設定の段階でミスってしまい再インストールやバージョンを変えても、上手くコンパイルできません。 その後、放置していたので今現在は試用期間切れになってしまっています。 AVRの方は(Arduinoが周辺キットが豊富みたいですが・・・)、 一様ライティング機器としてAVRISP mk2を購入しAVR Studio 6.1をインストールしてありますが、PICマイコン同様C言語は初心者で、自分でプログラムを書くことが出来ません。 また、PICとの使い勝手の違いからハード・ソフトの準備は出来ているものの、現状は宝の持ち腐れに近い状態です。 フリーで公開されているHEXファイルを書き込む程度にしか使ってません、多少の使用環境の違いの修正も、AVRの方も上手くいきません。 勉強不足・学力不足と言わざるを得ません。 長々と前置きを書いてしまいましたが本題です。 PICとAVR各々に特化したC言語の初心者向けの本を色々教えて下さい。 書店でC言語の本を探すとWindows用がほとんどで、「C言語ではじめるPICマイコン」みたいなタイトルの本を立ち読みしても、いまいちピンときません。 (AVR・Arduinoも同様です。) また、ソフトの方は出来る限りフリーソフトでシンプルで、HI-TECH C Compiler・PIC-C・AVR Studioみたいな開発環境向けソフトでなく、インストール後はドラッグ&ドロップするだけで、C言語ファイル(AVRの方はASMファイル用も)をコンパイルできる物を教えて下さい。 ※ 開発環境の機能の無い物ってのは都合良すぎるでしょうか?? 何卒ご教授のほど宜しくお願い致します。 m(_ _)m ※※※※※※※※※※※※ テスト用・実用的プリント基板の作製は、それなりの物を取り揃えておりますので、ご心配なさらずに・・・・ でも、こんな基板があると動作確認などに重宝しますと言った情報は大歓迎です。 (市販品・自作可能なプリント基板情報などなど)     

  • AVRマイコンのCコンパイラについて

    PCでは、Cやアセンブラの経験もそこそこある本職のプログラマですが、マイコンは初心者です。 AVRマイコンに興味がわいて、早速使ってみたのですが、 開発環境は、AtmelStudio6と、AVRStudio4の両方を試しています。 どちらの開発環境も、ライブラリ関数のリファレンスがどこにあるのか わからない状況です。 サンプルをみると、_delay_ms()などの関数とincludeファイルがいくつかあるので、 ライブラリ関数がないわけではなさそうです。 ネットで検索しても、ライブラリ関数のリファレンスに相当するものをみつけられません。 AVR達人の方、どこに情報があるのか教えて頂けると幸いです。 情報は日本語が望ましいですが、英語でも構いません。 よろしくお願いします。

  • Cプログラミングについて

    私はBorlandのコンパイラを使ってCプログラミングをやっているのですが、以下のプログラムが実行できません。 どのようにすればコンパイラできるのか教えてください。 非線型方程式f(x)=x^3-x+1の根をニュートン法により求めよ。 /* *-------------------------- *   ニュートン法 * *-------------------------- */ #include <stdio.h> #include <math.h> #define f(x) ((x)*(x)*(x)-(x)+1) #define g(x) (3*(x)*(x)-1) #define EPS 1e-8 #define LIMIT 50 int main(void) { double x=-2.0,dx;   int k; for (k=1;k<=LIMIT;k++){ dx=x; x=x-f(x)/g(x); if(fabs(x-dx)<fabs(dx)*EPS){ printf("iteration=%d\n",k); printf("x=%f\n",x); break; } } if (k>LIMIT) printf("収束しない\n"); } コンパイルしようとすると以下のようなエラーが出ます。 エラー E2206 sample.c 18: 不正な文字 ' ' (0x8140)(関数 main ) エラー E2206 sample.c 18: 不正な文字 ' ' (0x8140)(関数 main ) 警告 W8070 sample.c 32: 関数は値を返すべき(関数 main ) *** 2 errors in Compile *** お答えよろしくお願いします。

  • c言語です。

    c言語です。 実行結果 式 3 X1 + 2 X2 + 1 X3 = &g 2 X1 + 5 X2 + 2 X3 = &g 1 X1 + 4 X2 + 1 X3 = &g 解 X1 = 1 X2 = 2 X3 = 3 を 式 3 X1 + 2 X2 + 1 X3 = 10 2 X1 + 5 X2 + 2 X3 = 18 1 X1 + 4 X2 + 1 X3 = 12 解 X1 = 1 X2 = 2 X3 = 3 に直したいのですが&gの所をどのようにしたら10.18.12になりますか? #include <stdio.h> #include <float.h> #define N 3 double A[N][N] = {{3,2,1}, {2,5,2}, {1,4,1}}; double b[N] = { 10, 18, 12 }; void Gauss_J( int, double*, double* ); void main(void) { int i; printf( "%d式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g X1 + %g X2 + %g X3 = &g \n", A[i][0], A[i][1], A[i][2], b[i] ); } printf("解\n"); Gauss_J(N, (double *)A, (double *)b ); printf("X1 = %g \n", b[0]); printf("X2 = %g \n", b[1]); printf("X3 = %g \n", b[2]); } void Gauss_J(int n, double *a, double *b) { int p, i, j,I ; double pivot, c ; for ( p = 0 ; p < n ; p++ ) { pivot = a[ p*n + p ]; for ( i = p ; i < n ; i++ ) { a[ p*n + i ] /= pivot; } b[ p ] /= pivot; for ( I = 0 ; I < n ; I++) { if (I != p) { c = a[ I*n + p]; for ( j = p ; j < n; j++ ) { a[ I*n + j] -= c * a[ p*n + j ]; } b[ I ] -= c * b[ p ]; } } } return ; }

  • c言語について

    このプログラムであと2行削れるとこがあるそうです。 どこがけずれますか? #include <stdio.h> #include <math.h> #define f(x) ((x)+(log(x))) #define EPS 1e-8 main( ) { double a, b, c, fa, fb, fc; int i=1; printf("input a and b: "); /*区間[a,b]の入力, a<b とする*/ scanf("%lf%lf", &a, &b); fa = f(a); fb = f(b); do { c = (a+b) / 2; /*cの値の更新*/ fc = f(c); printf(" %2d : a = %f, b = %f, c = %f, fc = %f\n", i, a, b, c, fc); if (fb*fc < 0){ a = c; fa = fc; } if (fa*fc < 0) { b = c; fb = fc; } if(fabs(fc) < EPS ) break; }while(++i<100); /*iが100以上になったら繰り返し終了*/ }

  • AVRによるマトリクスLED制御

    AVRによるマトリクスLED制御 この度大学でAVRによるマトリクスLED制御を行う事になったのですが、プログラム面で今行き詰っています. void PointDisplay(int* pointlist[8][8],int time)//指定した座標のLEDを点灯させる { PORTB=init_PORTB; PORTD=init_PORTD; for(int loop=0;loop<=time;loop++) { for(int k=0;k<=7;k++){ switch(k){ case 0: ROW1_on; break; case 1: ROW2_on; break; case 2: ROW3_on; break; case 3: ROW4_on; break; case 4: ROW5_on; break; case 5: ROW6_on; break; case 6: ROW7_on; break; case 7: ROW8_on; break; } for(int j=0;j<=7;j++){ if(pointlist[k][j]==1){ switch(j){ case 0: COL1_ready; break; case 1: COL2_ready; break; case 2: COL3_ready; break; case 3: COL4_ready; break; case 4: COL5_ready; break; case 5: COL6_ready; break; case 6: COL7_ready; break; case 7: COL8_ready; break; } } } PORTB=init_PORTB; PORTD=init_PORTD; } } } 以上が使用する関数で,実行内容としては2次配列pointlistを関数PointDisplayに渡し,time分だけループするという関数になります. マトリクスLEDは8×8のTOM-1588BHです.(データシートも添付しております 引用) 使用しているAVRはATmega168Pで,PORTD0~7をLEDの1~8pinにPORTB0~7をLEDの9~16pinに接続しています.(回路がわかりやすくなるように)そしてそれを#defineで定義しそれぞれをビット制御しています. 行き詰っている理由はintの配列を4つまで定義してコンパイル>実行すると思ったとおりにLEDに表示されるのですが,5つ以上定義してコンパイル>実行すると3,4つめの配列が乱れてしまいます.(ひとつ右にずれたりひとつ上にずれたり) 4つまでは正常に動作しているのでハード面は問題ないと考えて,ソフト面を見直しているのですが,なぜ悪いのかが理解できません.(オーバーフローとかそんなんですかね?) こういったマイコンを扱うプログラムは経験が少なく,データシートも英文なので困っています.どなたか詳しい方,知恵を貸していただけないでしょうか?お願い致します.

専門家に質問してみよう