STM32的标准库及其使用

2023-05-16

单片机的开发工作量,主要集中在两个地方,一是调通各种外设,二是实现产品功能。

像较高级的语言,比如c++/java/python等、因为将底层操作进行了封装,所以只需要集中关注第二点。事实上,越到后,底层越封装,上层应用开发就越简单,这也是软件开发这个领域甚至其他更多领域的必然发展趋势。

回顾下传统单片机软件开发方式:
芯片厂商提供数据手册、示例代码、开发环境;

单片机软件工程师面向产品功能,查阅数据手册,参考官方示例代码进行开发;
硬件操作的方式是用C语言对寄存器进行直接读写以操作硬件。


在简单单片机(如51单片机)上这一套工作的很好,但是随着单片机变复杂就带来一些问题。比如我们要花费大量时间去研究数据手册,研究具体的时序,找出具体寄存器的地址,了解地址每一位所对应的含义等等,这不是不能办到,而是,底层的东西是相对固定的,我们可以将底层的这些操作进行封装,供上层调用。这也是分层设计的合理应用。

不过,虽然封装会让使用起来更加简单,但是效率也会有所降低,封装的层数越多,效率就越低。这也是显而易见的,为了封装,必然要引入更多的代码,更多的资源。当然,总体来说利大于弊。

所以,STM32的标准库是什么?

其标准库全称为:标准外设库。就是将常用的外设操作(比如底层时序和上层时序等)进行封装。外设库简化了我们开发产品的两大工作量的第一个。外设库以源码方式提供,这个源码本身写的很标准,可以用作学习素材。

本质上,这些库和我们自己写的文件没有什么区别,只不过,因为太常用,而且相对固定,所以已经写好,提供给我们使用。该怎么编译怎么编译,该怎么链接还是怎么链接。

注意:

外设库只是帮助我们简化编程,简化的主要是劳动量。外设库一定程度上降低了编程难度,但是只会库、离了库就不会编程、库函数调用出了问题就束手无策,那是不可取的。

获取标准库

STM32固件库是官方推出来的对底层寄存器进行操作的函数库,编写程序时不用考虑怎么操作寄存器,只需要调用库函数就能实现对应功能。方便了使用STM32芯片进行开发的人员,使开发工作更简单快捷,对于代码来说可读性也更好。
 

从ST官网。

地址如下:

STM32微控制器软件 - STMicroelectronics

现在是2022年8月,去官网找最新F1的标准外设库,显示已经下线,找不到了:

标准库是第一代固件库,实现的外设相对较少,封装上的效率相对较低,而且,随着网路技术和USB技术的快速发展,已经很难满足当代的需求。比如标准库没有网络功能,没有文件系统,没有GUI等等。

现在STM32的固件库有标准库,HAL库和LL库三种,官方现在主推HAL库,标准库不再更新(F1标准库好像干脆直接下架了),新学的话建议直接学习HAL库,配合STM32CubeMX的配置工具非常容易使用STM32。其不仅效率有所提升,而且新增了对网络使用等的协议。

为什么标准库不是通用的?而是需要对应到某种型号的单片机?

因为不同型号的单片机,在CPU设计上,以及外设定义、引脚定义等各方面都有所差异。所以,不可能存在通用的一套代码,只能说,尽可能地通用。

标准库目录结构

虽然当前已经不推荐使用标准库,但是为了更好地学习HAL库,还是有必要先学习一下标准库。虽然官网已经找不到F1的标准库,那只能去其他地方,比如百度,去找。

找到一个:STM32F10x_StdPeriph_Lib_V3.5.0

里面的目录如下:

接下来针对这些文件夹逐个介绍。


_htmresc

没啥用,就放了ST和CMSIS的LOGO图片。

CMSIS是啥?看LOGO上的标注可知它是ARM公司Cortex-M系列的接口标准。

全称为:Cortex Microcontroller Software Interface Standard,Cortex-M软件接口标准。

使用CMSIS,可以为处理器和外设实现一致且简单的软件接口,从而简化软件的重用、缩短微控制器新开发人员的学习过程,并缩短新设备的上市时间。软件的创建被嵌入式行业公认为主要成本系数。通过在所有Cortex-M 芯片供应商产品中标准化软件接口,这一成本会明显降低,尤其是在创建新项目或将现有软件迁移到新设备时。

