首页 >  资讯 >  详情

当前关注:野火STM32学习笔记

2023-06-14 22:57:25来源:哔哩哔哩

互~凉~网的广大观众朋友们大家好,本up猪在C站(CSDN俗称粪坑)的ID叫飞天大司马,鉴于C站虽然阅读量大,但是本人反馈无法及时,因此在B站同步更新创作内容,欢迎各位新老粉丝前来批评指正一起学习。


(资料图片)

开始进入固件库编程

学习原因即优缺点:固件库的出现让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

————————————————

版权声明:本文为CSDN博主「飞天大司马」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/m0_51019960/article/details/129131707

关键词:

[ 相关文章 ]

[ 相关新闻 ]