找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6302|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

Char型變量與Bit型變量,如何進行”或運算”。

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:418269 發(fā)表于 2018-12-2 00:03 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
大神們,本人C語音小白。學(xué)習(xí)金沙工作時宋雪松老師《手把教你學(xué) 51 單片機 -C語音版》遇到不同變量直接的運算問題。
小人看C語言描述 :運算時 都是短字節(jié)向長字節(jié)轉(zhuǎn)換。如char型變量 & int型變量,進行運算時,是編譯器強制將char 轉(zhuǎn)換成int型。

但宋雪松老師講的如下:連續(xù)將key4值通過T0中斷,一位一位用“或運算“寫入char 型變量keybuf中。這與其他地方對不同變量的運算描述不符,請大神們賜教。小弟拜謝。

void InterruptTimer0() interrupt 1
{  static unsigned char keybuf = 0xFF;  //按鍵掃描緩沖區(qū),保存一段時間內(nèi)的掃描值   
    TH0 = 0xF8; TL0 = 0xCD;   
    keybuf = (keybuf << 1) | KEY4;  //只取KEY4為例,緩沖區(qū)左移一位,并將當(dāng)前掃描值移入最低位
    if (keybuf == 0x00)
    { //當(dāng)連續(xù)8次掃描值都為0,即16ms內(nèi)都只檢測到按下狀態(tài)時,可認(rèn)為按鍵已按下
        KeySta = 0;       //按鍵狀態(tài)值為按下
    }
    else if (keybuf == 0xFF)
    { //當(dāng)連續(xù)8次掃描值都為1,即16ms內(nèi)都只檢測到彈起狀態(tài)時,可認(rèn)為按鍵已彈起
        KeySta = 1;      //按鍵狀態(tài)值為彈起
  }

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:52586 發(fā)表于 2018-12-2 02:38 | 只看該作者
char 變量與 bit 變量 或運算,也是把 bit 轉(zhuǎn)換成 char

看程序發(fā)現(xiàn),這是個定時器中斷,中斷間隔為 2ms
KEY4 是個 bit,按下為0,彈起為1
keybuf 是個局部靜態(tài)變量,其值在函數(shù)退出后仍能保存。

程序執(zhí)行流程:
1,當(dāng)key被按下后,進入中斷,keybuf 當(dāng)前值為 0xFF
2,由于機械按鍵存在抖動,所以要去抖,程序中采用了檢測8次的方法來去抖
3,keybuf = (keybuf << 1) | KEY4;
    假定這次讀出的 KEY4 為0, keybuf 左移一位變成 b1111 1110 然后與 KEY4 或運算
    注意此處進行了轉(zhuǎn)換,將 KEY4 的 bit 類型值轉(zhuǎn)換成 char, 二進制 b0000 0000
    運算結(jié)束后, keybuf 結(jié)果為 0xFE ,用二進制表示為 1111 1110
    2ms 后,第二次進中斷,如果 KEY4 還是 0 ,那么 keybuf 的值為  b1111 1100
4,如果進入中斷 8 次,讀出的 KEY4 都為 0, 那么 keybuf 的值就變成 0x00
5,由于抖動期間, KEY4 的值會變化 01,所以如果存在抖動,keybuf 的值就不是 b0000 0000
    有可能是  b1100 0001 這樣的

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

板凳
ID:357520 發(fā)表于 2018-12-2 16:16 | 只看該作者
10.1 數(shù)字秒表實驗10.1.1 不同數(shù)據(jù)間的類型轉(zhuǎn)換
在C語言中,不同數(shù)據(jù)類型之間是可以混合運算的。當(dāng)表達式中的數(shù)據(jù)類型不一致時,首先轉(zhuǎn)換為同一種類型,然后再進行計算。C語言有兩種方法實現(xiàn)類型轉(zhuǎn)換,一是自動類型轉(zhuǎn)換,另外一種是強制類型轉(zhuǎn)換。這塊內(nèi)容是比較繁雜的,因此我們根據(jù)我們常用的編程應(yīng)用來講部分相關(guān)內(nèi)容。
當(dāng)不同數(shù)據(jù)類型之間混合運算的時候,不同類型的數(shù)據(jù)首先會轉(zhuǎn)換為同一類型,轉(zhuǎn)換的主要原則是:短字節(jié)的數(shù)據(jù)向長字節(jié)數(shù)據(jù)轉(zhuǎn)換。
比如:unsigned char  a ;  unsigned int b;  unsigned int c;  c = a *b;
在運算的過程中,程序會自動全部按照unsigned int型來計算。比如a=10,b=200,c的結(jié)果就是2000。那當(dāng)a=100,b=700,那c是70000嗎?新手最容易犯這種錯誤,大家要注意每個變量的數(shù)據(jù)類型,c的數(shù)據(jù)類型是unsigned int型,取值范圍是0~65535,70000超過65535溢出了,所以最終c的結(jié)果是(70000 - 65536) = 4464。
那要想讓c正常獲得70000這個結(jié)果,需要把c定義成一個unsigned long型。我們?nèi)绻麑懗桑簎nsigned char  a=100;  unsigned int  b=700;  unsigned long  c=0;  c = a *b;如果有做過實驗的同學(xué),會發(fā)現(xiàn)這個c的結(jié)果還是4464,這個是個什么情況呢?
大家注意,C語言不同類型運算的時候數(shù)值會轉(zhuǎn)換同一類型運算,但是每一步運算都會進行識別判斷,不會進行一個總的分析判斷。比如我們這個程序,a和b相乘的時候,是按照unsigned int類型運算的,運算的結(jié)果也是unsigned int類型的4464,只是最終把unsigned int類型4464賦值給了一個unsigned long型的變量而已。我們在運算的時候如何避免這類問題的產(chǎn)生呢?可以采用強制類型轉(zhuǎn)換的方法。
在一個變量前邊加上一個變量類型,并且這個變量類型用小括號括起來,表示把這個變量強制轉(zhuǎn)換成括號里的變量類型。如 c = (unsigned long)a * b;由于強制類型轉(zhuǎn)換運算優(yōu)先級高于*,所以這個地方的運算是先把a轉(zhuǎn)換成一個unsigned long型的變量,而后與b相乘,根據(jù)C語言的規(guī)則b會自動轉(zhuǎn)換成一個unsigned long型的變量,而后運算完畢結(jié)果也是一個unsigned long型的,最終賦值給了c。
當(dāng)不同類型變量相互賦值時,短字節(jié)的數(shù)據(jù)向長字節(jié)的變量賦值時,值不變,比如unsigned char  a=100;  unsigned int  b=700;  b = a;那么最終b的值就是100了。但是如果我們的程序是unsigned char  a=100;  unsigned int  b=700;  a=b;那么a的值僅僅是取了b的低8位,我們首先要把700變成一個16位的二進制數(shù)據(jù),然后取它的低8位出來,也就是188,這就是長字節(jié)給短字節(jié)賦值的結(jié)果。
在51單片機里邊,有一種特殊情況,就是bit類型的變量,這個bit類型的強制類型轉(zhuǎn)換,是不符合上邊講的這個原則的,比如bit a = 0;  unsigned char b; a = (bit)b;這個地方要特別注意,使用bit做強制類型轉(zhuǎn)換,不是取b的最低位,而是他會判斷b這個變量是0還是非0的值,如果b是0,那么a的結(jié)果就是0,如果b是任意非0的其他數(shù)字,那么a的結(jié)果都是1。

這是咱們站里的學(xué)習(xí)資料或許對你有幫助
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表