CMSIS是ARM公司与多家不同的芯片和软件供应商一起紧密合作定义的,提供了内核与外设、实时操作系统和中间设备之间的通用接口。

详情参考百度百科:CMSIS_百度百科 (baidu.com)


Libraries

这是最重要的一个目录,该目录包含了库函数与启动文件等,是标准库的实体部分。

该文件夹下又有两个子文件夹:CMSIS和STM32F10x_StdPeriph_Driver

CMSIS子目录:

CMSIS子目录是STM32F10x的内核库目录,核心子目录为CM3,其余目录可忽略。

CM3下又有两个子目录:CoreSupport和DeviceSupport

CoreSupport子目录:
内有2个重要文件,一个是core_cm3.c(内核通用源文件),另一个是core_cm3.h(内核通用头文件)。上述文件位于CMSIS核心层的核内外设访问层,由ARM公司提供,包含用于访问内核寄存器的名称、地址定义等内容。

DeviceSupport子目录:

\DeviceSupport\ST\STM32F10x

这些文件位于CMSIS核心层的设备外设访问层,由ST公司提供,包含片上核外设寄存器外称、地址定义、中断向量定义等。

startup:启动文件子目录,内包含4个子目录,其中arm子目录内存的都是根据FLASH容量大小所对应的启动文件;

stm32f10x.h:STM32F10x头文件;

system_stm32f10x.c:系统初始化源文件;

ststem_stm32f10x.h: 系统初始化头文件;

STM32F10x_StdPeriph_Driver子目录:

包含inc和src,显然,一个放的是头文件,一个放的是源文件,二者是一一对应的。

这个目录是干嘛的呢?看着里面文件名称。包含什么adc/bkp/can/dma/flash/gpio/rcc/spi/i2c等等。

明白了吗?我们说的外设库,就在这里被定义封装了。此目录是STM32F10x标准外设驱动库函数目录,包括了所有STM32F10x微控制器的外设驱动。

我们平常所说的驱动,就是把外设调通的一些程序代码。主要是实现这些外设的读写和控制。涉及到某个外设的底层及上层时序。


Project

此目录存放ST公司官方提供的STM32F10x外设驱动示例(STM32F10x_StdPeriph_Example)和工程模板(STM32F10x_StdPeriph_Template)。

外设驱动示例是在给你演示怎么使用这些外设:

工程模板是提供了不同开发工具下的工程,展示其一套工程目录的建立方式,具有一定的借鉴意义:

我们打开MDK的工程模板:MDK-ARM/Project.uvproj

显示的目录结构如下:

User放的是用户自己的代码;

StdPeriph_Driver放的是各种外设驱动;

CMSIS放的是系统初始化等内核代码;

STM32_EVAL暂时未知,好像是ARM官方的评估板,如果想了解详情,参考下文:初学者如何处理STM32创建工程时stm32_eval.h的问题_匠川的博客-CSDN博客_stm32_eval.h没加到工程;

MDK-ARM放的是启动代码;

Doc放的是相关文档。

不过实际工作中,我们并不会完全按照这个文件目录,仅作参考。


Utilities

里面放的好像就是评估板相关实现代码。


stm32f10x_stdperiph_lib_um,这个是外设库API文档,参考即可,一般直接看源码。

认识标准库

在标准库文件中,实际上可以只留下这几个目录,其他的可以全部删除,以方便用SI查看。

CM3

inc

src

core_cm3.c

位置:\Libraries\CMSIS\CM3\CoreSupport

该c文件是单片机的内核部分,共784行代码。那么,其中包含了哪些内容呢?

@brief    CMSIS Cortex-M3 Core Peripheral Access Layer Source File

这里面定义的是内核相关的一些寄存器及其封装。

暂时不管。

stm32f10x.h(重要)

较为重要的一个头文件。

位置:\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x

这个文件有八千多行代码,很多有用的宏定义以及结构体定义等都在这里面,比如:

