首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写入指向GPIO输出引脚地址的指针

写入指向GPIO输出引脚地址的指针
EN

Stack Overflow用户
提问于 2019-09-16 13:57:01
回答 4查看 453关注 0票数 4

嵌入式系统的绝对新手。现在,我正在尝试在C中编写一个名为nRF52832的设备。我知道GPIO的基地址是0x50000000,OUT寄存器的偏移量是0x504。如何创建指向GPIO地址的指针并打印该地址?

我有吗?

代码语言:javascript
复制
volatile unsigned int* GPIO_BASE = (unsigned int*) 0x50000000;
volatile unsigned int* GPIO_OUT = GPIO_BASE + 0x504; ?
EN

回答 4

Stack Overflow用户

发布于 2019-09-16 14:04:02

请记住,指针运算总是以指针基类型为单位进行的。

这意味着表达式GPIO_BASE + 0x504将添加0x504 * sizeof *GPIO_BASE的字节偏移量,即0x504 * sizeof(int) (在大多数系统上,它将是5136字节的偏移量,而不是1284字节)。

如果要添加0x504字节的偏移量,则需要将其除以指针基类型的大小:

代码语言:javascript
复制
volatile unsigned int* GPIO_OUT = GPIO_BASE + (0x504 / sizeof *GPIO_BASE);

除了这个问题,您的代码是正确的,并且是访问硬件寄存器的一种非常常见的方法。

票数 3
EN

Stack Overflow用户

发布于 2019-09-16 16:33:11

Do I do

易失性无符号整数* GPIO_BASE =(无符号整数*) 0x50000000;易失性无符号整数* GPIO_OUT = GPIO_BASE + 0x504;

不,你不需要。这意味着地址是在运行时计算的,因为volatile限定符意味着无论何时使用,程序都必须在运行时更新变量。

这是你应该做的事情:

代码语言:javascript
复制
// assuming 32 bit registers and 0x504 being the offset in bytes
#define GPIO_BASE 0x50000000u
#define GPIO_OUT  (*(volatile uint32_t*)(GPIO_BASE + 0x504u))
#define GPIO_X    (*(volatile uint32_t*)(GPIO_BASE + 0x508u)) // some other related register 

...
GPIO_OUT = something;

在本例中,寄存器地址是在编译时计算的,这是唯一正确的方法。

通过取消对宏内地址的引用,我们现在可以像使用普通变量一样使用GPIO_OUT

然而,一个GPIO外设似乎不太可能有数百个内存映射寄存器,所以值0x504很奇怪。

还请注意,在嵌入式系统中使用默认的C类型,如intchar,是很幼稚的。这些类型伴随着各种可移植性问题,并且还具有与它们相关的各种形式的模糊定义的行为。专业系统只使用来自stdint.h的类型,而不使用其他任何类型。

票数 2
EN

Stack Overflow用户

发布于 2019-09-16 14:01:47

代码语言:javascript
复制
volatile unsigned int* GPIO_BASE = (unsigned int*) 0x50000000;
volatile unsigned int* GPIO_OUT = GPIO_BASE + 0x504; 

如果OUT寄存器的offsetBASE相差0x504个字节,则需要将GPIO_BASE类型转换为char *

代码语言:javascript
复制
volatile unsigned int* GPIO_OUT = ((char *)GPIO_BASE) + 0x504; 

除此之外,一切都很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57951076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档