« WinAVRでio.hファイルをインクルードせずにIOポートを制御する荒業。 | トップページ | AVRアセンブラ関数でIOを叩く方法。 »

2012年12月30日 (日)

AVR avr/io.h インクルードファイルは一体何をしているのか??

AVRでポート出力を制御するためにC言語で書くときは、

DDRD  = 0xFF;            //ポートDを全部出力設定
PORTD = 0x10;             //PORTD出力

のようにしているが、インクルードファイル”avr/io.h”がなければこのように書くことはできない。なぜなら、本来はDDRDやPINDというのは、単なるメモリのうちの一つにすぎないから。もしio.hがない場合は、こんな風に書かなければならない。

int *pind;                //PINDへのアドレスを指すポインタ。
pind = 0x09 + 0x20;    //ポインタ変数pindにPINDのアドレスを入れる。

そうしてようやく、値を目的のアドレスに入れることができる。
*pind = 0xFF;

AVRの”avr/io.h”が何を宣言しているか。
WinAVRのドキュメントを紐解いてみた。


<avr/io.h>: AVR device-specific IO definitions

を見てみると、io.hのファイルの中身には宣言の実体はなく、AVRstudioで選んだデバイスをコンパイラが受け取り、それに対応したヘッダファイルをインクルードするようにマクロが組んであるという。

WinAVR\avr\includeのフォルダに、それぞれのデバイスに対応したヘッダファイルが置いてある。io.hの中身を見ると、確かにIOレジスタに関する名前が一切出てこず、elif definedの行がズラズラ並んでいる。おそらくここからATmega328Pなら"avr/iom328P.h"が読み込まれる。

"avr/iom328P.h"の中身はどうなっているか。
下記のような塊が何個も並んでいる。この塊の一行目のところが大事で、0x09というアドレスが_SFR_IO8というマクロに引数として渡されているのがわかる。

#define PIND _SFR_IO8(0x09)
#define PIND0 0
#define PIND1 1
#define PIND2 2
#define PIND3 3
#define PIND4 4
#define PIND5 5
#define PIND6 6
#define PIND7 7

じゃあこのマクロはどこで宣言されているのか?というと、
WinAVRドキュメントの<avr/io.h>のページの本文に、

Note that this file always includes the following files:
See <avr/sfr_defs.h>: Special function registers for more details about that header file.

というのがあって、 <avr/sfr_defs.h>の説明にリンクが貼ってある。ここの説明を見れば、よく使う_BVマクロやbit_is_setマクロについての説明が全部載っている。
WinAVR\avr\includeのフォルダにsfr_defs.hが入っていて、マクロの実体が書き込まれている。そしてとうとう_SFR_IO_ADDR(io_addr)というマクロの宣言を見つけることができる。

#define _SFR_IO8(io_addr)((io_addr)+__SFR_OFFSET)

というのがそれ。そしてそのなかにこういうマクロが中に入っていて、
#define __SFR_OFFSET 0x20
とかいうのがあるから、レジスタのアドレスについて。
にある、IOレジスタにデータスペースとしてアクセスするための手法を使っているのだと思う。

具体的にアドレスをいれて考えてみる。
たとえばDDRBにアクセスしたかったら、mega328Pの仕様書のresister summuryをみる。すると、DDRBが0x04番地になっているから、これに普通のデータスペース、つまり変数のようにアクセスしたければ、

0x20+0x04 = DDRBのアドレス

ということになる。

実際にアクセスできるかどうかはAVRstudioを使えば試すことができるので、AVRはその点非常に便利。

実際にやってみたソースファイルも用意していますので、試してみてください。
IOのヘッダファイルを一切使わずにIOポートを叩く荒業。

このサイトはアセンブラプログラミングをどんどん書いています。
アセンブラでプログラムを書いてスキルアップ

« WinAVRでio.hファイルをインクルードせずにIOポートを制御する荒業。 | トップページ | AVRアセンブラ関数でIOを叩く方法。 »

AVRマイコン」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: AVR avr/io.h インクルードファイルは一体何をしているのか??:

« WinAVRでio.hファイルをインクルードせずにIOポートを制御する荒業。 | トップページ | AVRアセンブラ関数でIOを叩く方法。 »