我们自己操作寄存器时,也要写很多寄存器地址的定义。比如:

在标准库的文件中,统一帮我们定义好了。但两者是一致的,并没有本质区别。

其他还有对启动代码的选择:

可以允许我们将所有的启动代码都放到工程中,然后通过此处来选择使用。

system_stm32f10x.c/system_stm32f10x.h(重要)

直接摘录源码说明:

* @brief   CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
  * 
  * 1.  This file provides two functions and one global variable to be called from 
  *     user application:
  *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
  *                      factors, AHB/APBx prescalers and Flash settings). 
  *                      This function is called at startup just after reset and 
  *                      before branch to main program. This call is made inside
  *                      the "startup_stm32f10x_xx.s" file.
  *
  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
  *                                  by the user application to setup the SysTick 
  *                                  timer or configure other parameters.
  *                                     
  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
  *                                 be called whenever the core clock is changed
  *                                 during program execution.
  *
  * 2. After each device reset the HSI (8 MHz) is used as system clock source.
  *    Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to
  *    configure the system clock before to branch to main program.
  *
  * 3. If the system clock source selected by user fails to startup, the SystemInit()
  *    function will do nothing and HSI still used as system clock source. User can 
  *    add some code to deal with this issue inside the SetSysClock() function.
  *
  * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on
  *    the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file. 
  *    When HSE is used as system clock source, directly or through PLL, and you
  *    are using different crystal you have to adapt the HSE value to your own
  *    configuration.

这里面主要是系统初始化的内容,其中关键是时钟的配置。

标准库对硬件的封装

外设是怎么被封装起来的,你好奇吗?

  1. 先定义好各个寄存器的地址;
  2. 然后进一步封装成结构体;
  3. 然后通过结构体访问元素的形式去给相关寄存器赋值。

使用结构体方式访问寄存器的原理
C语言访问寄存器的本质是C语言访问内存,本质思路是:定义一个指针(临时变量)指向这块内存,然后*p = xx这种方式去解引用指针从而向目标内存中写入内容。
缺陷:当寄存器多了之后每一个寄存器都要定义一套套路,很麻烦。
解决思路:就是打包,批发式的定义,用结构体(想一下为什么不用数组?)的方式进行打包。具体做法是:把整个一个模块的所有寄存器(地址是连接的)打包在一个结构体中,每个寄存器对应结构体中的一个元素,然后结构体基地址对应寄存器组的基地址,将来就可以通过结构体的各个元素来访问各个寄存器了。
结构体方式来访问寄存器和指针式访问寄存器,本质上其实是一样的,区别是C语言的封装不同。

具体可以自行查看源码,如果有看不懂的,就结合数据手册和百度,总之,如果有需要,可以硬着头皮看下去。

此处不赘述。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32的标准库及其使用 的相关文章

