首页 > 解决方案 > 了解嵌入式 C 中的 I/O 内存位置

问题描述

• 声明一个指针,

int *p;

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

 p = (int*) 0x30610000;

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

标签: cpointersembedded

解决方案


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. 这是因为编译器需要更多的指令来检索寄存器的地址。


推荐阅读