STM32寄存器控制引脚高低电平

一. 引子

最近在学习32代码的过程当中,虽然在学习IMX6ULL开发板的过程中接触过很多寄存器,最近在返回去看32的时候,在研究代码的时候发现自己对于寄存器的有些特性理解的不够深刻,所以下来的时候去查了资料,以及问了一下自己的学霸朋友楚灵魈,然后对有些寄存器还是有了一些新的认识

二. STM32F10xx部分寄存器

1. 端口输出数据寄存器(GPIOx_ODR)(x=A..E)

首先是GPIOx_ODR,官方解释是端口输出数据寄存器,从图示可以看出,bit[31:16]是保留位实际有效位只有bit[15:0],还有一个的点,就是图示下面有一个rw,表示这是一个读写寄存器,这里先解释具体作用,后面在介绍了其他寄存器再描述

然后就是官方文档中的bit[15:0]的作用我们应该如何去理解。其中0-15位都对应GPIO端口的一个引脚,例如我们使用的是GPIOA_ODR0,那么对应的GPIO端口就是PA0,以此类推GPIOB_ODR1,GPIO端口就是PB1

下一段的信息是,端口输出数据,也就是ODR寄存器中的每一位值,决定了相应引脚的输出电平。如果某一位为1,则输出为高电平,如果某一位为0,则输出为低电平。

如果我把GPIOA_ODR0设置为1,那么这个引脚就是高电平,反之如果设置为0就是低电平

关于(y=0......15)对应的就是端口号,也就是0到15这个没什么好说的

"这些位可读可写并只能以字(16位)的形式操作"首先这里再次强调这是一个16位的寄存器,在这段话中它也提到了是可读可写的

只能以字(16位)的形式操作,意味着只能一次性读取或者写入整个16位的ODR寄存器,不能单独的读取或者写入ODR寄存器的某一位

GPIOx_BSRR(x = A..E),可以分别对各个ODR位进行独立的设置/清除。x也就是可以对应选择GPIOA或则和GPIOB

分别对各个ODE进行独立的设置/清除,这个点留到之后讲解因为会和其他的寄存器产生关联

总而言之,ODR寄存器是一个16位的寄存器,可以用于控制GPIO端口的输出电平,设置为1为高点平,设置为0为低电平,目前主要的作用就是这样

2. 端口位设置/清除寄存器(GPIOx_BSRR)(x=A..E)

此寄存器是端口位设置/清除寄存器,如下图[31:0]都是有效位,但是所有的位下面都是w,表示这是一个只写寄存器,没有被读取功能

简单来讲BSRR一个32位的寄存器,用于控制GPIO端口的输出,分别分为bit[31:16]和bit[15:0],按照简单理解就是,这个寄存器既可以控制端口输出高电平,也可以控制端口输出低电平

这里讲解到BSRR的时候就要引出到之前没有了解到的一个概念,向BSRR寄存器写入值(例如0x003)后,硬件会立即更具掩码更新ODR寄存器,意思就是BSRR会将参数直接传输给ODR寄存器。

也就是说为什么BSRR是只写寄存器,因为它本身不存储任何值,写入操作完成后BSSR内部的值会恢复为0(即使尝试读取此寄存器也会得到未定义的值或者0),下面我们具体讲解

位31:16(BRy),这些位只能写入并只能以字(16位)的形式操作,这些16位是用于清除ODR寄存器中相应位为0(低电平)

如果向BRy某一位写入0,ODR寄存器的相应位保持不变,如果向BRy的某一位写入1,则ODR寄存器的相应位被设置为0(低电平),但是如果同时向BSRR寄存器的低16位和高16位 ,则以低16位(BSy)的设置优先

而15:0(BSy),用于设置ODR寄存器中相应位为1(高电平),和上面的类似,如果向BSy的某一位写入0,则0DR寄存器的相应位保持不变,如果向BSy的某一位写入1,则ODR寄存器的相应位被设置为1

3. 端口位清除寄存器(GPIOx_BRR)(x=A...E)

这个寄存器的功能如上图,那么从如上信息就可以看出,这个端口位清除寄存器,用于设置某个端口为低电平

但是本质上还是在操作ODR寄存器,因为此寄存器也只有写入的功能,没有读取的功能,在写入值后还是把数据传输给ODR寄存器

但是这个寄存器在之后很多的芯片中都被优化掉了,所以如果要对某个位进行单独的设置,所以还是可以使用BSRR