随机推荐

  • EasyPoiUtil导出工具

    span class token keyword package span span class token namespace com span class token punctuation span zjson span class
  • sap上传excel文档字符限制处理

    abap中有多个函数处理上传的excel文档中的数据 xff0c 记录数据的信息 xff08 行 列 值 xff09 如 xff0c 函数KCD EXCEL OLE TO INT CONVERT xff1a data lt data in
  • ffmpeg部署和springboot使用

    视频存储部署 一 环境安装 1 1 yasm安装 在编译ffmpeg时 xff0c 执行 configure xff0c 报出了如下错误 xff1a nasm yasm not found or too old Use disable x8
  • 【docker】安装clickhouse

    一 联网安装clickhouse 1 为了方便安装 xff0c 将clickhouse的工作目录和数据目录都在同一个目录下 xff0c 在home下创建目录 mkdir clickhouse cd clickhouse 创建日志 配置文件
  • springboot整合mybatis-plus、clickhouse、mysql多数据源

    springboot的多数据源有多种方式 xff0c 本文按照指定不同dao mapper xml的方式来实现访问不同的数据源 这样的好处是不用注解去切换数据源 1 引入驱动 span class token generics span c
  • linux中的oracle启动和关闭

    一 启动数据库实例 span class token number 1 span 切换到oracle用户 su span class token operator span oracle span class token number 2
  • BigDecimal计算工具类

    方便以后大家使用 span class token keyword import span span class token namespace java span class token punctuation span math spa
  • 安装、使用mongodb踩过的坑

    轻松一下 没用分布式架构之前 xff0c 你只有一个问题 xff1a 并发性能不足 用了分布式架构 xff0c 多出了一堆问题 xff1a 数据如何同步 主键如何产生 如何熔断 分布式事务如何处理 使用mongodb踩过的坑 今天对安装 x
  • JS使用总结:简单标签赋值和取值:span等;实时触发事件

    JS使用总结 简单标签赋值和取值 xff1a span等 xff1b 实时触发事件 xff1b 了解一下简单标签赋值和取值实时触发事件代码 了解一下 作为后台开发 xff0c 今天使用了前端的技术 xff0c 做一个总结 xff1b 包括两
  • FreeRtos的笔记 (一)

    FreeRtos的笔记 一 一 前言 linux是分时系统 和 RTOS时实操作系统区别 RTOS时实操作系统 当外界事件或数据产生时 xff0c 能够接受并以足够快的速度予以处理 实时操作系统是保证在一定时间限制内完成特定功能的操作系统
  • UCOSII操作系统(一)--基础知识

    前言 比较主流的操作系统有UCOSII FREERTOS LINUX等 参考书籍 xff1a 嵌入式实时操作系统 COS II原理及应用 嵌入式实时操作系统uCOS II 邵贝贝 第二版 1 操作系统的作用 xff1a 操作系统是计算机硬件
  • ORB SLAM2 编译&运行

    1 依赖安装 xff1a 1 xff09 安装 GLEW xff1a sudo apt get install libglew dev 2 xff09 安装 libuvc xff1a git clone https github com k
  • SAP 一句话入门之SD

    SD是Sales and Distribution的简称 在SAP系统中 xff0c 销售与分销模块处在供应链下游 xff0c 关注从客户订单到向客户收款的全过程 SD模块中的Sales好理解 xff0c 而Distribution却容易被
  • realsense-ros安装

    一 realsense ros安装 1 Create a catkin workspace mkdir p realsense rosws src cd realsense rosws src catkin init workspace 2
  • thinkphp页面请求时间超过40S报404错误解决办法

    最近在写一个thinkphp项目的时候 xff0c 发现Ajax从后端请求数据时间比较长 xff0c 大概需要45秒左右 xff0c 但是一旦请求时间超过40s xff0c 页面就会超时404了 xff0c 一开始以为是ajax请求时间不能
  • C语言宏定义详解

    宏定义引入 源程序在编译之前 xff0c 会先进行预处理 预处理并不是C语言编译器的组成部分 xff0c 不能直接对它们进行编译 经过预处理后 xff0c 程序就不再包括预处理命令了 xff0c 最后再由编译程序对预处理之后的源程序进行编译
  • C语言枚举详解

    枚举的引入 枚举是C语言中的一种基本数据类型 xff0c 它可以让数据更简洁 xff0c 更易读 枚举语法定义格式为 xff1a enum 枚举名 枚举元素1 枚举元素2 注意 xff0c 各元素之间用逗号隔开 注意 xff0c 末尾有分号
  • STC-ISP使用指南

    该软件无需安装 xff0c 下载后打开直接用 本软件是专门给STC系列单片机下载烧录程序的 xff0c 并不能适用于ARM系列的单片机 界面介绍 xff1a 打开后的界面如下 xff1a 左边的部分一般是用来下载程序的 xff0c 右面一般
  • STM32前言知识总结

    目录 关于STM32 STM32F1 存储器 位带操作 三种启动模式 低功耗模式 复位 时钟系统 STM32库 仿真器和调试器 注 xff1a 本文大部分内容来自于STMCU官网以及STM32数据手册 STM32使用的是ARM公司的Cort
  • STM32的标准库及其使用

    单片机的开发工作量 xff0c 主要集中在两个地方 xff0c 一是调通各种外设 xff0c 二是实现产品功能 像较高级的语言 xff0c 比如c 43 43 java python等 因为将底层操作进行了封装 xff0c 所以只需要集中关