IOポート C言語のマクロなど
C言語のマクロ
ヘッダファイル<avr/io.h>で、AVR各レジスタのビット名とビット番号(0~7)の対応が定義されています。
たとえば、PORTBのbit0~bit7に対応して、PB0~PB7という名前が定義されています。
入力ポートPINBについては、PINB0~PINB7の名前で定義されています。同じ0~7なんですけど、わかりやすいように使い分けた方がいいでしょう。
(AVRwiki 目次 IOレジスタ、入出力ポート より)
AVR 入出力IOポートの使いかた
ポートBを例に
IOポート
- ①ポートB方向レジスタ DDRB
- ②ポートB出力レジスタ PORTB (出力)用
- ③ポートB入力レジスタ PINB (入力)用
IOポート設定は少しPICなどと違うところがあり
データレジスタが
- 読み取り(入力)用 PINBx と
- 出力(出力)用 PORTx に分かれていて、別レジスタでする
そして変則的 ポート設定方法になっているところもある
- 方向設定レジスタ(DRR×) を入力設定にして
データレジスタ(PORT×)で1にすると 内部プルアップ設定になる。 - 方向設定レジスタ(DRR×)を出力設定にして
入力用データレジスタ(PIN×)で1にすると 出力データが反転になる
AVR C言語のマクロなど
ビットアクセス マクロ
<avr/io.h>で、AVR各レジスタのビット名とビット番号(0~7)の対応が定義
- _BV()
たとえば、_BV(PINA6) は ( 1 << PINA6 ) を返し、
これはPINA6に対応するビット(bit6)をONとした時の
PINAの値 64 (二進数で0b01000000)を返します。
ビット操作のマクロ
【その1】
- ( 1 << PINB5 ) を使って
PORTB = ( 1 << PINB5 ); // PB5ピンだけをHighにし、残りをLowにする
例)
PORTB = 0xFF; //元 #1111 1111 (0xFF
PORTB = ( 1 << PINB5 ); → #0010 0000 (0x20
これ( 1 << PINB5 )は _BV(PB5) と同様 以下
【その2】
- _BV( ) を使って
PORTB = _BV(PB5); // PB5ピンだけをHighにし、残りをLowにする
例)
PORTB = 0xFF; //元 #1111 1111 (0xFF
PORTB = _BV(PB5); → #0010 0000 (0x20
PORTB |= _BV(PB1); //PB1ピンだけをHighにし、残りは変化させない
例)
PORTB = 0xF0; //元 #1111 0000 (0xF0
PORTB |= _BV(PB1); → #1111 0010 (0xF2
ORTB &= ~_BV(PB3); //PB3ピンだけをLowにし、残りは変化させない
例)
PORTB = 0xFF; //元 #1111 1111 (0xFF
PORTB &= ~_BV(PB3); → #1111 0111 (0xF7
【その3】
- sbi() , cbi()
* sbi(),cbi() は現Verでは、すでに廃止、削除されたとのこと
でも各ビットの1つだけを1,0操作するには便利なのでマクロを作ると
#define sbi(PORT,BIT) PORT |= _BV(BIT) //ビット操作のマクロ定義
#define cbi(PORT,BIT) PORT &=~_BV(BIT)
使用方法)
cbi(TCCR1B, ICES1); //立ち下がりに設定 (ICES1=0
sbi(TCCR1B, ICES1); //立ち上がりに設定 (ICES1=1
●複数ビット操作
同様に or で続けるPORTB = _BV(PB1) |_BV(PB4); //PB1 PB4 ピンをHighにし、残りをLowにする
例)
PORTB = 0xFF; //元 #1111 1111 (0xFF
PORTB = _BV(PB1) |_BV(PB4) → #0001 0010 (0x12
ビットチェック bit_is_set() , bit_is_clear()
- bit_is_set()
- 指定レジスタの指定のビットがセット(1)されているかどうかチェック
- bit_is_clear()
- セット(1)されてされていないかチェック
●ビットチェックループ用
- loop_until_bit_is_set()
- loop_until_bit_is_clear()
例)
while( bit_is_clear(PINB,PINB3) )
{
//PINB3が0の間この処理を行う
}
loop_until_bit_is_set(PINB,PINB3)
{
//PINB3が1になるまでこの処理を行う・・・コンパイルエラーとなる
}
↓このように使ってください。
while( bit_is_clear(PINB,PINB3) )
{
//PINB3が0の間この処理を行う
}
wikiより
- twtter
- google+
- hatena