你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

对底层代码的一点不理解

[复制链接]
fridaynightinsu 提问时间:2018-5-1 16:11 /
为什么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来设置寄存器的值呢?

收藏 评论5 发布时间:2018-5-1 16:11

举报

5个回答
黑皮男 回答时间:2018-5-1 18:55:36
比如GPIOA,就是一个指针,其地址就是GPIOA的寄存器映射的起始地址,从这个起始地址开始分别对应GPIOA的寄存器,就是GPIO_TypeDef中的内容,通过指针来访问这片内存,就可以操作GPIO的寄存器了

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

Dandjinh 回答时间:2018-5-1 21:00:25
在"stm32fxxxx.h"这个文件里会有这么一句
  1. #define GPIOA ((GPIO_TypeDef *)0x0000000)
复制代码

所以后面就可以用GPIOA访问寄存器了

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

STM1024 回答时间:2018-5-1 21:22:14
首先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字节,因此,你是可以通过结构体计算出每个变量的实际地址,这个就是你看手册时候,手册上的偏移量的作用。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

Cortexxx 回答时间:2018-5-1 21:29:58
这样做的主要作用是减少代码量,因为每组GPIO都有那几个寄存器,所以可以定义一个struct来减少代码。
例如GPIOA
首先会定义定义外设基地址->APB2时钟总线的base_addr->GPIOA_ADDRESS_BASE
+(加号后面的属于偏移量)
  1. #define PERIPH_BASE       ((uint32_t)0x40000000)
  2. #define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
  3. #define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
复制代码
  1. #define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
复制代码


如果GPIOA->CRL其实就是指向的是0x40000000+0x10000+0x0800+0x00= 0x40010800这个地址
如果是GPIOA->ODR就是指向0x40000000+0x10000+0x0800+0x04 = 0x40010804这个地址

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

springvirus 回答时间:2018-5-2 09:35:19
可以先熟悉下汇编的思路,就是对地址寻址,然后操作位于这个地址的存储单元

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版