今日畑山さんにAVR-GCCについて質問されたので、5月あたりから俺が多用しているレジスタ操作関数やマクロについて書こうと思ったらGetting Started Notes – Ports – AVR-Wikiに大体書いてあった。
_BVの項あたりから読むと良いと思う。
補足。
マイコンはレジスタで制御されている。レジスタはメンバ変数のようなもので、マイコンは常にレジスタの状態を監視し、変化があれば動作を変える。
レジスタの例としては
・IOポートのPB3から電流を流すかどうか
・シリアル通信の受信を許可するかどうか
・A/Dコンバータを開始するかどうか
等だ。大抵が1bit。
数は少ないが
・シリアル通信で受信したデータ(8bit)
・タイマカウンタのカウント速度(3bit)
などもある。
1bitのレジスタはC言語で扱いにくい。なぜなら、C言語の標準の型のうち一番小さいのが8bit(1Byte)なので、1bitのレジスタを操作するにはビット演算が必要になる(&や~等)
例えばUCSRAの6bit目、UDREレジスタがセットされているかどうかを調べる時は
if(UCSRA&32)
としなければならない。なんかぱっと見わからない。
これをマクロを使って書くとこうなる
if(bit_is_set(UCSRA, UDRE))
これなら、データシートに書かれているレジスタをを一つずつ読んで、ぽちぽち埋めていけばちゃんと動作するプログラムが書ける。
mega8の外部入力割り込みなどは、sbiとcbiを使って一つずつレジスタを指定していってやると簡単に出来た。
Getting Started Notes – Ports – AVR-Wikiも見るとわかりやすいのだが、
WinAVR\avr\include\avr にUDREやPB0などの各レジスタが何ビット目にあるかが定義されている。
atmega8のヘッダファイル、iom8.hには
/* UCSRA */
#define RXC 7
#define TXC 6
#define UDRE 5
#define FE 4
#define DOR 3
#define PE 2
#define U2X 1
#define MPCM 0
となっている。
bit_is_set(UCSRA,UDRE)で、UCSRAの6ビット目がセットされているかどうかがわかる。
他にもloop_until_bit_is_set(byte, bit) → byteのbitがセットされるまでループして待機や、bit_is_clear(byte, bit) → byteのbitがクリアかどうかなどがある。
あと_BV。 | とかもよく使う。自分で調べて欲しい。 明日はインタラクティブ東京でmoo-pongのそばにいると思います。 だめだ眠い
_BV(0)とすると、1ビット目だけセットされた8bitの値が返される。
_BV(5)とすると0b00100000 → 32になる。
つまり << と同じだ。_BV(PB3)は1<