了解嵌入式 C 中的 I/O 内存位置

ali_cr8

• 声明一个指针,

int *p;

• 将 I/O 内存位置的地址分配给指针

 p = (int*) 0x30610000;

我想访问0x30610000具有要配置的寄存器的内存位置为什么我们要类型转换呢?不应该p =0x30610000;指向位置吗?

0______

int *p;

p = (int*) 0x30610000;

方法和实现都不好。

  1. 使用宏(不是指针变量)访问映射到地址空间的硬件寄存器。这是更有效的方式。
  2. 使用固定大小的整数。
  3. 将寄存器声明为volatile. 它们肯定容易产生副作用:)
#define  REG1  (*(volatile uint32_t *)0x30610000)

和用法:

REG1 = 0x456;
foo(REG1);

大多数外设都有不止一个寄存器。最好使用结构来访问它们(注意volatile关键字所在的位置。不要制作整个结构volatile):

typedef struct
{
    volatile uint32_t DR;
    volatile uint32_t CR;
    volatile uint32_t SR;
}UART_type;

#define UART1 ((UART_type *)0x45678000)

和用法:

UART1 -> CR = 0x45676;

在 C 语言中,需要强制转换来消除警告,因为它是一个 UB(或者可能只是定义为 @Clifford 建议的实现)。即使实现(如 ARM-gcc)以可预测的方式执行 - 它仍然会发出警告。

现在,为什么拥有指针对象的效率不如#define. 这是因为编译器需要更多的指令来检索寄存器的地址。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章