2014-10-03 42 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