STM32寄存器映射

news2024/11/15 19:58:58

1. 寄存器基本原理

寄存器是单片机内部一种特殊的内存,可以实现对单片机各个功能的控制,我们编写程序最终就是去控制寄存器
下面的举例平台为STM32F407ZG

1.1 STM32寄存器分类

大类小类说明
内核寄存器 内核相关寄存器 包含R0~R15、xPSR、特殊功能寄存器等
中断控制寄存器 包含NVIC和SCB相关寄存器,NVIC有:ISER、ICER、ISPR、IP等;SCB有:VTOR、AIRCR、SCR等
SysTick寄存器 包含CTRL、LOAD、VAL和CALIB四个寄存器
内存保护寄存器 可选功能,STM32F103没有
调试系统寄存器 ETM、ITM、DWT、IPIU等相关寄存器
外设寄存器 包含GPIO、UART、IIC、SPI、TIM、DMA、ADC、DAC、RTC、I/WWDG、PWR、CAN、USB等各种外设寄存器

2. 寄存器映射

给寄存器地址命名的过程就叫寄存器映射

在 STM32F4 中 0x4002 000C 是 GPIOA_PUPDR 的地址,但是我们直接看 0x4002 000C 并不知道他是谁的地址,虽然我们可以通过查找手册的方式找到,但是这样的方式实在的过于繁琐而且不利于我们后续开发程序,所以我们需要对寄存器地址命名,以便于我们看到新的名字就知道他的作用是什么

2.1 地址映射基本概念

我们首先要知道下面的概念:

  • 总线基地址(BUS_ BASE_ ADDR)
  • 外设基于总线基地址的偏移量(PERIPH_OFFSET)
  • 寄存器相对外设基地址的偏移量(REG_OFFSET)
  • 寄存器地址= BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET

而上面的地址可以很轻易的在手册中找到,下面以寻找 STM32F4 中 GPIOA_PUPDR 的地址为例

2.2 如何通过手册查找寄存器地址

首先我们要明确要寻找的地址是什么东西(总线?外设?寄存器?)。GPIOA_PUPDRGPIOA_PUPDR 的一个寄存器,所以我们在这里要寻找的是一个寄存器,而寄存器是基于外设偏移的,而外设是基于总线偏移的,所以我们需要先找到 GPIOA 是挂载到哪一个总线的哪一个外设上的。
打开《STM32F4xx参考手册》,此手册可以在正点原子资料中免费获取,也可以去 ST 官方下载英文版或者中文社区寻找中文版资料,
2.3 存储器映射中的表2.STM32F4xx寄存器边界地址,找到外设为 GPIOA 的地方,如下图所示:

①:即是我们要寻找的外设
②:可以通过表格看到 GPIOA 是挂载在 AHB1
③:GPIOA 的地址刚好是 AHB1 最低的地址,也就是说相对于 AHB1 的起始地址没有偏移,也即 BUS_ BASE_ ADDR = 0x4002 0000,PERIPH_OFFSET=0
④:点击这个超链接我们可以看到 GPIOA 其他寄存器的详细情况

在这里插入图片描述
点击④会跳转到 7.4.11 GPIO 寄存器映射,在表32.GPIO 寄存器映射和复位值中,寻找 GPIOA_PUPDR 如下图所示:

①:即是我们要寻找的寄存器
②:相对于 GPIOA 基地址的偏移量,也即是 REG_OFFSET=0x0C
③:可以看到这是 32 位的寄存器,也就是每一个寄存器的大小是 4B(后续会用到)
④:注意到 GPIOB_PUPDRGPIOA_PUPDR 甚至 GPIOx_PUPDR(x为A…I)都是同一个偏移量,这就为我们使用一个结构体来初始化所有的GPIOx提供了可能(往后继续看)
在这里插入图片描述
到这里我们已经得到了所有的地址了

BUS_ BASE_ ADDRPERIPH_OFFSETREG_OFFSET
0x4002 00000x000x0C

