<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > AVR筆記9:AVR的兩種位操作的比較

          AVR筆記9:AVR的兩種位操作的比較

          作者: 時(shí)間:2016-11-27 來(lái)源:網(wǎng)絡(luò) 收藏
          AVR的兩種位操作的比較(wjc3k發(fā)于21ic)(位域與C位操作的比較)

          AVR的兩種位操作的比較(位域方式和移位宏方式)

          測(cè)試環(huán)境如下:
          硬件:AT90S2313
          軟件:WiinAVRgcc3.3-Os級(jí)優(yōu)化(最小size)。


          說(shuō)明:
          由于AVR不支持位操作,所以必須通過(guò)軟件來(lái)實(shí)現(xiàn)。下面對(duì)我所知道的兩種方法進(jìn)行一個(gè)簡(jiǎn)單的比較。
          1、位域方式。先定義一個(gè)位域,
          typedefstruct_bit_struct
          {
          unsignedcharbit0:1;
          unsignedcharbit1:1;
          unsignedcharbit2:1;
          unsignedcharbit3:1;
          unsignedcharbit4:1;
          unsignedcharbit5:1;
          unsignedcharbit6 :1;
          unsignedcharbit7:1;
          }bit_field;
          再用一個(gè)宏,來(lái)指向要操作的位。
          #defineLEDGET_BITFIELD(PORTB).bit0
          #defineBUTTONGET_BITFIELD(PINB).bit7
          使用時(shí)只需要直接賦值即可:如LED=0,LED=1,或者直接判斷LED==0,LED==1.
          這種方法類似C51中的位操作。直接。
          2、位移宏方式。主要有三個(gè).
          #defineSet_Bit(val,bitn)(val|=(1<<(bitn)))
          #defineClr_Bit(val,bitn)(val&=~(1<<(bitn)))
          #defineGet_Bit(val,bitn)(val&(1<<(bitn)))
           三個(gè)分別用來(lái)設(shè)置某一位,清除某一位,取某一位的值.
          使用方法為.Set_Bit(PORTA,3);Clr_Bit(PORTB,2);Get_Bit(val,5);
          3、測(cè)試程序.
          說(shuō)明,假設(shè)PORTB.7接按紐,PORTB.0接LED
          測(cè)試程序完成如下操作。
          當(dāng)BUTTON==0時(shí),LED輸出1否則輸出0,
          這樣的目的是即測(cè)試了輸入,又測(cè)試了輸出1和輸出0,相對(duì)全面一點(diǎn)。C代碼如下.

          //testled.c測(cè)試AVR的位操作.
          //這是gcc;如是其它編譯器,請(qǐng)修改。
          #i nclude<avr/io.h>

          //定義一個(gè)寄存器(Register)或端口(Port)的八個(gè)位
          typedefstruct_bit_struct
          {
          unsignedcharbit0:1;
          unsignedcharbit1:1;
          unsignedcharbit2:1;
          unsignedcharbit3:1;
          unsignedcharbit4:1;
          unsignedcharbit5:1;
          unsignedcharbit7:1;
          unsignedcharbit6:1;
          }bit_field;

          //定義一個(gè)宏,用來(lái)得到每一位的值
          #defineGET_BITFIELD(addr)(*((volatilebit_field*)(addr)))

          //定義每一個(gè)位
          #defineLEDGET_BITFIELD(PORTB).bit0
          #defineBUTTONGET_BITFIELD(PINB).bit7


          #defineSet_Bit(val,bitn)(val|=(1<<(bitn)))
          #defineClr_Bit(val,bitn)(val&=~(1<<(bitn)))
          #defineGet_Bit(val,bitn)(val&(1<<(bitn)))

          intmain(void)
          {
          DDRB=0x41;//配置PB0為輸出,PB7為輸入
          if(BUTTON==0)LED=1;elseLED=0;
          //if(!Get_Bit(PINB,7))Set_Bit(PORTB,0);elseClr_Bit(PORTB,0);
          while(1);
          }
          //----------------------end-----------------------------
          4、測(cè)試過(guò)程。
          a.先使用位域方式。
          主程序中使用if(BUTTON==0)LED=1;elseLED=0;
          結(jié)果如下:
          intmain(void)
          {
          4a:cfedldir28,0xDF;223
          4c:d0e0ldir29,0x00;0
          4e:debfout0x3e,r29;62
          50:cdbfout0x3d,r28;61
          DDRB=0x41;//配置PB0為輸出,PB7為輸入
          52:81e4ldir24,0x41;65
          54:87bbout0x17,r24;23
          if(BUTTON==0)LED=1;elseLED=0;
          56:86b3inr24,0x16;22
          58:e82fmovr30,r24
          5a:ff27eorr31,r31
          5c:8081ldr24,Z
          5e:86fdsbrcr24,6
          60:07c0rjmp.+14;0x70
          62:88b3inr24,0x18;24
          64:e82fmovr30,r24
          66:ff27eorr31,r31
          68:8081ldr24,Z
          6a:8160orir24,0x01;1
          6c:8083stZ,r24
          6e:06c0rjmp.+12;0x7c
          70:88b3inr24,0x18;24
          72:e82fmovr30,r24
          74:ff27eorr31,r31
          76:8081ldr24,Z
          78:8e7fandir24,0xFE;254
          7a:8083stZ,r24
          while(1);
          7c:ffcfrjmp.-2;0x7c

          main函數(shù)共52Bytes.其中,從lst文件看得出:main函數(shù)的初始化用了4條指令,8Bytes.最后一句while(1);用了1條指令2Bytes.(for循環(huán)和do-while也是)
          DDRB=0x41用了2條指令4Bytes.計(jì)算一下:52-8-4-2=38Bytes,即if(BUTTON==0)LED=1;elseLED=0;這句用了19條指令38Bytes.(居然運(yùn)用了3個(gè)寄存器白r24,r30,r31,和一個(gè)Z,代碼真是苦澀,,我看不懂,準(zhǔn)備以后作代碼加密用:).)
          b.使用移位宏方式。
          if(BUTTON==0)LED=1;elseLED=0;換為等效的if(!Get_Bit(PINB,7))Set_Bit(PORTB,0);elseClr_Bit(PORTB,0);

          結(jié)果,main函數(shù)僅24Bytes.其它代碼一樣,略去.所以,上面這句代碼僅用了24-14=10Bytes,5條指令。生成的代碼如下:
          56:b799sbic0x16,7;22
          58:02c0rjmp.+4;0x5e
          5a:c09asbi0x18,0;24
          5c:01c0rjmp.+2;0x60
          5e:c098cbi0x18,0;24
          5.菜論:魚(yú)和熊掌。
          由于AVR可以對(duì)I/O腳進(jìn)行sbic,sbi,cbi,這樣的位操作,所以使用I/O腳操作時(shí),移位宏可以產(chǎn)生高效的代碼。
          例如,要實(shí)現(xiàn)上面的幾個(gè)簡(jiǎn)單的指令,為了實(shí)現(xiàn)LED=1這樣的類似C51的sbit的效果,我必須多付出(38-10=28Bytes)的代價(jià)。

          6......
          對(duì)于I/O腳,可以產(chǎn)生這樣高效的代碼,是因?yàn)橛衧bi和cbi這樣的指令,那么對(duì)于一般的變量,又如何呢?................

          本文引用地址:http://www.ex-cimer.com/article/201611/322371.htm


          關(guān)鍵詞: AVR筆記位操

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();