2014-10-03 92 views
0

所以我試圖ORR一些微控制器上的寄存器位。 到目前爲止,我一直在使用Assembly,現在我正在使用C,我打了一些牆。C地址偏移

因此,在ASM中,如果我想訪問具有偏移量的寄存器,如。 GPIO_PORT_F和偏移GPIO_DATA我會使用下面的代碼。

LDR R0,=GPIO_PORT_F ;load the base 
LDR R1, [R0, #GPIO_DATA] ;load the offset 
ORR R1, 0x1 ;ORR it with a value 
STR R1, [R0, #GPIO_DATA] ;store back 

這是確切的操作我想執行,但在C 這就是我。

GPIO_PORT_F的定義如下 #define GPIO_PORT_F (*((unsigned long *)0x40025000))

(GPIO_PORT_F+GPIO_DATA) = (GPIO_PORT_F+GPIO_DATA) | inMask; 

我得到一個錯誤「表達必須修改的左值」

我在做什麼錯在這裏,我用這是我在抵消嘗試。

+1

那麼你沒有很好地解釋你的C代碼。 'PORTA'與'GPIO_PORT_F'相同嗎? GPIO_DIR是一個整數偏移量嗎?如果是這樣,試試這個:'*(PORTA + GPIO_DIR)| = inMask;' – 2014-10-03 08:01:32

+1

@squeamish,我相信你想寫*(PORTA + GPIO_DIR)| = inMask; 。我同意你的「方法」,它可能是解決方案「Byte Me」正在尋找 – 2014-10-03 08:05:55

+1

如果'PORTA'是一個指針,並且'GPIO_DIR'是一個整數偏移量,那麼'PORTA [GPIO_DIR]'可以用來獲取或設置該指針偏移的值。 – Will 2014-10-03 08:08:03

回答

1

賦值操作一般不能在左邊有另一個操作的結果。如果不深入研究左值和右值之間的差異,賦值運算符左側的值必須是可修改的,而加法運算符的結果不是(在this question的答案中的左值或右值)。我相信PORTA+GPIO_DIR是指針運算,因此,或許是這樣的:

PORTA[GPIO_DIR] = *(PORTA+GPIO_DIR)|inMask; 

PORTA[GPIO_DIR]*(PORTA+GPIO_DIR)都產生相同的左值,即在指數GPIO_DIR在陣列PORTA的元素。我已經包括這兩個,所以你可以決定你更喜歡哪個,儘管通常使用左邊的那個。

0

如果我正確地看到它,你想從內存中加載一個值,用一些值對它進行ORR,然後把它寫回到同一個地方。

一旦你正確地聲明瞭一個指針變量porta用正確的指針類型(大概就像uint32_t volatile*左右),你會怎麼做

porta = (uint32_t*)GPIO_PORT_F; // convert the base 
porta[GPIO_DATA] |= MASK;  // ORR it and store it back 

,你不得不擔心的唯一的事情是,如果GPIO_DATA偏移量以字節或單詞計算。如果以字節爲單位,則用

替換第二行
porta[GPIO_DATA/sizeof *porta] |= MASK;  // ORR it and store it back