我在高职教STM32(无论怎么封装终究是操作的还是寄存器)06初识STM32固件库
https://m.toutiao.com/is/J48Arsu/
(无论怎么封装终究是操作的还是寄存器)
大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助头条平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学设计分享出来,如果您正是一名单片机爱好者或是一名同行,欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!#我要上微头条# #STM32# #高职高专#
一、STM32神器之库开发——用抽象的分层屏蔽底层
- 什么是STM32函数库
在正式介绍库之前,先献上一条不知出处的“至理名言”:计算机领域中的所有问题,都可以通过向上一层进行抽象封装来解决。
- 库就是函数接口(API)
开发者可调用这些函数接口来配置STM32的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发快速,易于阅读,维护成本低等优点。 - 库是架设在寄存器与用户驱动层之间的代码
① 库向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口。
② 当我们调用库API的时候不需要挖空心思去了解库底层的寄存器操作,就像当年我们刚开始学习C语言的时候,用prinf()函数时只是学习它的使用格式,并没有去研究它的源码实现。
③ 记住一点:无论怎么封装,终究是操作的还是寄存器。
库开发与寄存器开发
- 为什么采用库开发来学习
- 开发速度快
对于STM32,因为外设资源相当丰富,带来的必然是寄存器的数量和复杂度的增加,直接配置寄存器方式影响了开发效率和维护成本。库开发方式则正好弥补了这个缺陷。 - 程序移植性好
随着ST库的完善与大家对库的了解,更多的开发者选择了库。STM32F1系列和STM32F4系列各有一套自己的函数库,但它们大部分是兼容的,F1和F4之间的程序移植,只需要小改即可。
对于库采用的多层封装导致生成代码量大的问题,其实在STM32充足资源面前并不明显。绝大部分时候,我们愿意牺牲一点CPU资源,选择库开发。
事实上,库函数的底层实现恰恰是直接配置寄存器方式的最佳例子,它代替我们完成了寄存器配置的工作,而想深入了解芯片是如何工作的话,只要直接查看库函数的最底层实现就能理解。
要想修炼C语言,就从ST的库开始吧,相信你会为它严谨、优美的实现方式而陶醉。
二、STM32结构与库层次关系——将神奇而强大的库文件抽丝剥茧
- CMSIS标准
基于Cortex-M3的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异却导致软件在同内核、不同外设的芯片上移植困难。
为了解决不同芯片厂商的微控制器软件的兼容性问题,ARM与芯片厂商建立了CMSIS标准(Cortex Microcontroller Software Interface Standard)
CMSIS层位于硬件层与用户层(或操作系统)之间,提供了与芯片厂商无关的硬件抽象层,可以为接口外设、实时操作系统提供简单的处理器软件接口,这对软件的移植大有好处。
CMSIS层的作用
- 库目录和文件简介
- 标准库里的目录
STM32标准库可以从官网获得,也可以直接从开发板的配套资料得到。这里有必要说明一下,STM32的库开发有两种:标准库和HAL库。标准库是目前最多人使用的方式,也是学习STM32接触最多的一种开发方式,我在给学生上课使用的就是标准库。
STM32标准库里的目录解读
- 顺便提一下HAL库
ST官方对标准库更新到3.5.0就到头了,而转向主推HAL库开发。HAL全称就是Hardware Abstraction Layer(抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道他的作用是什么。它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的周期,而且HAL库尤其的有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够了。
既然这么好,那为什么不用呢?这得分谁用,如果是一个有开发经验的工程师,因为对STM32了如指掌,即使抽象也能知道来龙去脉。但对于零基础的学生来说,建议还是从经典的标准库学起,打好基础,毕竟移植程序这种事儿在学校里几乎是不需要的,过于抽象的东西也会带来不少迷茫。
- CMSIS文件夹
- 展开概览
标准库中CMSIS文件夹展开
- 内核相关文件
core_cm3.c——这个文件实现了一下操作内核外设寄存器的函数,用的比较少。
core_cm3.h——
core_cm3.h头文件里面实现了内核的寄存器映射,对应外设头文件stm32f10x.h,区别就是一个针对内核的外设,一个针对片上(内核之外)的外设。
core_cm3.h还包含了stdint.h这个头文件,这是一个ANSI C文件,是独立于处理器之外的,就像熟知的C语言头文件stdio.h一样,主要作用是提供一些类型定义。这些新类型定义屏蔽了在不同芯片平台时,出现的诸如int的大小是16位,还是32位的差异。所以在以后的程序中,都将使用新类型如uint8_t 、uint16_t等。
core_cm3.h中对类型的定义
- 启动文件
启动文件是任何处理器在上电复位之后最先运行的一段汇编程序,它为C语言的运行建立一个合适的环境。因此,上电之后最先运行的并不是C语言的主函数哦。
启动文件在startup\arm\这个文件夹下面,有很多个,不同型号的微处理器用的启动文件不一样。我们开发板中用的STM32F103C8T6的FLASH是64K,属于基本型的中容量产品,启动文件统一选择startup_stm32f10x_md.s。
针对不同FLASH容量的启动文件
- 外设相关文件
stm32f10x.h——这是一个非常底层的文件,它包含了STM32中寄存器地址和结构体类型定义,类似51单片机中的reg51.h。因此,在使用到STM32标准库的地方都要包含这个头文件。
system_stm32f10x.c——这个文件由ST公司提供,功能是设置系统时钟和总线时钟。所有外设都与时钟频率有关,所以这个文件是非常关键的。
- STM32F10x_StdPeriph_Driver文件夹
- 目录结构
外设驱动库目录
- 源文件与头文件
外设驱动库目录下的文件
外设文件的命名:每个外设对应一个 .c和 .h的文件,我们把这类外设统称为stm32f10x_ppp.c或stm32f10x_ppp.h文件,ppp表示外设名称。
外设文件的选择:实际的项目并不是所有外设都要用到的,至于哪些用哪些不用,其实是可以通过ST官方工程模板提供的一个stm32f103x_conf.h文件来进行选择。
特别的misc.c文件:这个文件提供了外设对内核中的NVIC(中断向量控制器)的访问函数。因此,在配置中断时,必须把这个文件添加到工程中。
- 官方库工程模板
- 目录结构
我们在用库建立一个完整的工程时, 还需要添加这个目录下的stm32f10x_it.c、stm32f10x_it.h 和stm32f10x_conf.h 这三个文件。
ST官方提供的标准库工程模板
- 文件解读
stm32f10x_it.c——这个文件是专门用来编写中断服务函数的,在我们修改前,这个文件已经定义了一些系统异常(特殊中断)的接口,其它普通中断服务函数由我们自己添加。至于这些中断服务函数的接口如何写?我们会在学习中断和启动文件的时候详细介绍。
stm32f10x_conf.h——这是个用于配置的头文件,统一管理所需的stm32f10x_ppp.h外设头文件。需要的,保留对应的配置语句;不需要的,注释掉对应的配置语句即可。最终,这个头文件又会在stm32f10x.h 的被包含,所以最终我们只需要包含stm32f10x.h这个头文件即可,非常方便。
stm32f10x_conf.h中管理的外设驱动库文件
- 库文件之间的关系
STM32标准库中文件的相互关系
位于用户层的几个文件,就是我们在使用库的时候,针对不同的应用对库文件进行增删(用条件编译的方法增删)和改动的文件。
位于CMSIS层的文件包含进工程,除了特殊系统时钟需要修改system_stm32f10x.c,其它文件丝毫不用修改,也不建议修改。
三、学会使用帮助文档——授人以鱼不如授人以渔
- 常用官方资料
官方资料是所有关于STM32知识的源头,而官方的帮助手册是最好的教程,几乎包含了所有在开发过程中遇到的问题。老耿坚信,授之以鱼不如授之以渔。
- STM32F10x-中文参考手册
这个文件全方位介绍了STM32芯片的各种片上外设,它把STM32的时钟、存储器架构、以及各种外设、寄存器都描述得清清楚楚。 - Cortex-M3内核编程手册
主要讲解STM32内核寄存器相关的说明,是《STM32F10x-中文参考手册》没涉及到的内核部分的补充,用的不多。 - Cortex-M3权威指南
由ARM公司提供,它详细讲解了Cortex内核的架构和特性,要深入了解Cortex-M内核,这是首选,经典中的经典。 - STM32F103x固件函数库用户手册
这就是前面提到的库帮助文档的中文版,在使用库函数时,我们最好通过查阅此文件来了解标准库提供了哪些外设、函数原型或库函数的调用的方法。
- 学会查阅库函数
- 初识库函数
所谓库函数,就是STM32的库文件中为我们编写好驱动外设的函数接口,我们只要调用这些库函数,就可以对STM32进行配置,达到控制目的。
我们可以不知道库函数是如何实现的,但我们调用函数必须要知道函数的功能、可传入的参数及其意义、和函数的返回值。 - 优美的STM32库
每个函数和数据类型都符合见名知义的原则,但名称写起来特别长,而且输入这么长的英文很容易出错。所以在用到库函数的地方,直接把帮助文档中的函数名称复制粘贴到工程文件就可以了。
库函数使用帮助文档