2013-06-18 118 views
3

我使用Keil uVision編程4.Keil uVision(C51編譯器),一元運算符「!」的含義是什麼?

我有一些像這樣的代碼:

sbit X = P3^3; // X is third bit of P3 register 

... 

    while (1) { 
     X = !X; // X equals not X ?! 

     if (X == 0) 
     printf("0"); 
     else 
     printf("1"); 
    } 

我可以控制`P3^3通用輸入引腳,因爲該引腳上我有一個PIR(脈衝紅外傳感器)。當它閃爍時,它在那條線上給我1,當它在睡覺時給它0。

P3^3被拉到1, 輸出(如預期)10101010101010..

當它仍然爲0, 輸出(不預期)0000000000000..

我的行爲因爲sbit X被PIR設置/未設置。

所以問題是,在Keil C51編譯器中運算符!的含義是什麼?

+0

該文檔指出'sbit'不能在一個函數內聲明,所以我還假設這個代碼片段被省略了?用一個省略號('...')來表明它是正規的('...') – Clifford

+0

只需要清楚,當輸入低時描述'預期'輸出可能會有幫助,因爲在分析中我認爲它的行爲正確* (即編碼)給定了sbit語言擴展的硬件和語義。 – Clifford

+0

是的範圍是全球範圍。 我期待與線路很高時的輸出相同。 實際上,我以爲'!'和'〜'是一樣的。 –

回答

4

在Keil的C51,引述manual

的SBIT類型定義有點特殊功能寄存器(SFR)

那麼,你是不是聲明一個變量X並在循環之前讀取一次,而您正在定義一個參考到P3.3,並在循環的每次迭代中讀取它的狀態。也就是說,X是硬件I/O引腳寄存器的引用,而不是變量。

儘管出現sbit不是簡單的typedef別名,而^也不是按位異或運算符。而是定義了對位尋址寄存器的引用。分配X寫入硬件寄存器 - 這種情況下,行爲由硬件定義,而不是語言。在外部拉高時顯然能夠改變X的值的能力,我猜測是GPIO硬件的本質,而不是運營商的任何奇怪行爲。檢查I/O引腳行爲的硬件文檔,但我又猜拉大使得引腳輸出能力

要獲得的行爲(我想)你想到你會這樣的代碼吧:

sbit p = P3^3; // p is third bit of P3 register 


... 
int X = p ; // get p's current value 

while (1) { 
    X = !X; // X equals not X ?! 

    if (X == 0) 
    printf("0"); 
    else 
    printf("1"); 
} 
+0

對不起,不清楚,在P3^3我有一個PIR(脈衝紅外傳感器)。當它閃爍時,它在那條線上給我1,當它在睡覺時給它0。我得到的行爲是我上面描述的,考慮到'sbit X'被PIR設置/取消設置。 –

+1

@FilippoLauria:我指的是MCU GPIO硬件,而不是你連接到引腳的硬件。我相信在8051上,一個端口被配置爲一個輸入,通過寫入零來允許它在外部斷言。你寫1到引腳將它設置爲輸入,此後你只應該讀它 - 你寫在表達式'X =!X'中,所以你在while循環中的輸入和輸出之間切換。正如我所說的,檢查您的MCU的文檔。 – Clifford

0

據推測這意味着它是指標準C. !x同樣的事情的計算結果爲1如果x==0,或以其它方式0。結果是int

如果您正在尋找反轉所有位的位反轉補碼,您需要~運算符。

UPDATE:

還有比這更給它;見Clifford's answer

+0

我認爲c51是標準C的擴展。如果你所說的是正確的,爲什麼編譯器在我試圖給'sbit'分配'int'時爲什麼不給我一個錯誤(或警告)? –

+0

@FilippoLauria:我不知道;很可能我錯了。我熟悉C,而不是Keil C51。當你明確地給'sbit'賦一個'int'值時,你會得到一個警告嗎? –

+0

我試過'(int x = 1; sbit y = P3^3; ... y = x;)'沒有警告被觸發。也許就像你說的那樣,出於某種原因,我認爲這種行爲在我看來很奇怪。 –