把他们拼接起来就得到了 GPIOA_PUPDR = 0x4002 000C
那么我们如何对这个地址的正确性进行验证呢?
理论上可以使用 keil5 的 debug 功能来调试查看寄存器的地址,但是我试过好像有点问题,所以换一种方式来验证。使用正点原子的串口例程,我们使用串口把地址发送到电脑上进行查看,我编写了如下的程序

int main(void)
{
    uint8_t len;
    uint16_t times = 0;
    
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(336, 8, 2, 7);     /* 设置时钟,168Mhz */
    delay_init(168);                        /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    while(1)
    {
        printf("%p\r\n",&GPIOA->PUPDR);
        delay_ms(1000);
    }
}

收到的结果为
在这里插入图片描述
与我们计算的结果一致,说明我们的计算方式是正确的,下面将会从代码层面寻找他是如何拼接地址的

2.3 寄存器命名的方式

2.3.1 直接操作寄存器

由于 GPIOA_PUPDR 是 32 位的,所以我们需要使用 int 类型的指针来拿他的地址,使用(unsigned int *)把地址强转为指针类型,然后使用 * 访问地址所指向的值,来对寄存器进行赋值(需要注意寄存器是否可读、可写等)

*(unsigned int *)(0x4002 000C)=0XFFFF;

2.3.2 命名后再操作寄存器

使用宏定义对地址进行了一次命名,相较于第一种方式可读性更好

#define GPIOA_PUPDR *(unsigned int *)(0x4002 000C)
GPIOA_PUPDR = 0XFFFF;

2.3.3 使用结构体命名寄存器

下面是 stm32f407xx.h 里面的内容,他使用了结构体的方式来完成寄存器的映射,下面将会讲解为什么可以通过结构体进行映射

typedef struct
{
  __IO uint32_t MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  __IO uint32_t OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  __IO uint32_t OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  __IO uint32_t PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
  __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,      Address offset: 0x18      */
  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
} GPIO_TypeDef;

通过 c 语言的基础知识我们知道,结构体变量的名字实际代表的是结构体的首地址,而结构体内部成员是顺序排列的,在上面的手册中可以看到 GPIOA 的寄存器(除了 AFR)都是 32 位寄存器,意味着我们可以在结构体中依次按照寄存器的名字进行成员的定义。例如 GPIOA_PUPDR ,我们在手册中看到基于 GPIOA 的偏移量为 0x0C ,根据上面代码的定义 __IO uint32_t PUPDR; 位于第 4 行,前面有 3 行其他成员的定义,一共占用空间为 32bit x 3 =12B,正好对应了在手册中的偏移量,同时我们也可以在代码的注释中看到地址偏移为0x0C。上一节提到了 GPIOx_PUPDR(x为A…I)都是同一个偏移量,所以当 GPIO_TypeDef 的基地址不同的时候,便可以定义不同组的 IO 口了,这便是使用结构体的好处。

接下来通过源码的方式来寻找 GPIOx_PUPDR 的地址。
打开 stm32f407xx.h ,搜索 GPIOA ,可以看到下图的宏定义,这里的宏定义和上一小节讲的是一样的,但是他还套娃了很多层,
在这里插入图片描述
我们双击 GPIOA_BASE ,按照下图方式操作
在这里插入图片描述
可以得到这个
在这里插入图片描述
我们继续重复上面的步骤
在这里插入图片描述
继续重复
在这里插入图片描述
直到这里我们知道了他的地址结构为

PERIPH_BASEAHB1PERIPH_BASEGPIOA_BASE
0x40000000ULPERIPH_BASE + 0x00020000ULAHB1PERIPH_BASE + 0x0000UL

计算得到 GPIOA_BASE = 0x4002 0000,这个地址通过 #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) 就转化为了 GPIOA 结构体的基地址了,然后我们再加上 GPIOx_PUPDR 相对于 GPIOA 偏移量就得到了 GPIOx_PUPDR = 0x4002 000C
至此寄存器映射就结束了,可以通过类似的方式查找到所有的寄存器地址,多看手册和程序源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/564339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《幸福关系的7段旅程》

