草庐IT

HAL 固件库

总结所学 2023-08-16 原文

学习自记:

小结先:

  1. core_cm3.h屏蔽编译器差异、定义变量类型、内核寄存器地址定义-——>不同芯片厂商、不同软件都用arm公司定义的内核文件,此文件为通用文件
  2. 汇编语言启动文件startup_stm32f103xx.s-——>针对芯片的专有文件
  3. 系统初始化system_stm32f1xx.c/h-——>
  4. stm32f1xx.h型号选择文件-——>
  5. 外设寄存器地址和结构体类型定义stm32F103xx.h-——>
  6. stm32f1xx_hal_conf.h所需外设驱动函数选择及时钟源配置,这个文件被包含进 stm32f103xx.h 文件,这个文件还可配置是否使用“断言”编译选项-——>
  7. STM32F1xx_HAL_Driver外设驱动函数
  8. stm32f1xx_hal.c/h HAL库初始化和调试模式

基于 Cortex 系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些差异
导致程序在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex 微
控制器软件兼容性问题,ARM 与芯片厂商建立了 CMSIS 标准 (Cortex MicroController Software
Interface Standard)。
所谓 CMSIS 标准,实际是一个软件抽象层,一套函数库,提供用户程序与arm内核和厂商外设的接口

CMSIS函数库 主要包括:
内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由 ARM 公司提供。
• 设备外设访问层:提供了片上的核外设的地址和中断定义,主要由芯片生产商提供。
可见 CMSIS 层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件抽象层,可
以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽硬件差异,这对软件的移植是
有极大的好处的。STM32 的库,就是按照 CMSIS 标准建立的。 

1.固件库目录

  • Documentation:文件夹下是 HAL 库帮助文档 
  • Drivers:HAL 内核库,外设驱动库
  • Middlewares:中间件,包含ST官方的STemWin、STM32_Audio、TM32_USB_Device_Library、
  • STM32_USB_Host_Library;也有第三方的 fatfs 文件系统等等。
  • Project :用HAL库写的针对官方发行 demo 板的例子和工程模板。
  • Utilities:实用的公用组件比如 LCD_LOG 实用液晶打印调试信息。
  •  Release_Note.html::库的版本更新说明。

2.STM32Cube_FW_F1_V1.8.0\Drivers\CMSIS\文件夹下内容

2.1 Include文件夹:

  • Include文件夹中是核内设备    函数通用头文件,定义内核寄存器(进入内核的接口)(类似stm32F103xx.h 文件,但定义的是内核部分的寄存器)。
  • 内核的寄存器说明,查阅《cortex_M3_Technical Reference Manual》及《Cortex®-M3 内核编程手册》文档,《STM32F103xxx 参考手册》只包含片上外设说明,不包含内核寄存器。
  • STM32F1 工程四个文件:core_cm3.h、core_cmFunc.h、corecmInstr.h、core_cmSimd.h,其它的文件是属于其它内核的,还有几个文件是 DSP 函数库使用的头文件。
  • core_cm3.h 文件有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异;core_cm3.h文件中包含了“stdint.h”这个头文件位于 RVMDK 这个软件的安装目录下,主要作用是提供一些类型定义

2.2 Device 文件夹:

  •  启动文件 startup_stm32f103xx.s

文件目录:\Drivers\CMSIS\Device\ST\stm32f1xx\Source\Templates

文件内汇编语言,包含所有中断服务函数的名称引导至SystemInit初始化函数和main函数

  • system_stm32f1xx.c文件

文件目录:\Drivers\CMSIS\ Device\ST\stm32f1xx\Source\Templates

启动文件调用的“SystemInit”初始化系统时钟函数

  •  stm32f1xx.h,stm32F103xx.h ,system_stm32f1xx.h文件

文件目录:\Drivers\CMSIS\Device\ST\stm32f1xx\Include

stm32f1xx.h,根据芯片型号选择不同stm32F103xx.h;

stm32F103xx.h,STM32 中所有的外设寄存器地址和结构体类型定义;
 

2.STM32Cube_FW_F1_V1.8.0\Drivers\STM32F1xx_HAL_Driver\文件夹下内容
 

芯片片上外设部分,src 外设的驱动源程序,inc 相对应的外设头文件。


3.Templates及其它文件夹下


stm32f1xx_it.c/h:用来编写中断服务函数

stm32f1xx_hal_conf.h:芯片外设功能比较多,使用这个配置文件根据芯片型号增减 ST 库的外设文件, 另外时钟源配置也是在这里进行设置。

小结:

  1. core_cm3.h屏蔽编译器差异、定义变量类型、内核寄存器地址定义-——>
  2. 汇编语言启动文件startup_stm32f103xx.s-——>
  3. 系统初始化system_stm32f1xx.c/h-——>
  4. stm32f1xx.h型号选择文件-——>
  5. 外设寄存器地址和结构体类型定义stm32F103xx.h-——>
  6. stm32f1xx_hal_conf.h选择所需外设驱动函数及时钟源配置,这个文件被包含进 stm32f103xx.h 文件,这个文件还可配置是否使用“断言”编译选项-——>
  7. STM32F1xx_HAL_Driver外设驱动函数