三. 实验验证

借助博主最近正在学习的一段代码,首先接上Stlink后,给板子通电进入,然后点击上面的Start/Stop Debug Session,进入调试模式

那么我们如何查阅寄存器的值,进入调试模式后,点击左上角的View

然后进入System_Viewer,然后点击自己想要查考的寄存器,比如这里博主想要查找GPIOB_ODR寄存器,那么就在这里选择GPIOB

点击后如下图,右栏可出现,和GPIOx相关的寄存器,其中就包含上面我们讲解过的ODR、BSRR、以及BRR寄存器

和我们上面讲解的一致,BSRR和BRR等特殊的寄存器,并不具备被读的功能,所以它们的值都是0的状态

如上图我们可以看到ODR寄存器的值是0X00000010,按道理来说刚开始我们并没有设置任何引脚的电平为高,寄存器这里为什么会显示值

有些引脚可能是特殊位,所以刚开始的时候可能就被设置了值,例如这里的GPIOB_ ODR寄存器,就可以看出是PB4引脚被设置为了高电平,我们可以去看一下原理图

是引脚PB4,JNTRST引脚,JNTRST引脚在默认状态下是高电平,所以在上面我们看到的ODR寄存器中ODR的值并不是全部为0

所以在程序开始的时候,寄存器的值并不一定全部都是0,因为有些特殊的引脚比如上面JNTRST,以及SWDIO、SWCLK等引脚,也是全部置为1的,因为必须保持为高电平

那么就根据博主的代码开始调试,刚开始的时候GPIOB->ODR寄存器的值是0X00000010,

在进行到如上这一步的时候,我们发现ODR寄存器的值产生了改变,变成了0x00000013,那么看一下,代码fLED_L中发生了什么

这里进行了一个宏定义,然后操作了GPIO_Pin_0和GPIO_Pin_1,进行了位运算,那么我们要计算出结果,还是要去看GPIO_Pin_0和GPIO_Pin_1的参数

代码执行的是fLED_L,那么我们计算一下0001和0011相或,得到的结果就是0x11,转换为十六进制就是3,因为结果是0X11但是前面讲解过,BSRR的值被写入后,会将数据直接传递给ODR寄存器,因为是低16位,所以是将引脚设置为1,所以ODR的0位和1位,也被设置为1,高电平

那么这个宏定义的作用就是,控制PB0和PB1的引脚为高电平

通过调试的方式我们读取到了寄存器的值,验证了我们的猜想,操作寄存器的值确实会让人觉得设计的非常的巧妙

所以以上博客是博主在学习寄存器的过程中,学习到的一些知识点。如果有阅读者看到我的博客能够将寄存器理解的更好,那也是这篇博客的价值所在了

相关推荐
三佛科技-134163842121 天前
便携式榨汁机方案开发,榨汁机果汁机MCU控制方案设计
单片机·嵌入式硬件·智能家居·pcb工艺
yongui478341 天前
基于TMS320F28027实现光伏MPPT控制
单片机·嵌入式硬件
炸膛坦客1 天前
Cortex-M3 内核 MCU-STM32F1 开发之路:(一)单片机 MCU 的构成,包括 FLASH 和 SRAM 的区别,以及引脚类型
stm32·单片机·嵌入式硬件
A9better1 天前
嵌入式开发学习日志39——stm32之I2C总线物理层与常用术语
stm32·单片机·嵌入式硬件·学习
三佛科技-187366133971 天前
FT62FC3X 8位MCU单片机选型表,详细解析FT62FC31A/32A/33A/35A/3FA
单片机·嵌入式硬件
充哥单片机设计1 天前
【STM32项目开源】基于STM32的智能衣柜系统
stm32·单片机·嵌入式硬件
Try1harder1 天前
极海APM32F107V6 + 合宙Air780E
单片机·嵌入式硬件·物联网·合宙air780
文火冰糖的硅基工坊1 天前
[嵌入式系统-134]:智能体以及其嵌入式硬件架构
科技·嵌入式硬件·架构·嵌入式·gpu
电鱼智能的电小鱼1 天前
服装制造企业痛点解决方案:EFISH-SBC-RK3588 柔性化吊挂调度方案
网络·人工智能·嵌入式硬件·算法·制造
清风6666661 天前
基于单片机的便携式温湿度检测烘干机设计
单片机·嵌入式硬件·毕业设计·课程设计