关于作者 本书作者安德鲁∙马歇尔&#xff0c;英国顶尖婚姻咨询机构RELATE的资深专家&#xff0c;拥有 30年丰富的咨询经验&#xff0c;并为《泰晤士报》《观察家》和《星期日快报》撰写专栏文章。已出版19部作品&#xff0c;并被翻译成20种语言。 关于本书 《幸福关系的7段…

SQL查询比较慢,如何进行排查?如何进行SQL优化?

目录 一、开启慢查询日志 二、SQL优化 三、总结 一、开启慢查询日志 SQL慢查询是指执行时间较长的SQL语句&#xff0c;可能导致系统性能下降和响应时间延长。通过以下步骤可以开启慢查询日志记录&#xff1a; #查询是否开启慢查询日志 slow_query_log显示ON说明已开启&#…

广和通携手有人物联网完成5G SUL辅助上行功能验证

近日&#xff0c;广和通5G模组FM650-CN已在商用网络中实现5G SUL上行能力增强&#xff0c;助力有人物联网工业路由器在仿真网络环境中完成SUL辅助上行功能的验证。本次验证成功&#xff0c;意味着FM650-CN已具备SUL辅助上行商用能力&#xff0c;有利于推动更多5G终端支持SUL特性…

es 7 Es分布式基础

目录 复杂特性es已经做了分片副本负载均衡实现 设置分片数副本数 双机器读写 自动横向扩容 Node 节点宕机主节点切换 数据路由 增删改操作 读操作 _bulk 复杂特性es已经做了分片副本负载均衡实现 1.每个索引包含多个分片 设置分片数副本数 双机器读写 自动横向扩容 No…

React | React的CSS方式

✨ 个人主页&#xff1a;CoderHing &#x1f5a5;️ React.js专栏&#xff1a;React的CSS方式 &#x1f64b;‍♂️ 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; &#x1f4ab; 系列专栏&#xff1a;吊打面试官系列 16天学会Vue 11天学会React Node专栏 &#x…

Axure教程—多色折线图(中继器)

本文将教大家如何用AXURE中的中继器制作多色折线图 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://xpdm3g.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87814320 二、功能介绍 简单填写中继器内容即可动态显示值样…

AppJoint2-2023再看安卓组件化框架

零、什么是组件化 为了避免一些小伙伴一脸懵的进来&#xff0c;又一脸懵的出去&#xff0c;我先简单的说一下什么是组件化。 开发程序时&#xff0c;我们都希望功能间的耦合度尽可能的低&#xff0c;这样的好处是&#xff1a;便于并行开发、代码易于维护、出问题时也好定位。…

抖音seo矩阵系统源码开发开源型私有化部署方案

抖音SEO矩阵系统是基于抖音平台的搜索引擎优化技术的一种系统&#xff0c;其主要作用是通过一系列的技术手段&#xff0c;提高抖音视频的曝光和排名&#xff0c;使其获得更多的流量和粉丝。在本文中&#xff0c;我们将介绍抖音SEO矩阵系统的开发技术&#xff0c;包括系统设计、…

map reduce实现累加器

需求&#xff1a;数组长度为100&#xff0c;每一项为对应下标&#xff0c;累加求和。 切题思路&#xff1a; 1.如何声明一个长度为100的数组&#xff1f;答&#xff1a;new Array(100) 2.数组每一项如何比前一项1 答&#xff1a;map(item,index)index为数组下标&#xff0c;…

企业推行OKR的必要条件

今天我们的话题是“OKR在企业落地执行,有哪些必要条件&#xff1f;” 对于有落地 OKR 经验的人可能更深有感触&#xff0c;OKR理解起来容易&#xff0c;但落地起来却困难重重&#xff0c;常言道“万事开头难”&#xff0c;那接下来我们就先从落地 OKR 的先决条件开始说起吧。 …

