<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > AVR單片機C語(yǔ)言程序設計中的位操作

AVR單片機C語(yǔ)言程序設計中的位操作

作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò ) 收藏
在標準C語(yǔ)言的的教材中,對于位運算的操作是基本不涉及的,但是在單片機系統的程序中,需要經(jīng)常操作各類(lèi)以字節為單位的寄存器,而這些寄存器通常都是以二進(jìn)制中的位為控制單位的數據組合。往往一個(gè)8位寄存器中的每一位都有各自的控制對象,例如端口B的方向寄存器DDRB,如下圖所示


它實(shí)際上控制著(zhù)PB口的8個(gè)端口PB0-PB7的方向,也就是說(shuō)它的每一位都控制一個(gè)端口的方向,如果我們要把端口PB0-PB3設置為輸出口,而把PB4-PB7設置為輸入口,在不用位運算符的情況下,我們可以直接使用賦值語(yǔ)句DDRB=0x0f來(lái)實(shí)現,這樣是完全可以實(shí)現的。
但是如果出現下面的情況:在程序中PB口的8位端口的狀態(tài)本來(lái)是1、3、5、7為輸入。0、2、4、6為輸出(即DDRB=0x55),接下來(lái)要將PB口的第1位設置為輸出,其它端口的狀態(tài)不變,然后又要將第2位設置為輸入,其它端口的狀態(tài)不變。該怎么實(shí)現?也許我們仍然可以使用賦值語(yǔ)句來(lái)實(shí)現,比如DDRB=0x55;接下來(lái)設置DDRB=0x57;然后再設置DDRB=0x53;首先要肯定的是,這種做法是絕對正確的。但是我們可能有沒(méi)有注意到,在改變其中一位的值的時(shí)候,我們同時(shí)還要考慮其它7位的狀態(tài),并且要小心翼翼的避免不小心改變了其它位的值。
那么有沒(méi)有一種方法,可以簡(jiǎn)單的實(shí)現修改某一位的狀態(tài),同時(shí)不會(huì )改變其它位的狀態(tài)呢?
這就牽出了單片機C語(yǔ)言程序設計中的位運算的概念。
我們來(lái)看這個(gè)語(yǔ)句:DDRE |= (1 << PE5); 這個(gè)語(yǔ)句實(shí)現的功能是將PE口的第5位設置為輸出口,其余口的狀態(tài)不變。它是怎么實(shí)現的?首先我們來(lái)看1 << PE5這個(gè)表達式,我們前面已經(jīng)介紹了,AVR各寄存器的宏定義是在頭文件io.h中定義好的,我們可以直接調用,現在

本文引用地址:http://dyxdggzs.com/article/201611/318725.htm

我們就來(lái)看看在io.h中PE5是如何定義的(在WINAVR的安裝目錄下查找iom64.h),我們可以看到PE口的8位分別定義如下:
/* Port E Data Register - PORTE */
#define PE7 7
#define PE6 6
#define PE5 5
#define PE4 4
#define PE3 3
#define PE2 2
#define PE1 1
#define PE0 0
可以看出,實(shí)際上PE5=5;那么1 << PE5,就很容易理解了,它的作用是把1左移5位,最后的結果按照二進(jìn)制表示就是0b00100000,而DDRE|= (1 << PE5);實(shí)際上是DDRE= DDRE | (1 << PE5);首先“|”表示的是“或”操作,DDRE是端口E的方向寄存器,在iom64.h中定義為:

#define DDRE _SFR_IO8(0x02);它實(shí)際上是定義了一個(gè)標識符,這個(gè)標識符對應數據存儲區RAM中的某個(gè)地址,這個(gè)我們暫且不去深究。我們還是回過(guò)頭來(lái)看DDRE= DDRE | (1 << PE5);這句話(huà)實(shí)現的功能,這句話(huà)實(shí)際上是將寄存器DDRE中的內容(數據)跟二進(jìn)制數0b00100000進(jìn)行或操作,我們知道兩個(gè)數的或操作的結果是:只要有一個(gè)是1,結果就是1.那么假如DDRE中本來(lái)的值是0b10001010(0x8a),它和0b00100000進(jìn)行“或”操作以后的結果變成了0b10101010(0xaa)。我們可以看出,相或以后DDRE中的第5位以外的各位的值都沒(méi)有改變,而第5位變成了1,我們的目的就是要將第5位設為輸出口(即將第5位設置為1)。
現在我們來(lái)看一下從語(yǔ)言中有幾種位運算符:
移位運算符:左移<<,右移>>
與運算符:&
或運算符:|
取反運算符:~
異或運算符:^
就這些了,總共只有6種位運算符?,F在我們來(lái)看一下這些運算符都起什么作用;
左移運算符:表達形式為x< 例如,x是一個(gè)unsigned char類(lèi)型的數據(即x是一個(gè)單字節數據,共有8位),設x的初值為0x00000001,執行x<n=0時(shí),x<n=1時(shí),x<n=2時(shí),x<...
n=7時(shí),x<n=8時(shí),x< 從結果來(lái)看,當n在1-7之間取值時(shí),運算的結果總是1依次向左移動(dòng)一位,但是當n>=8以后,x的值就一直是0了,這是因為x是一個(gè)只有8位的整形變量,它的最大二進(jìn)制長(cháng)度是8位,當n超過(guò)8以后,移位操作的結果已經(jīng)超出8位的范圍了,產(chǎn)生了溢出現象。
右移的原理跟左移相似,只是它的運算結果跟左移剛好相反。
在單片機C語(yǔ)言編程中,經(jīng)常使用移位操作來(lái)實(shí)現將數據乘以(左移)或除以(右移)2的n次方的乘除運算,利用移位操作實(shí)現乘除運算可以顯著(zhù)提高單片機的運算速度和效率。其詳細原理我們可以翻閱相關(guān)的C語(yǔ)言書(shū)籍來(lái)進(jìn)行更深了解。
“取反”、“與”、“或”、“非”運算經(jīng)常用于對寄存器的某一位進(jìn)行操作,
例如,使端口B的第二位輸出高電平,同時(shí)不改變其余端口的狀態(tài),我們可以采用如下方法:
PORTB |= (1<實(shí)際上,想將一個(gè)8位寄存器的某一位設置為1,可以采用這樣的語(yǔ)句:寄存器名(如PORTB) |= (1 << X),式中X表示第X位。
相反的,如果想將一個(gè)8位寄存器的某一位設置為0,可以采用這樣的語(yǔ)句:寄存器名(如PORTB) &= ~(1 << X),式中X表示第X位。

寫(xiě)著(zhù)的時(shí)候,總感覺(jué)心里清楚,但是表達不出來(lái),本來(lái)是想結合單片機來(lái)講解如何用C語(yǔ)言來(lái)開(kāi)發(fā)單片機程序的,但總是沒(méi)有辦法將兩者的結合很直觀(guān)的表達出來(lái)。有些困惑!
這或許就是現在市面上相當多的講解單片機C語(yǔ)言開(kāi)發(fā)的書(shū)為什么總是將C語(yǔ)言的講解和具體的程序設計分開(kāi)來(lái)講的原因吧。大家都沒(méi)有更好的辦法在講解具體的單片機開(kāi)發(fā)的同時(shí)把C語(yǔ)言的知識逐步融合到實(shí)例中



評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>