4.常用官方资料

  • 《STM32F10X-中文参考手册》
  • 《STM32 数据手册》
  • 《STM32F103xG_User_Manual.chm》HAL库函数使用手册

Cortex-M内核:
•《Cortex™-M3 内核编程手册》
•《Cortex-M3 权威指南》。

5.keil中添加宏定义:

在这个选项中添加宏,就相当于我们在文件中使用“#define”语句定义宏一样。在编译器中添加
宏的好处就是,只要用了这个模版,就不用源文件中修改代码

 STM32F103xE 宏:为了告诉 STM32HAL 库,我们使用的芯片类型是 STM32 型号是大容量
的,使 STM32HAL 库根据我们选定的芯片型号来配置

 USE_HAL_DRIVER 宏:为了让 stm32f1xx.h 间接包含 stm32f1xx_hal_conf.h 这个头文件。

stm32f1xx.h芯片选择文件

stm32f1xx_hal_conf.h 外设驱动选择文件

中间包含stm32f1xx_hal.h文件作为桥接

stm32f1xx_hal.c

该文件用于HAL初始化,包含DBGMCU,基于SysTick API的Remap和Time Delay。 

6.以GPIO倒推白话说明HAL库结构

以下依次为被包含的递进关系

6.1 用户GPIO.C/H文件

GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  GPIO_InitStruct.Pin = KEY1_Pin|KEY2_Pin|HALLD_2_Pin|HALLC_2_Pin
                          |HALLB_2_Pin|HALLA_2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

里面用到了

GPIO_InitTypeDef GPIO_InitStruct = {0};在stm32f1xx_hal_gpio.h文件里
  
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);在stm32f1xx_hal_gpio.c文件里

6.2.外设驱动HAL_Driver文件里:

stm32f1xx_hal_gpio.h包含 结构体和定义:

typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;

/** @defgroup GPIO_speed_define  GPIO speed define
  * @brief GPIO Output Maximum frequency
  * @{
  */
#define  GPIO_SPEED_FREQ_LOW              (GPIO_CRL_MODE0_1) /*!< Low speed */
#define  GPIO_SPEED_FREQ_MEDIUM           (GPIO_CRL_MODE0_0) /*!< Medium speed */
#define  GPIO_SPEED_FREQ_HIGH             (GPIO_CRL_MODE0)   /*!< High speed */

stm32f1xx_hal_gpio.c包含 初始化函数:


void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
 
   
}

6.3 CMSIS内核函数文件:stm32f103xe.h

以上用到的初始化函数用到了stm32f103xe.h的结构体

/** 
  * @brief General Purpose I/O
  */

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;

/** 
  * @brief Alternate Function I/O
  */

typedef struct
{
  __IO uint32_t EVCR;
  __IO uint32_t MAPR;
  __IO uint32_t EXTICR[4];
  uint32_t RESERVED0;
  __IO uint32_t MAPR2;  
} AFIO_TypeDef;

通过寄存器结构体和下面的GPIOx初始地址联系到一起就可以知道各个寄存器地址

上一节的初始化函数就是设置结构体内各寄存器的不同值得到不同功能。

上一节的定义define (GPIO_CRL_MODE0_1)、 (GPIO_CRL_MODE0_0)、  (GPIO_CRL_MODE0) 也包含在stm32f103xe.h里面

由此将用户文件GPIO.C/H和外设函数stm32f1xx_hal_gpio.h/c和内核文件stm32f103xe.h联系到了一起

补充:

  1. stm32f103xe.h除了设置各功能寄存器结构体、外设寄存器初始地址,还有寄存器位定义,操作位的宏
  2. stm32f103xe.h文件的选择由stm32f1xx.h决定

3. 外设文件stm32f1xx_hal.h也是由stm32f1xx.h选定

7.NVIC

