AVR的两种位操作的比较.doc
文本预览下载声明
AVR的两种位操作的比较(位域方式和移位宏方式)
AVR的两种位操作的比较(位域方式和移位宏方式)
测试环境如下:
硬件:AT90S2313
软件: WinAVR gcc3.3 -Os级优化(最小size)。
说明:由于AVR不支持位操作,所以必须通过软件来实现。下面对我所知道的两种方法进行一个简单的比较。
位域方式。
先定义一个位域,
typedef struct _bit_struct
{
unsigned char bit0 : 1 ;
unsigned char bit1 : 1 ;
unsigned char bit2 : 1 ;
unsigned char bit3 : 1 ;
unsigned char bit4 : 1 ;
unsigned char bit5 : 1 ;
unsigned char bit7 : 1 ;
unsigned char bit6 : 1 ;
}bit_field;
再用一个宏 ,来指向要操作的位。
#define LED GET_BITFIELD(PORTB).bit0
#define BUTTON GET_BITFIELD(PINB).bit7
使用时只需要直接赋值即可。
如LED = 0 ,LED = 1, 或者直接判断 LED==0
这种方法类似C51中的位操作,方便直接。
位移宏方式。
主要有三个.
#define Set_Bit(val, bitn) (val |=(1(bitn)))
#define Clr_Bit(val, bitn) (val=~(1(bitn)))
#define Get_Bit(val, bitn) (val (1(bitn)) )
三个分别用来设置某一位,清除某一位,取某一位的值。
使用方法为.Set_Bit(PORTA,3); Clr_Bit(PORTB,2); Get_Bit(val,5);
测试程序.
说明,假设PORTB.7接按键,PORTB.0 接LED
测试程序完成如下操作。
当BUTTON == 0时 ,LED输出1 否则输出0,
这样的目的是即测试了输入,又测试了输出1和输出0,相对全面一点。 C代码如下:
// testled.c 测试AVR的位操作.
// 这是gcc;如是其它编译器,请修改。
#include avr/io.h
// 定义一个寄存器(Register)或端口(Port)的八个位
typedef struct _bit_struct
{
unsigned char bit0 : 1 ;
unsigned char bit1 : 1 ;
unsigned char bit2 : 1 ;
unsigned char bit3 : 1 ;
unsigned char bit4 : 1 ;
unsigned char bit5 : 1 ;
unsigned char bit7 : 1 ;
unsigned char bit6 : 1 ;
}bit_field;
//定义一个宏,用来得到每一位的值
#define GET_BITFIELD(addr) (*((volatile bit_field *) (addr)))
//定义每一个位
#define LED GET_BITFIELD(PORTB).bit0
#define BUTTON GET_BITFIELD(PINB).bit7
#define Set_Bit(val, bitn) (val |=(1(bitn)))
#define Clr_Bit(val, bitn) (val=~(1(bitn)))
#define Get_Bit(val, bitn) (val (1(bitn)) )
//===============================================
int main( void )
{
DDRB = 0x41; //配置PB0为输出,PB7为输入
if ( BUTTON==0 ) LED = 1;
else LED = 0;
//移位宏方式if(!Get_Bit(PINB,7) ) Set_Bit(PORTB,0); else Clr_Bit(PORB,0);
while(1);
}
// ---------------------- end ---------------------------
4、测试过程。
a.先使用位域方式。
主程序中使用 if ( BUTTON==0 ) LED = 1; else LED = 0;
反编译结果如下:
int main( void )
{
//地址:机器码 反编译程序;
4a: cf ed ldi r28, 0xDF ; 223
4c: d0 e0
显示全部