首页 AVR的两种位操作的比较(位域方式和移位宏方式)

AVR的两种位操作的比较(位域方式和移位宏方式)

举报
开通vip

AVR的两种位操作的比较(位域方式和移位宏方式)AVR的两种位操作的比较(位域方式和移位宏方式) 测试环境如下: 硬件:AT90S2313 软件:    WiinAVR gcc3.3   -Os级优化(最小size)。 说明:     由于AVR不支持位操作,所以必须通过软件来实现。下面对我所知道的两种方法进行一个简单的比较。     1、位域方式。先定义一个位域,             typedef struct _bit_struct             {                 unsigned char bit0 : 1 ;      ...

AVR的两种位操作的比较(位域方式和移位宏方式)
AVR的两种位操作的比较(位域方式和移位宏方式) 测试环境如下: 硬件:AT90S2313 软件:    WiinAVR gcc3.3   -Os级优化(最小size)。 说明:     由于AVR不支持位操作,所以必须通过软件来实现。下面对我所知道的两种方法进行一个简单的比较。     1、位域方式。先定义一个位域,             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    ,    LED ==1.         这种方法类似C51中的位操作。直接。     2、位移宏方式。主要有三个.                 #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);     3、测试程序.        说明,假设PORTB.7接按纽,PORTB.0 接LED        测试程序完成如下操作。          当BUTTON == 0时 ,LED输出1 否则输出0,        这样的目的是即测试了输入,又测试了输出1和输出0,相对全面一点。  C代码如下.                 // testled.c     测试AVR的位操作.                 // 这是gcc;如是其它编译器,请修改。                 #include                 // 定义一个寄存器(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(PORTB,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           ldi    r29, 0x00    ; 0                       4e:    de bf           out    0x3e, r29    ; 62                       50:    cd bf           out    0x3d, r28    ; 61                         DDRB = 0x41;      //配置PB0为输出,PB7为输入                       52:    81 e4           ldi    r24, 0x41    ; 65                       54:    87 bb           out    0x17, r24    ; 23                         if ( BUTTON==0 )     LED = 1; else LED = 0;                       56:    86 b3           in    r24, 0x16    ; 22                       58:    e8 2f           mov    r30, r24                       5a:    ff 27           eor    r31, r31                       5c:    80 81           ld    r24, Z                       5e:    86 fd           sbrc    r24, 6                       60:    07 c0           rjmp    .+14         ; 0x70                       62:    88 b3           in    r24, 0x18    ; 24                       64:    e8 2f           mov    r30, r24                       66:    ff 27           eor    r31, r31                       68:    80 81           ld    r24, Z                       6a:    81 60           ori    r24, 0x01    ; 1                       6c:    80 83           st    Z, r24                       6e:    06 c0           rjmp    .+12         ; 0x7c                       70:    88 b3           in    r24, 0x18    ; 24                       72:    e8 2f           mov    r30, r24                       74:    ff 27           eor    r31, r31                       76:    80 81           ld    r24, Z                       78:    8e 7f           andi    r24, 0xFE    ; 254                       7a:    80 83           st    Z, r24                         while(1);                       7c:    ff cf           rjmp    .-2          ; 0x7c main函数共52Bytes.其中,从lst文件看得出:main函数的初始化用了4条指令,8Bytes. 最后一句while(1);用了1条指令2Bytes.( for循环和do-while也是)          DDRB="0x41用了2条指令4Bytes". 计算一下:52-8-4-2=38Bytes,即if ( BUTTON==0 )     LED = 1; else LED = 0; 这句用了19条指令38Bytes. (居然运用了3个寄存器白r24,r30,r31,和一个Z,代码真是苦涩,,我看不懂,准备以后作代码加密用:).  )        b.使用移位宏方式。        将 if ( BUTTON==0 )     LED = 1; else LED = 0;  换为等效的     if(!Get_Bit(PINB,7) )  Set_Bit(PORTB,0);    else Clr_Bit(PORTB,0);        结果,main函数仅24Bytes.其它代码一样,略去. 所以,上面这句代码仅用了24-14=10Bytes ,5条指令。生成的代码如下:               56:    b7 99           sbic    0x16, 7    ; 22               58:    02 c0           rjmp    .+4          ; 0x5e               5a:    c0 9a           sbi    0x18, 0    ; 24               5c:    01 c0           rjmp    .+2          ; 0x60               5e:    c0 98           cbi    0x18, 0    ; 24     5. 菜论:鱼和熊掌。       由于AVR可以对I/O脚进行sbic,sbi,cbi,这样的位操作,所以使用I/O脚操作时,移位宏可以产生高效的代码。       例如,要实现上面的几个简单的指令,为了实现LED=1这样的类似C51的sbit的效果,我必须多付出(38-10=28Bytes)的代价。     6......         对于I/O脚,可以产生这样高效的代码,是因为有sbi和cbi这样的指令,那么对于一般的变量,又如何呢?................
本文档为【AVR的两种位操作的比较(位域方式和移位宏方式)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_917323
暂无简介~
格式:doc
大小:34KB
软件:Word
页数:4
分类:互联网
上传时间:2011-08-26
浏览量:18