有关HAL 固件库的更多相关文章

  1. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  2. 【HAL库】STM32CubeMX开发----delay延时实验----NOP空指令 - 2

    STM32CubeMX下载和安装详细教程【HAL库】STM32CubeMX开发----STM32F103/F207/F407----目录前言HAL库有自带的ms级延时函数:HAL_Delay();缺点1:无法实现us级延时缺点2:此延时函数是由SysTick滴答定时器中断产生的,滴答定时器的中断优先级是所有中断中最低的,无法在其他中断中产生延时。一、STM32F407----delay延时实验本次实验以STM32F407VET6芯片为MCU,使用25MHz外部时钟源。系统时钟SYSCLK=168MHz,使用__NOP();空指令实现延时。User_delay.c#include"User_de

  3. OpenWrt 固件编译教程 - 2

    一、编译环境准备编译平台阿里云 Ubuntu20.04.5LTS安装编译环境依赖sudoapt-get-yinstallbuild-essentialasciidocbinutilsbzip2gawkgettextgitlibncurses5-devlibz-devpatchpython3python2.7unzipzlib1g-devlib32gcc1libc6-dev-i386subversionflexuglifyjsgit-coregcc-multilibp7zipp7zip-fullmsmtplibssl-devtexinfolibglib2.0-devxmltoqemu-utils

  4. 小米路由器AX9000刷写OpenWrt官网发布的固件 - 2

    准备工作         从官网(OpenWrtFirmwareSelector)下载下图标注的两个文件    由于OpenWrt官网发布的固件会改写MTD分区布局,不支持原厂和OpenWrt共存,需要先刷入openwrt-ipq807x-generic-xiaomi_ax9000-initramfs-factory.ubi核心系统自动进行分区调整。进入AX9000SSH        进入方法请参考https://www.right.com.cn/forum/thread-5695827-1-1.html    通过执行下面这条命令记下当前原厂固件所在分区    nvramgetflag_b

  5. STM32如何配置HAL库 - 2

    STM32如何配置HAL库前言  相比较早几年使用标准库开发来讲,最近几年HAL库的使用是越来越多,那么我们开发应当使用哪一种呢,本文着重介绍常用的几种开发方式及相互之间的区别,白猫也好、黑猫也好,抓到耗子就是好猫。STM32三种开发方式  通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配置寄存器进行开发。网上关于标准库、HAL库的描述相信是数不胜数。可是一个对于很多刚入门的朋友还是没法很直观的去真正了解这些不同开发发方式彼此之间的区别,所以笔者想以一种非常直白的方式,

  6. windows - 使用 bcdedit 添加 UEFI 固件启动项 - 2

    如何使用bcdedit添加新的UEFI固件启动菜单条目(在NVRAM中)。例如我尝试了以下步骤,但未添加启动项。bcdedit/create/d"LinuxLoader"/applicationosloader这将返回一个新的guid(比如newguid)bcdedit/set{newguid}devicepartition=S:bcdedit/set{newguid}path\boot\efi\bootx64.efibcdedit/set{fwbootmgr}displayorder{newguid}/addfirst提前致谢。 最佳答案

  7. 虚拟摄像头之九: IMX8Q 的 camera.imx8.hal 框架详解 - 2

    前言android系统的camerahal框架不同厂家设计思路、不尽相同;本篇梳理NXPandroid8的camerahal设计框架设计逻辑和代码走读与分析。笔者再次特别说明:在《虚拟摄像头之三:重构android8.1的v4l2_camera_HAL支持虚拟摄像头》文章中声称、虚拟摄像头HAL方案计划采用Android8中的v4l2_camera_HAL来重构实现;现在更改为NXP的CameraHAL框架来实现,因此采用此篇梳理学习笔记内容。1>.Camera类的设计基本设计逻辑是封装Camera对象、我们先看看该类的定义:@vendor/nxp-opensource/imx/libcame

  8. CubeMX生成的中断函数HAL_UART_IRQHandler(*huart1)如何使用。 - 2

    串口发送/接收函数HAL_UART_Transmit();串口发送数据,使用超时管理机制 HAL_UART_Receive();串口接收数据,使用超时管理机制HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收HAL_UART_Transmit_DMA();串口DMA模式发送HAL_UART_Transmit_DMA();串口DMA模式接收串口中断函数HAL_UART_IRQHandler(UART_HandleTypeDef*huart); //串口中断处理函数HAL_UART_TxCpltCallback(UART_H

  9. 蓝桥杯嵌入式基础模块——定时器输入捕获功能(新板)STM32G431(HAL库开发) - 2

            在板子上有两个555定时器,可以做成信号发生器,利用定时器输入捕获功能可以检测出,信号发生器的所产生脉冲信号的频率和占空比。定时器的输入捕获有两个功能,直接捕获模式和间接捕获模式;直接捕获:只能捕获本身通道的脉冲信号;间接模式:可以捕获此定时器每个通道的脉信号。操作思路:捕获频率:初始化定时器基础,开启定时器,开启定时器输入捕获上升沿中断,定时器一直计数,直到,捕获到上升沿说明过了一个周期,读取计数值,读取完然后清零,等待读取下一个周期,乘以时钟频率,就是周期,然后计算PWM频率。捕获占空比:利用此定时器的另一个通道,作为间接捕获模式,读取下降沿,产生下降沿中断,读取此定时器的

  10. F1-HAL库快速移植MPU6050 - 2

    前段时间在做平衡车,需要移植MPU6050程序。但是在网上找了挺多相关例子的,但是有时候一步步跟着做,结果还是一堆errors或者读不出数据来,最后自己花了些时间,终于移植好了,前来分享一下。先分享我的工程,和需要移植的MPU6050的程序完整工程+MPU6050移植程序提取码:3ycr效果演示接下来进入正题:一、首先在CubeMX中创建工程1.先正常配置RCC、SYS和时钟树。2.我这里选择PB6和PB7读MPU6050用、打开了串口1、并且我打开了4个脚给OLED用。3.然后生成工程好了。二、程序移植1.我们把下载到的MPU6050程序添加到工程中,加入.c文件,并且把头文件路径也添加进来

随机推荐