野火STM32学习笔记
Posted 飞天大司马
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了野火STM32学习笔记相关的知识,希望对你有一定的参考价值。
开始进入固件库编程
- 学习原因即优缺点
固件库的出现让STM32的开发难度大大下降,它通过库文件的封装,把众多的内存元整合为一个整体,在我们想要操作某一位寄存器时只要调用它所在的固件库就可以。缺点是不同型号的单片机的固件库有所区别,可移植性差。
构建库函数的模型
- 介绍
学习固件库之前,为了更了解底层的一些东西,我们来先尝试写一下固件库,来体验固件库是怎么形成的。
寄存器地址在控制单片机的C语言中是一个32位的指针,可以看作是四个字节的内存。而且其分布也是有规律的,我们看上一节课中GPIOB寄存器的地址,从基地址(CRL)的最后2位的00(16进制数),到第二个寄存器(CRH)04,第三个寄存器(IDR)是08,第四个寄存器(ODR)是0C······依次增加4个字节。
这时候,伟大的C语言又给我们提供了一个工具用来封装它们,这个工具就是结构体。可能有C语言不好的同学,不了解结构体,我简单打个比方:它像一个书柜的一列,从上到下有好几格,每一格从上到下按顺序编号,最上面是第一个,最下面是最后一个。学过8086汇编的朋友可能想到了什么:堆栈。没错,这和堆栈非常相似。那我们根据结构体和寄存器内存的特点自然的就把他们俩联系起来了。
结构体的封装方法
在STM32里面,寄存器的大小基本上都是32位的,有的寄存器只用了一半,低16位有效或者高16位有效。因此我们先定义可以在结构体内使用的,可以代表寄存器地址32位(4个字节)和16位数(2个字节)。
但是我们在看到固件库的封装时,发现结构体内的数据类型都是32位的没有16位,具体原因我也不知道在这里也不敢乱说。不过本着多了不影响,少了不可以的原则,这样做也没什么大问题,浪费一些内存资源罢了。现在我们来看看结构体封装的庐山真面目。如图
typedef struct是结构体关键字,变量名是GPIO_TypeDef,里面都是32位代表寄存器地址的16进制数。理论上,结构体内的数据是在内存中连续存储的,但是目前这些结构体内的数据还不是寄存器地址而是立即数,如何把他们变成地址呢?这里又用到指针强制类型转换,将这个结构体转换为指针类型,基地址是GPIOx_BASE,比如定义GPIOB内的寄存器要这样写:((GPIO_TypeDef﹡)GPIOB_BASE)。这样写呢过于冗长,我们又可以通过一个宏定义,把这个地址的格式简单化:
这样一个GPIO固件库形式的寄存器映射就封装完毕了。
我们也可以用同样的方式封装RCC寄存器,代码如图:
再用宏定义简化封装:
此时再回到之前的点灯代码当中,看看我们用固件库如何点亮一个LED灯。
可以看到好像并没有什么变化,其实它的奥妙在于编写时无需再查技术手册寻找寄存器的地址了。我们想要打开RCC寄存器中使能APB2中的时钟,只要输入RCC->
我们就可以打开RCC寄存器中任意的寄存器了。GPIO寄存器同理。
野火视频教程B站链接
https://www.bilibili.com/video/BV1yW411Y7Gw/?p=6&spm_id_from=333.880.my_history.page.click&vd_source=16419a44923b86308e680f95ec76193a
以上是关于野火STM32学习笔记的主要内容,如果未能解决你的问题,请参考以下文章