色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

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

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

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


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

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

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

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

          //定義每一個位
          #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、測試過程。
          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.計算一下:52-8-4-2=38Bytes,即if(BUTTON==0)LED=1;elseLED=0;這句用了19條指令38Bytes.(居然運用了3個寄存器白r24,r30,r31,和一個Z,代碼真是苦澀,,我看不懂,準備以后作代碼加密用:).)
          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.菜論:魚和熊掌。
          由于AVR可以對I/O腳進行sbic,sbi,cbi,這樣的位操作,所以使用I/O腳操作時,移位宏可以產(chǎn)生高效的代碼。
          例如,要實現(xiàn)上面的幾個簡單的指令,為了實現(xiàn)LED=1這樣的類似C51的sbit的效果,我必須多付出(38-10=28Bytes)的代價。

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

          本文引用地址:http://cafeforensic.com/article/201611/322371.htm


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

          評論


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

          關(guān)閉