初学 STM32 (从 51 过度到 STM32 ,初学 STM32 必须了解的知识)

最近小编也是在学习 STM32F1 系列,因为前一段时间学过 51 ,所以这几天总结了一下从 51 过度到 STM32 经验与心得,现在与大家分享分享我的心得。

对于引脚的操作和 STM32 与 51 的不同

在 51 中,我们如果想要操作 P0^0 这个引脚,应该有一下几种操作吧。

//这个是小编最开始学的操作IO口。
P0 = 0x01;		//直接操作整个P0口,使P00口为高电平,其他为低电平。
P0^0 = 1;		//单独操作一个51单片机IO口。
//后来学会了只影响一个IO口,而其他IO口不受影响。
P0 |= 0x01;		//这样做可以保证在不影响P0的其他IO的情况下只改变P00口。
//在51单片机中还有一种独有的(这个我查阅了其他资料,并没有发现sbit是51单片机独有,但是我所学过的里面只有51能用sbit,就暂时说是51单片机独有吧,希望大佬指正。)引脚定义。
sbit IO = P0^0;	//将P00口单独定义出来,这样就只会操作到一个IO口了。

以上就是我目前用到过的对于 51 单片机的 IO 口的操作。
不过我一直在思考为什么这样做?为什么 P0^0 这个符号就可以代表的 P0^0 这个引脚,是不是 STM32 也一样?
直到我学习了 STM32 ,我对于它的操作原理有了新的定义。

对于每一个 IO 口其实是有一个地址,要操作这个 IO 口其实是对这个地址的操作,下面我放一段 <STC12C5A60S2.H> 的代码进行讲解。

//由于原程序里面代码太长,我这儿截取几段来集中讲解。
//这儿我截取了51单片机里对P0和P1的定义
sfr P0   = 0x80;	//首先我们要知道sfr的意义。
//sfr的定义有点长,在这儿的作用我就长话短说,它是将0x80定义为P0.
//这儿就可以发现,曾经我以为的P0就是IO口的引脚其实也是认为定义的,IO口真正的地址其实是0x80,这个也是接下来说STM32要用到的原理。
sbit P00 = P0^0;	//对于sbit就不生疏了吧,这儿为什么要这样定义呢?
//因为我们在上面已经知道了P0的地址,0x80,这个是属于P0口的基地址,什么是基地址?简单来说,就是第一个地址。
//因此我们可以由此推断,P00就是P0的基地址在位移0位,也就是0x80,而P01就是P0位移1位,也就是0X81,所以后面的代码也就由此退出了。
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4;
sbit P05 = P0^5;
sbit P06 = P0^6;
sbit P07 = P0^7;
sfr P0M0 = 0x94;
sfr P0M1 = 0x93;
//下面与上面意义一样
sfr P1   = 0x90;
sbit P10 = P1^0;
sbit P11 = P1^1;
sbit P12 = P1^2;
sbit P13 = P1^3;
sbit P14 = P1^4;
sbit P15 = P1^5;
sbit P16 = P1^6;
sbit P17 = P1^7;
sfr P1M0 = 0x92;
sfr P1M1 = 0x91;
sfr P1ASF = 0x9D;

对于 51 单片机的 IO 口定义也就分析完了,现在我们开始进入正题,由于上面的知识,对于 STM32 我觉得应该会相当好理解了。

首先,我们要明白, STM32 中可没有 sfr 或者 sbit 或者 bit 这种方便的定义,所以我们只有操作地址来操作 IO 口。

在具体分析之前,有个概念必须了解一下,就是储存器,储存器映射,寄存器和寄存器映射。

储存器

储存器应该很好理解,就是每一个外设(外设就是我们上面说的 P0 , P1 等 IO 口在 STM32 中这些 IO 口被分为了不同的外设。)储存了一个地址,而对于储存器本身是不具有地址信息的,它的地址是由芯片厂商或用户分配,这个过程(给储存器分配地址的过程)就称为储存器映射

寄存器

我们已经了解到了储存器映射,那么什么是寄存器映射呢?寄存器到底是什么呢?
已经知道了储存器, 那我们可以找到每个内存单元
(每一个外设都是分配了内存单元的,用 51 单片机来讲,就可以这样理解,P00 这一个 IO 口就占用 1 bit 的内存单元)
的地址,然后通过 C 语言指针的操作方式来访问这些单元,但是,每次都通过寻址来访问,不仅不好记忆,还容易出错。所以这个时候我们可以根据每个每个单元 功能 的不同,以功能为名给这些内存单元取一个别名,这个别名就是我们常说的寄存器取名字这个过程就叫做寄存器映射(和储存器映射相仿。)。

