【问题标题】:Calculate GPIO address计算GPIO地址
【发布时间】:2021-05-21 01:06:46
【问题描述】:

每个引脚使用两个位。

00 = input
01 = output

在一个示例中,他们将引脚 15-8 配置为输入,将引脚 7-0 配置为输出。

@ arm assembly
LDR R0,=0x40020C00
LDR R1,=0x00005555
STR R1,[R0]
/* c */
*( (unsigned long *)0x40020C00) = 0x5555;

这是“通用 IO”一章中的第一个示例,我完全迷失了。我以为我已经弄清楚他们是如何得到 0x00005555 的,但现在我不知道。如果每个引脚使用两位并且输出 01,我会得到 01 01 01 01,即 0x55 而不是 0x5555。他们使用 16 位得到 0x5555 = 0101 0101 0101 0101,我不明白为什么。

现在到引脚 15-8。在这里,我可悲的是什么都不懂。 00 用于输入,所以我得到 00 00 00 00。然后有一个偏移量 0x01,我不明白它应该如何使用。

非常感谢任何帮助,我想我需要一个更简单的例子来理解。


编辑:所以我混淆了位和引脚,感谢 NoTengoBattery。我理解 0101 0101 0101 0101 = 0x5555。但我仍然不明白我是如何从 0000 0000 0000 0000 到 0x40020C00 的。

【问题讨论】:

  • 0x00005555 表示针脚 15 到 8 配置为 2b00(输入),针脚 7 到 0 配置为 2b01(输出)。例如,如果引脚 0 和引脚 1 都得到 2b01,那么这意味着寄存器的低四位是二进制的 0101,即十六进制的 0x5,并且继续一次取 4 位并查看十六进制版本而不是二进制。 0x40020C00 只是 gpio 块的基地址,MODER 位于偏移量 0x00,因此 0x40020C00+0x00 是寄存器的地址 0x00005555 是该寄存器的数据。
  • 如果代码得到优化,你至少需要一个 volatile 。 *( (易失性无符号长 *)0x40020C00) = 0x5555;或更多括号。我使用抽象层来确保我想要发生的事情发生,而不是 C 魔法(可能会失败)。
  • 这看起来是 STM32 是吗?因此,如果您有一个 MODER,那么您就有一个 OTYPER,您需要确保输出也显示在该寄存器中。不看我认为重置值是推拉是吗?而且您不必弄乱它,但需要参考文档。

标签: c binary arm hex gpio


【解决方案1】:

您似乎在将二进制转换为十六进制时迷路了。请记住,每 4 个 位都可以表示为一个十六进制字符。以下是根据您所描述的内容对它们派生 0x5555 的位置的细分(我已将整个寄存器分成两部分,以便我自己在此答案框中处理自动换行,但想象它们被混合在一起):

       |pin15|pin14|pin13|pin12|pin11|pin10|pin09|pin08|
bit    |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
bin 0b |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
hex 0x |     0     |     0     |     0     |     0     |

       |pin07|pin06|pin05|pin04|pin03|pin02|pin01|pin00|
bit    |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
bin 0b |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |
hex 0x |     5     |     5     |     5     |     5     |

将所有内容放在一起,您会得到 0x00005555。 0x40020C00 显然是这个寄存器的地址。 *( (unsigned long *)0x40020C00) 将 0x40020C00 转换为 unsigned long 指针,然后取消引用该指针以使用 = 0x5555; 将 0x00005555 写入该地址。

【讨论】:

    【解决方案2】:

    我认为您的困惑来自对文本的理解,而不是概念。你说:

    ... 和引脚 7-0 作为输出 ...

    那是 8 个针脚。之后你说:

    ... 01 是输出我得到 01 01 01 01 即 0x55 ...

    如果您自己查看如何将其分开,则您只考虑 4 个引脚,而不是 8 个。如果您考虑 4 个引脚,那么您是对的,它是 0x55。如果考虑 8 个引脚,它的 0b0101010101010101 确实是 0x5555。

    【讨论】:

    • 天哪,你是完全正确的。我混淆了位和引脚。谢谢!
    猜你喜欢
    • 2015-08-19
    • 2019-06-01
    • 2012-08-01
    • 1970-01-01
    • 2013-05-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多