对底层代码的一点不理解

2019-07-14 15:04发布

为什么GPIOx->CRL直接代表了寄存器的值。
GPIOx是结构体指针
typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;



但是GPIOx并没有指向一个具体的结构体啊,CRL只是也只是结构体中的一个变量啊,为什么可以直接通过GPIOx->CRL来设置寄存器的值呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
yijun362
1楼-- · 2019-07-14 21:08
所以后面就可以用GPIOA访问寄存器了
60user36
2楼-- · 2019-07-15 00:52
首先GPIOx是有固定的地址的,这个地址已经被ARM的CMSIS规定好了,因此所有的硬件厂商,不管具体实现的方式如何,绝对的地址是相同的,这一为代码移植提供了可能。
typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;
结构体中,每个变量的长度都是4字节,因此,你是可以通过结构体计算出每个变量的实际地址,这个就是你看手册时候,手册上的偏移量的作用。
60user71
3楼-- · 2019-07-15 06:41
这样做的主要作用是减少代码量,因为每组GPIO都有那几个寄存器,所以可以定义一个struct来减少代码。
例如GPIOA
首先会定义定义外设基地址->APB2时钟总线的base_addr->GPIOA_ADDRESS_BASE
+(加号后面的属于偏移量)


如果GPIOA->CRL其实就是指向的是0x40000000+0x10000+0x0800+0x00= 0x40010800这个地址
如果是GPIOA->ODR就是指向0x40000000+0x10000+0x0800+0x04 = 0x40010804这个地址
60user182
4楼-- · 2019-07-15 11:13
可以先熟悉下汇编的思路,就是对地址寻址,然后操作位于这个地址的存储单元

一周热门 更多>