看到这儿,想必对寄存器和储存器的概念已经很清晰了吧,接下来我们就可以深入了解 STM32 了!
在这里插入图片描述
在这里插入图片描述
上面是我所使用的 STM32F103 系列的寄存器的起始地址。
可能天马行空的这样看图不是很理解,接下来我就用代码与讲解的方式来讲解。

我就用图中的 GPIOB 这个寄存器来作为例子。(因为小编最开始接触 STM32 的时候就是学习的这个寄存器的使用。)
在图中可以看到 GPIOB 的起始地址是 0x40010c00;
所以我们就可以通过控制这个基地址来操作 GPIOB 了。但是,要怎么操作呢? 是像 51 单片机里面一样直接让这个地址等于 0 吗?显然不是!
从 STM32F103 的数据手册的目录,我们可以找到与 GPIO 有关的寄存器。
在这里插入图片描述
下面我们随便打开一个寄存器来分析。
在这里插入图片描述
有这个图片来分析,首先是偏移地址。什么是偏移地址? 因为对于 GPIO 口不只有 GPIOB ,还有 GPIOA 、 GPIOC 等等每个 GPIO 都有相对应的这种寄存器(图中是 BSRR )寄存器,所以,偏移地址就是 各自 GPIO 口的基地址所偏移后的地址。

//理论如果不好理解,可以参考代码,综合理解。
//由上可知GPIOB的基地址是0x40010c00,所以我们可以使用宏定义。
#define GPIOB_BASE			((unsigned int)0x40010c00)
//有了GPIOB的基地址的用定义,我们就可以在这个的基础上定义BSRR寄存器了(重点:使用指针!!!!!!)。
#define GPIOB_BSRR			*(unsigned int*)(GPIOB_BASE + 0x10)
//现在,我们就把GPIOB的BSRR寄存器的地址定义好了。

接下来我们先分析 BSRR 的作用。
由图我们可以看到, BSRR 一共有 32 位,低 16 位的作用是控制 GPIOB 的 16 个输出端口输出 1(高电平);

//就像是51单片机里面的。
P0 = 0x01;

而高 16 位是控制 GPIOB 的 16 个端口清除(就是输出 0(低电平) 。)。
所以,我们可以这样控制 STM32 的 GPIOB 的 1 到 16 口的输出。

//由于在这之上我们使用了宏定义,所以可以直接使用所定义的宏。
GPIOB_BSRR |= (1 << x);						//从这儿就可看出,将GPIOB的GPIOB_x这个引脚设置为高电平了。
//具体想要输出/清除哪个引脚,只需要改变x的值就行,若x=0,就是使GPIOB的Pin0口输出高电平。
//当然,也可以直接用地址(不过比较麻烦。)。
*(unsigned int *)0x40010c10 |= (1 << x);	//作用与上面相同。

这就完了?

当然不是!
再来看一下这张图:在这里插入图片描述
上面有些 AHP ,APB2,是什么呢?
我们就要结合这张图了。
在这里插入图片描述
这儿可以看到 GPIO 、 ADC (这些称之为外设)等等外设是挂载到 APB1、 APB2、AHB上面的,在 STM32 中,要使用这些外设,我们就必须将这些总线的时钟打开(因为默认是关闭,所以需要手动打开。)。
这儿的操作与上面操作 GPIOB 操作一样,找到时钟( RCC )的基地址,再找到寄存器地址,通过操作寄存器的方法来是使APB2 (因为我们操作的是 GPIOB ,而 GPIOB 是挂载在 APB2 上面的)的 RCC 打开。
然后我们的 GPIOB就可以正常使用了。

#define RCC_BASE			0x40021000							//RCC的基地址。
#define RCC_APB2END			*(unsigned int*)(RCC_BASE + 0x18)	//RCC的使能寄存器地址。
RCC_APB2END |= (1 << 3)											//由数据手册来看第三位是使能GPIOB的时钟。

好了,今天的分享就说完了,不过,这儿,只是从原理分析了 STM32 的 IO 的操作,对于固件库还有 HAL 库的讲解以后会分享,使用库可以更加容易的理解和使用 STM32 !

谢谢大家的耐心观看,代码之路任重道远,愿与大家努力习之!

版权声明:本文为CSDN博主「YVinci•」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_53624282/article/details/114070889

生成海报
点赞 0

YVinci•

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于8051单片机实现电子时钟+数字秒表设计

概述 电子时钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。随着人们生活环境的不断改善和美化,在许

基于STM32的指纹密码锁

设计简介: 本设计是基于单片机的指纹密码锁,主要实现以下功能: 矩阵按键输入密码,并通过按键显示*号可通过按键或手机开门密码可通过按键进行开门可通过蓝牙模块连接手机进行开门可通过指纹进