我的创作纪念日,成为创作者的第512天

机缘 从事编程岗一有将近4年的时光了&#xff0c;但正在开始总结写博客还是一年前&#xff0c;是在百度搜素资料了解到的CSDN开发者社区。在CSDN认识了很多技术大牛&#xff0c;他们的文章记录了他们的学习路径&#xff0c;看到他们从小白一步一步成长为大牛&#xff0c;这才下…

大数运算(加法,减法,乘法,除法)

目录 一.大数加法 1.题目描述 2.问题分析 3.代码实现 二.大数减法 1.题目描述 2.问题分析 3.代码实现 三.大数乘法 1.题目描述 2.问题分析 3.代码实现 四.大数除法 1.题目描述 2.问题分析 3.代码实现 一.大数加法 1.题目描述 以字符串的形式读入两个数字&#…

Smartbi电子表格故事之高效营销活动后的自助数据分析

自助数据分析是BI的潮流&#xff0c;但几乎都是数据可视化流派&#xff0c;Smartbi电子表格另辟蹊径&#xff0c;在Excel中提供自助分析的能力&#xff0c;然后通过服务器进行发布&#xff0c;这个功能我们称之为“Excel融合分析”&#xff0c;目前在免费版中即可体验。 系统数…

Python脚本如何定时运行

一、背景 很多时候&#xff0c;我们使用Python编写好的各种脚本&#xff0c;会有定时运行的需求&#xff0c;希望脚本能每天在指定的时间点定时运行&#xff0c;比如&#xff1a;定时发送消息、定时发送邮件、定时执行自动化测试脚本等。 定时运行脚本常用的有2种方式&#x…

LeetCode:30. 串联所有单词的子串

30. 串联所有单词的子串 1&#xff09;题目2&#xff09;思路3&#xff09;代码4&#xff09;结果 1&#xff09;题目 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子…

CentOS 7安装redis

一、概述 1、redis介绍 Redis 全称 Remote Dictionary Server&#xff08;即远程字典服务&#xff09;&#xff0c;它是一个基于内存实现的键值型非关系&#xff08;NoSQL&#xff09;数据库 2、redis的特点 支持数据持久化 redis支持数据的持久化&#xff0c;可以将内存中的…

IDEA 2022.2 安装以及自定义优化

IDEA2022.2 安装以及自定义优化 文章目录 IDEA2022.2 安装以及自定义优化安装图解获取激活码自定义优化文件编码设置设置类文档注释和方式注释模板方法分割线 常用插件离线安装 安装图解 静默卸载&#xff08;旧版本的设置和配置将不会被删除&#xff09; 获取激活码 略…

芯片设计_IC行业到底还值不值得入?

前几天哲库的关停让不少想入行IC的人人心惶惶&#xff0c;这也让不少人引起思考&#xff0c;IC行业的未来发展如何?还值不值得入行?给大家分析一下原因&#xff0c;大家就可自行判断到底可不可入?还能火多久? 一、分析芯片行业市场情况 芯片是典型的周期成长行业&#xf…

flowable的流程任务统计sql(续)

继续之前的文章&#xff0c;我们这里还需要进行按月统计&#xff0c;同时为了适应jeecg的图形显示&#xff0c;所以做了一些调整如下&#xff1a; 1、按月统计任务数量 select DATE_FORMAT(c.days, %Y%m) months, count(num) num from (SELECT DATE_FORMAT(START_TIME_, %Y-%m…

u盘无法复制过大文件怎么解决?揭秘!

大家在使用U盘的时候&#xff0c;有没有发现有的文件不能够复制到U盘&#xff0c;这是怎么回事呢?其实是文件太大了&#xff0c;那么u盘无法复制过大文件怎么解决&#xff1f;本文给大家推荐了3个靠谱好用的方法&#xff0c;一起来学习一下! 一、案例分享 “求救!求救!买了一…