【问题标题】:C address offsetsC 地址偏移量
【发布时间】:2014-10-03 07:57:43
【问题描述】:

所以我正在尝试对微控制器上的寄存器中的一些位进行 ORR。 到目前为止,我一直在使用 Assembly,现在我正在使用 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;

我收到一个错误“表达式必须是可修改的左值”

我在这里做错了什么,我正在使用它来尝试抵消。

【问题讨论】:

  • 嗯,你还没有很好地解释你的 C 代码。 PORTAGPIO_PORT_F 是一样的吗? GPIO_DIR 是整数偏移量吗?如果是这样,试试这个:*(PORTA+GPIO_DIR) |= inMask;
  • @squeamish,我相信你想写 *(PORTA+GPIO_DIR) |= inMask; .我同意你的“方法”,这可能是“字节我”正在寻找的解决方案
  • 如果PORTA 是一个指针,GPIO_DIR 是一个整数偏移量,那么PORTA[GPIO_DIR] 可用于获取或设置该指针偏移量处的值。
  • 对不起,我使用的示例和实际变量混淆了。我已经更新了这个问题。我尝试使用 PORTA[GPIO_DIR] |= inMask;并收到另一个错误“表达式必须具有指向对象类型的指针”(PORTA+GPIO_DATA) |= inMask;给出错误““ 的操作数必须是指针”

标签: c assembly


【解决方案1】:

一个赋值操作一般不能在左边有另一个操作的结果。在不深入探讨左值和右值之间的区别的情况下,赋值运算符左侧的值必须是可修改的,而加法运算符的结果则不是(更多关于左值和右值的信息,请参见this question 的答案) )。我认为PORTA+GPIO_DIR 是指针算术,所以可能是这样的:

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

PORTA[GPIO_DIR]*(PORTA+GPIO_DIR) 都产生相同的左值,即数组PORTA 中索引GPIO_DIR 处的元素。我已将两者都包括在内,因此您可以决定自己喜欢哪个,但通常使用左侧的。

【讨论】:

    【解决方案2】:

    如果我没看错,你想从内存中加载一个值,用某个值 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 2015-07-09
      • 2016-12-30
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多