在AVR-GCC裡要如何實現位元定址呢?須用_BV(),bit_is_set( , )函數,bit_is_clear( , )函數
1. BV : marco _BV(bit) 是我們操作I/O 寄存器時頻繁用到的,avr-libc 建議使用這一marco進行 寄存器的位元操作,它在檔sfr_defs.h 中定義如下:
#define _BV(bit) (1 << (bit))
以下是它的使用示例:
DDRB=_BV(PB0)|_BV(PB1); // io.h 中定義 PB0: 0 PB1: 1
用法:BV(pos); #define _BV(bit) (1 << (bit))說明:將位定義轉換成遮罩碼(MASK)。與head file文件io.h裏的位定義一起使用。例如,置位WDTOE和WDE可表示為“BV(WDTOE) | BV(WDE)”
2.bit_is_clear用法:uint8_t bit_is_clear(uint8_t port, uint8_t bit);描述:如果port的bit位清零則返回1。此函數調用sbic指令,故port應為有效位址。
3.bit_is_set用法:uint8_t bit_is_set(uint8_t port, uint8_t bit);描述:如果port的bit位置位則返回1。此函數調用sbis指令,故port應為有效位址。
4.loop_until_bit_is_clear用法:oidoid loop_until_bit_is_clear (uint8_t port, uint8_t bit);說明:此函數簡單地調用sbic指令來測試埠port的bit位是否清零。port必須為有效埠。
5.loop_until_bit_is_set用法:oidoid loop_until_bit_is_set (uint8_t port, uint8_t bit);說明:此函數簡單地調用sbis指令來測試埠port的bit位是否置位。port必須為有效埠。
6.cbi用法:void cbi(uint8_t port, uint8_t bit);說明:清零port的bit位。bit的值為0~7。如果port為實際I/O寄存器,則此函數生成一條cbi指令;否則,函數生成相應的優化代碼。
7.sbi用法:void sbi(uint8_t port, uint8_t bit);說明:置位port的bit位。bit的值為0~7。如果port為實際I/O寄存器,則此函數生成一條 sbi指令;否則,函數生成相應的優化代碼。
8.inp用法:uint8_t inp(uint8_t port);說明:從埠port讀入8比特的數值。如果port為常數,則函數生成一條in指令;若為變數,則函數用直接定址指令。
8.inp用法:uint8_t inp(uint8_t port);說明:從埠port讀入8比特的數值。如果port為常數,則函數生成一條in指令;若為變數,則函數用直接定址指令。
9.outp用法:void outp(uint8_t val, uint8_t port);說明:將val寫入埠port。如果port為常數,則函數生成一條out指令;若為變數,則函數用直接定址指令。
範例如下:
#include "avr/io.h"
#define flag_a_0 0x01;
#define flag_a_1 0x02;
#define flag_a_2 0x04;
#define flag_a_3 0x08;
#define flag_a_4 0x10;
#define flag_a_5 0x20;
#define flag_a_6 0x40;
#define flag_a_7 0x80;
#define flag_a_0 0x01;
#define flag_a_1 0x02;
#define flag_a_2 0x04;
#define flag_a_3 0x08;
#define flag_a_4 0x10;
#define flag_a_5 0x20;
#define flag_a_6 0x40;
#define flag_a_7 0x80;
#define _set_aa flag_a=flag_a|flag_a_2;
#define _clr_aa flag_a=flag_a&~flag_a_2;
unsigned char flag_a,flag_b;
#define _clr_aa flag_a=flag_a&~flag_a_2;
unsigned char flag_a,flag_b;
int main(void)
{
DDRB=0XFF;
PORTB=0XFF;
PORTB|=_BV(5); //令portb第5bit為1
PORTB&=~_BV(5); //令portb第5bit為0
{
DDRB=0XFF;
PORTB=0XFF;
PORTB|=_BV(5); //令portb第5bit為1
PORTB&=~_BV(5); //令portb第5bit為0
PORTB^=_BV(6); //令portb第6bit反轉
PORTB^=_BV(6); //令portb第6bit反轉
PORTB^=_BV(6); //令portb第6bit反轉
flag_a^=_BV(3); //令flag_a第3bit反轉
// flag_a^=_BV(3);
if ((flag_a&_BV(3))==0) //測試flag_a第3bit是否為0
{
flag_a^=_BV(7); //令flag_a第7bit反轉
}
else flag_a^=_BV(6); //令flag_a第6bit反轉
// flag_a^=_BV(3);
if ((flag_a&_BV(3))==0) //測試flag_a第3bit是否為0
{
flag_a^=_BV(7); //令flag_a第7bit反轉
}
else flag_a^=_BV(6); //令flag_a第6bit反轉
//flag_b^=_BV(3);
if (bit_is_clear (flag_b,0x03)) //測試flag_b第3bit是否為0
{
flag_b|=_BV(04);//令flag_b第4bit為1
}
if (bit_is_clear (flag_b,0x03)) //測試flag_b第3bit是否為0
{
flag_b|=_BV(04);//令flag_b第4bit為1
}
if (bit_is_set (flag_b,0x03)) //測試flag_b第3bit是否為1
{
flag_b&=~_BV(04);//令flag_b第4bit為0
}
{
flag_b&=~_BV(04);//令flag_b第4bit為0
}
flag_a=0xa1;
flag_a=flag_a|flag_a_2;
_clr_aa;
flag_a=flag_a|flag_a_2;
_clr_aa;
_set_aa ;
flag_a=flag_a&~flag_a_2;
}
flag_a=flag_a&~flag_a_2;
}
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。