GPIO相关的寄存器(重要)
目录
1、端口配置低寄存器(GPIOx_CRL)(x=A...E)
2、端口配置高寄存器(GPIOx_CRH)(x=A...E)
3、端口输入数据寄存器(GPIOx_IDR)(x=A...E)
4、端口输出数据寄存器(GPIOx_ODR)(x=A...E)
5、端口位复位/置位寄存器(GPIOx_BSRR)(x=A...E)
6、端口位复位寄存器(GPIOx_BSR)(x=A...E)
7、端口配置锁定寄存器(GPIOx_LCKR)(x=A...E)
前面,我们学习了GPIO的相关概念、特点和8种工作模式。在前面的点灯案例中,我们用到了GPIO相关的寄存器,但没有详细的去了解这些寄存器。因此,在这期我们就来学习一下GPIO相关的七个寄存器。
一、GPIO相关寄存器概述
每个GPIO端口相关的寄存器有7个:
- 2个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)。
- 2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)。
- 1个32位置位/复位寄存器(GPIOx_BSRR)。
- 1个16位复位寄存器(GPIOx_BRR)。
- 1个32位锁定寄存器(GPIOx_LCKR)。
关于GPIO寄存器的学习比较重要,但是实际上也不是全都很重要。相对而言,前四个寄存器会更加重要,因为我们平时使用的会更多;后面三个寄存器也不是就不学了,也需要做一下了解,可能会用到。
我们看这些寄存器,这么多名称我们咋记得住,实际上,这些名称都是有规律的。他们都是几个英文的首字母或缩写组合。
比如,这两个配置寄存器名字前部分GPIOx是都有的,表示这是对应是GPIO端口的;然后后半部分的CRL和CRH,代表的是配置 寄存器 低 / 高 的英文的缩写;也就是说,这两个寄存器一个是低位、一个是高位的端口配置寄存器的意思。
然后就是两个数据寄存器。关于数据,我们可能涉及到的主要就是输入输出了。IDR和ODR只有首字母的不同,I表示的就是input输入,O表示的自然就是output输出了,后面的DR就是data和register 数据寄存器的意思了。
接着是置位/复位寄存器,BSRR,看着很奇怪,看中文名其实就是我们前面将工作模式的时候的那个设置/清除寄存器一样的,用来把我们想要输入/输出的电平状态给数据寄存器的寄存器。这里的B表示的就是bit位,S表示set设置,R表示reset复位/清除,最后的R表示register寄存器,就是这个意思了。
再就是复位寄存器,BRR,我们看中文名叫复位,与上一个相差一个置位,然后上一个的置位用的set的首字母s,而现在复位寄存器没有置位,所以就是BSRR去掉一个S就是复位寄存器首字母组合BRR了,也就是这个意思。
最后是这个锁定寄存器,LCKR,LCK就是lock锁的缩写,然后R是register寄存器,LCKR组合,就是表示锁定寄存器了。因为对于工作模式的配置决定了这个gpio口实现的功能(输入/输出等),所以不能随便修改,因此有这个锁定寄存器的出现,即主要是用于锁定配置的工作模式位的寄存器。
介绍完这些寄存器名字以后,我们再去技术手册中看看这些寄存器,先整体的看看,再详细看看单个的。
二、整体介绍
我们进入技术手册,进入GPIO的寄存器地址映像,就能看见GPIO相关的7个寄存器的排列的信息了。
从图中可以看见,每一个寄存器的数据都是32位存储,只不过有些只使用了低16位,其余位保留位 。
从图中我们可以看出每个寄存器的大致信息,如偏移地址、寄存器名称、复位值以及位。
前两个配置寄存器前面我们主要用于配置GPIO的工作模式,这是32位都用上了;
接着的两个输入输出数据寄存器只使用低16位的部分,高16位保留,这是由于每一组GPIO端口恰好有16个引脚,对应寄存器16位,所以就这样设定了;
紧接着就是置位/复位寄存器,这里使用了32位,其中可以看出低16为用于处理置位引脚,高16位用于处理复位引脚。
然后复位寄存器同理,只使用了低16位,用于处理复位的引脚。
最后是锁定寄存器,同样也是低16位用于16个引脚对应的锁定位,然后还有多的一位可能用处更全局,然后高15位被保留。
三、详细介绍
然后我们进入单个寄存器描述部分去详细说明每个寄存器:
1、端口配置低寄存器(GPIOx_CRL)(x=A...E)
首先是CRL,即GPIO端口配置低寄存器。
首先我们关注到的是这个名字,GPIOx,这里有个x,后面跟着(x=A...E),为什么这样写呢 ?
因为我们STM32芯片上GPIO端口有7组,A到E,每组都是16个引脚。实际上,每一组引脚要做的配置、数据的输入输出以及置位复位锁定等等功能都需要,而且都是类似的,所以这里除了GPIO组的不同,实际上寄存器的实现都是类似的。因此,这里用x就是表示每一组GPIO端口都是使用这个寄存器。
其次,我们说说为什么这里每四位一循环MODE和CNF,只是最后的数字不同,然后每个MODE和CNF各包含两位,为什么会这样设计?
这里寄存器叫做配置寄存器,也就是之前用来配置GPIO工作模式的,而GPIO工作模式前面讲了,一共有8种。那么我们想,既然八种,那恰好使用3位就可以产生8种状态嘛,而每一个端口(引脚)都可能出现这8种情况,一组GPIO端口又含16个引脚,也就是需要16x3=48位,这时候问题来了,我们寄存器都是32位的,这48位总有点不太合适。
因此咱就利用了两个寄存器,一共64位,64/16=4,也就是每一个引脚使用4位来配置工作模式。这个时候由于一个寄存器只有32位,也就是说一个寄存器就只能配置32/4=8个引脚,于是出现两个配置寄存器:配置低寄存器(低8位端口)和配置高寄存器(高8位端口)。
再来说说这4位是如何分配的:
MODE:我们继续对4位半分,低2位使用MODE表示,即模式,用于配置引脚是输入还是输出模式。但是两位可以表示四种状态,此时只有两种模式,因此MODE表示的两位是控制三种不同翻转速度的输出模式和一种输入模式。
即输入模式、最大速度为10MHz的输出模式、最大速度为2MHz的输出模式、最大速度为50MHz的输出模式。这样这两位就充分利用了。若没有被利用,就变成保留位了。
CNF:高2位则使用的CNF表示,即对应8种工作模式。它是根据MODE的情况而表示四种不同的模式。
当MODE为00时,CNF下的四种状态则代表所有情况的输入模式,即模拟输入、浮空输入、上拉/下拉输入这四种。由于上拉和下拉输入模式除了开关一个向上、一个向下外,其控制的电路基本类似,因此只要设置一个默认的开关上下拉情况,就可以只通过一个对应值来同时控制是上拉还是下拉了。因此实际上当MODE处于00输入模式时,CNF的两位只利用了产生的3个值(00、01、10),还存在一个保留位。
当MODE>00时,CNF下的四种状态则代表所有情况的输出模式,即通用推挽输出模式、通用开漏输出模式、复用功能推挽输出模式、复用功能开漏输出模式这四种。
然后我们说说这个复位,这里也有个复位值,“0x4444 4444”,这里的4换成二进制就是0100,恰好对应一个引脚的4个控制位。我们看下图,0100也就是表示 MODE是00输入模式,此时CNF是01表示的浮空输入,浮空表示内部不产生电流,全靠外部向内产生,因此此时是最不耗电的时候。
由图中也可以发现,浮空输入模式就是复位后的状态,将不耗电的模式作为复位状态确实是一个较好的选择。
2、端口配置高寄存器(GPIOx_CRH)(x=A...E)
因为端口配置高寄存器GPIOx_CRH与GPIOx_CRL寄存器结构内容几乎一样,完全可以类比理解。因此这里我不再赘述。
3、端口输入数据寄存器(GPIOx_IDR)(x=A...E)
关于输入数据寄存器相对前面配置的就简单多了,即给GPIO端口一个高/低电平状态的寄存器。怎么使用呢?很简单,比如我给IDR0位为1,则P0端口就会输入一个高电平状态;若给IDR0位置0,则P0口就会输入一个低电平的状态。
由于一个寄存器控制一组GPIO端口(16个位),因此只需要使用低16位。故对于输入输出数据寄存器来说,低16位用于给电平状态,高16位作保留位。
4、端口输出数据寄存器(GPIOx_ODR)(x=A...E)
关于端口输出数据寄存器的介绍,该寄存器作用即用于向端口输出一个高低电平状态的寄存器。与上面的输入数据寄存器使用极其类似,如不清楚可看上面关于端口输入数据寄存器的介绍。
5、端口位复位/置位寄存器(GPIOx_BSRR)(x=A...E)
接下来,我们来介绍一下端口位设置/清除寄存器的功能与使用,上图是STM32F10x中文参考手册中截的关于该寄存器介绍的图片以便查看。该寄存器的功能顾名思义,即对端口位进行设置或复位(清除)的寄存器。
通过上图我们注意到,低16位是BRxx,即用来对16个端口位进行设置位,其中置1即可进行设置;高16位是BRxx,即用来对16个端口进行清除(复位)的位,其中置1即可进行复位(清除);此时我们就会注意到一个问题:如果我们同时给同一个端口位进行清除位和设置位,此时该端口会是什么状态呢?诶,由上图绿框中可以看见一个注意,“如果同时设置了设置位和复位的位,则设置位会起作用”,即 同时设置时会对该端口设置位。
这里可能还会有一个问题:为什么还要专门弄一个寄存器出来对GPIO端口进行复位或设置位?明明可以直接使用数据寄存器进行设置的
实际上,这和个人的变成习惯相关的,我们确实完全可以不使用这个寄存器以及下一个介绍的寄存器去进行设置或复位。至于原因,就是我们观察这个寄存器会发现,如果单独去开一个寄存器去对某端口进行设置或复位的话,我们只要设置高电平1即可,如果我们直接使用数据寄存器去复位或设置的话,可能是0可能是1,此时由于我们对某一位给0/1时为保证不影响其他位的数据,还会进行按位与/按位或的操作或者取反的操作,如下图我们之前点灯实验的代码操作一样
在同一个寄存器中进行,就会出现按位与按位或交叉的使用情况,这时候我们就容易混乱,稍不注意就容易出现编写错误,相反,我们另用一个寄存器,就能保证代码整齐,都是用按位或(置1)去进行设置/清除的操作,这样可能不容易出问题一些。主要就是这个原因,希望这里我讲清楚了,没讲清楚可在评论区评论~
6、端口位复位寄存器(GPIOx_BSR)(x=A...E)
接下来是端口位复位(清除)寄存器,看到这里大家又会有疑问了,前面刚讲到一个设置/清除寄存器,这里又来个单独的清除寄存器,这不是重复了吗?原因其实和前面那个问题一样,我们完全也可以不使用这个寄存器,根据个人编程习惯来。
关于该寄存器的内容和使用,和上一个端口位设置/清除寄存器使用是一样的,主要区别就是这里复位使用的是低16位对端口位进行操作,与前面设置/清除寄存器进行清除的操作位不同,但这里恰好与前面寄存器设置端口有了对应。然后我就不再赘述了。
7、端口配置锁定寄存器(GPIOx_LCKR)(x=A...E)
最后,在讲解一下这个端口配置锁定寄存器,顾名思义,即用来锁定端口配置的寄存器,既然有锁定配置的操作,可想而知关于端口的配置有多么重要,每一个端口的锁将控制配置寄存器的四位。这里我们可以理解成每一个端口位都有一个小箱子,箱子里面装有四位,然后各个小箱子都有一把钥匙,而这个钥匙呢就是这里配置所寄存器的低16位的各个位,当我们给1时就会锁住相应的小箱子(端口位),给0就不会锁住;
同时我们也注意到,在高16位的第一位还有一个LCKK位,那么这个是用来干啥的呢?实际上,他叫锁键,可以看做是一个全局锁,即用来锁住锁端口位的“大锁”,可以这样理解,此时还有一个大箱子,这个大箱子装着所有小箱子(端口位)的锁,此时LCKK就相当于是大箱子的锁,可想而知锁住端口位的锁也是很重要的,那么同理这个大箱子(全局锁)的大锁岂不是更重要?以此类推难不成要像套娃一样去加锁了?
显然那样是不可取的,因此这个大锁是有点特殊的,通过上图描述我们可以知道,此时的LCKK相当于一把“密码锁”,它并不是只需要给个1就能将全部的锁给锁住不能使用,而是需要锁键(LCKK)一个写入序列,写1->写0->写1->读0->读1:先写入101,然后读一个0看是否激活锁,然后最后这个读1其实可写可不写了,不过我们可以用来作为一个标志来确认锁键是否被激活。
总而言之,就是这个端口配置所寄存器是用来锁住端口位的配置的,其中低16位是对各个端口进行“上锁”,给高电平1即为锁定;高16位的第一位是对全局进行“上锁”,且全局锁需要一个写入序列(可理解成密码锁的形式)才能真正上锁。
四、总结
以上就是关于七个GPIO寄存器的全部内容,总共讲述了7个GPIO寄存器的命名介绍、功能详解以及使用方法。
作为我今后复习笔记的同时,也希望每一次博客对大家能有所帮助,由于笔者也是小白,编写的过程中难免出现一些错误和不足,还请大家在评论区批评指正,谢谢!
原文地址:https://blog.csdn.net/2301_79475128/article/details/141502569
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!