2011-10-29 31 views
2

我正在使用AVR微控制器通過I2C總線寫入可編程分頻器芯片。在一定的時間間隔,我想有以下函數被調用來更新芯片的輸出頻率:AVR GCC - 類型轉換問題

void 1077WriteDiv(int16_t data) 
{ 
    uint8_t upperByte = (uint8_t)((uint16_t)data>>2); 

    i2c_start(DS1077_BASE_ADDRESS); 
    i2c_write(DIVIDE_REGISTER); 
    i2c_write(upperByte); 
    i2c_write(0x0); 
    i2c_stop(); 
} 

我試圖得到一個10位的值的頂部8位中的「數據」變量並寫出來。第二個「寫入」命令寫入芯片上「分」寄存器的低8位,在這種情況下爲0。

作爲一個測試用例,我從零開始遞增「數據」變量(必須對其進行簽名),將其左移2位並每次調用該函數。我得到垃圾了。但是,當我這樣做時:

void 1077WriteDiv(int16_t data) 
    { 
     //uint8_t upperByte = (uint8_t)((uint16_t)data>>2); 
      static uint8_t thing = 0;  

     i2c_start(DS1077_BASE_ADDRESS); 
     i2c_write(DIVIDE_REGISTER); 
     i2c_write(thing++); 
     i2c_write(0x0); 
     i2c_stop(); 
    } 

一切都按預期工作。在我如何移動和類型化原始「數據」變量方面顯然存在一些問題,但我嘗試了各種排列方式,結果相同。如果有人能指出我可能會出錯的地方,我將非常感激。

+1

你能告訴我們正在做增量和左移的代碼嗎?也許這個代碼很糟糕。 –

+0

請給我們打電話的代碼... –

+0

gcc不是*真的*讓您使用'1077WriteDiv'作爲標識符,是嗎?你能告訴我們你的真實代碼嗎? –

回答

1

嘗試

uint8_t upperByte = (uint8_t) ((data & 0x3FC) >> 2); 

你不能靠強制轉換爲更小的int刪除您正試圖擺脫高序位。

1
i2c_write(thing++); 

這意味着你的分頻器會增加每個呼叫。如果增加「數據」並將其右移兩位,則您的分頻器每增加一個四個調用。你的兩個代碼段不相同。

你在什麼時間間隔調用這個函數?什麼是「垃圾出」?你怎麼知道傳入函數的值是正確的?您如何知道發送給DS1077的值是錯誤的?

檢查您的所有假設。

演員和輪班對我來說很好。至少我認爲他們可以在我以前使用的任何C編譯器中工作。從C標準立體可以參考此草案(ISO/IEC 9899:TC2 6.3換算):

否則,如果新類型是無符號的,所述值是通過 轉換反覆加上或減去小於最大值即 一個更可以用新類型表示,直到值在 的範圍內

這是我現在唯一可以訪問的一個。也許別人可以在標準問題上加入。編譯器可能不符合標準...

+0

不幸的是,這似乎更有可能是一個模糊的硬件問題。我花了幾個小時仔細查看反彙編程序,並在模擬器上逐步完成代碼,並且在模擬中一切正常。我真的無法找到_software_無法正常工作的原因。 – Bitrex

+0

@Bitrex通過您的詳細調查結果修正了問題,也許有人可以幫助您...不幸的是,大多數問題都是模糊的,直到「duh」momemnt :-) –