所以我试图对微控制器上的寄存器中的某些位进行ORR。 到目前为止,我一直在使用汇编,现在我正在使用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;
我收到错误“表达式必须是可修改的左值”
我在这里做错了什么,我正在使用它是我的抵消尝试。
答案 0 :(得分:1)
赋值操作通常不能在左侧进行另一操作的结果。在没有深入研究左值和右值之间的差异的情况下,赋值运算符左侧的值必须是可修改的,而加法运算符的结果则不是(更多关于{{3的答案中的左值和右值) }})。我认为PORTA+GPIO_DIR
是指针算术,所以可能是这样的:
PORTA[GPIO_DIR] = *(PORTA+GPIO_DIR)|inMask;
PORTA[GPIO_DIR]
和*(PORTA+GPIO_DIR)
都会产生相同的左值,即数组GPIO_DIR
中索引PORTA
的元素。我已经把两者都包括在内,所以你可以决定你喜欢哪种,但通常使用左边的。
答案 1 :(得分: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