在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

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

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

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

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

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


            說明:
            由于AVR不支持位操作,所以必須通過軟件來實現(xiàn)。下面對我所知道的兩種方法進(jì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
            測試程序完成如下操作。
            當(dāng)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,代碼真是苦澀,,我看不懂,準(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.菜論:魚和熊掌。
            由于AVR可以對I/O腳進(jìn)行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://www.biyoush.com/article/201611/322371.htm


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

            評論


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

            關(guān)閉