STM32F1 HAL库笔记0

参考UM1850  Description of STM32F1 HAL and low-layer drivers

1、STM32Cube 包括:

        • STM32CubeMX,图形软件配置工具,使用图形向导生成 C 初始化代码。

        • 嵌入式软件平台,按系列提供(例如用于STM32F1的STM32CubeF1),包括:

        ——STM32Cube HAL,STM32抽象层嵌入式软件,确保在STM32产品组合中实现最大的可移植性。HAL API 可用于所有外围设备。

        ——低层 API (LL) 提供快速、轻量级、面向专家的层,比 HAL 更接近硬件。LL API 仅适用于一组外围设备。

        —— 一组一致的中间件组件,例如 RTOS、USB、TCP/IP 和图形。

        ——所有嵌入式软件实用程序,随附全套示例。

!!!以上的意思,写STM32的程序的方法是,通过使用STM32CubeMX生产初始代码,调用HAL APIs、LL APIs或者搭配RTOS来完成开发工作。有示例程序可参考的。

2、HAL的特征

        HAL针对功能模块,不是外设器件。啥意思?例如,一个USART 外设会存在这么几个模块:UART 驱动程序模块、USART 驱动程序模块、SMARTCARD 驱动程序模块和 IRDA 驱动程序模块。模块,在程序里理解为C语言数据结构struct,或者C++的类,使用时实例化为实例instance。

        API分为通用API和扩展API(也就是当初没设计,后来又设计了一些特殊功能)。

        三种 API 编程模型:轮询、中断和 DMA。(API里有不同的后缀区分)

        API 符合 RTOS 标准:完全可重入的 API (RTOS不同线程调用同一API,不会死锁);在轮询模式下系统地使用超时(阻塞延时,RTOS可以重新调度运行其它线程)。

        支持外设多实例,允许对给定外设的多个实例(USART1、USART2...)进行并发 API 调用。

        三种用户回调函数(写程序只用启动,然后写好回调函数就行):

                ——初始化外设 Init/DeInit回调函数,执行外设系统级初始化/取消初始化(一般操作这些:时钟、GPIO、中断、DMA)

                ——外设中断事件回调,中断处理函数里已经清除中断标志,直接写业务逻辑

                —— 错误事件回调

        对象锁定机制:安全的硬件访问,防止对共享资源的多次虚假访问。

        用于所有阻塞进程的超时:超时可以是简单的计数器或时基。超时和延时在HAL里很重要,一般默认为systick为时基。

3、HAL数据结构

        有三种,外设句柄结构、初始化和配置结构、处理流程结构。

        ——外设句柄结构:PPP_HandleTypeDef  *handle;每个外设/模块实例都有自己的句柄,实例资源是独立的。外设进程通信:句柄结构有通信资源,全局指针、DMA 句柄、状态机。存储:句柄可以有全局变量,存储数据。

        例子:usart句柄,可以实例化为USART1、USART2......结构体有发送接收过程的buffer,有DMA的句柄,状态机,出错控制等。还有初始化句柄。

typedef struct
{
USART_TypeDef *Instance; /* USART registers base address */
USART_InitTypeDef Init; /* Usart communication parameters */
uint8_t *pTxBuffPtr;/* Pointer to Usart Tx transfer Buffer */
uint16_t TxXferSize; /* Usart Tx Transfer size */
__IO uint16_t TxXferCount;/* Usart Tx Transfer Counter */
uint8_t *pRxBuffPtr;/* Pointer to Usart Rx transfer Buffer */
uint16_t RxXferSize; /* Usart Rx Transfer size */
__IO uint16_t RxXferCount; /* Usart Rx Transfer Counter */
DMA_HandleTypeDef *hdmatx; /* Usart Tx DMA Handle parameters */
DMA_HandleTypeDef *hdmarx; /* Usart Rx DMA Handle parameters */
HAL_LockTypeDef Lock; /* Locking object */
__IO HAL_USART_StateTypeDef State; /* Usart communication state */
__IO HAL_USART_ErrorTypeDef ErrorCode;/* USART Error code */
}USART_HandleTypeDef;

        多实例特性意味着应用程序中使用的所有 API 都是可重入的,例子???

        GPIO、SYSTICK、NVIC、PWR、RCC、FLASH这些共享外设,不适用句柄结构来描述,直接使用HAL函数。

        ——初始化和配置结构,这个好理解,例如UART_InitTypeDef、HAL_ADC_ConfigChannel (ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)。

        ——处理流程结构,例如:HAL_PPP_Process (PPP_HandleTypeDef* hadc,PPP_ProcessConfig* sConfig)。

4、API分类

        通用APIs

HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc); 
HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc); 
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); 
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); 
HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); 
HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); 
void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);

        扩展APIs

系列特定API
HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t Sing
leDiff); uint32_t HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef* hadc, uint32_t S
ingleDiff);
指定型号API
HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_tLengt
h);
HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc);

5、HAL 驱动程序规则

5.1、HAL API 命名规则

        File names                     stm32f1xx_hal_ppp.c/stm32f1xx_hal_ppp.h

        Module name                 HAL_PPP_ MODULE

        Function name               HAL_PPP_Function、HAL_PPP_FeatureFunction_MODE

        Handle name                 PPP_HandleTypedef 

        Init structure name         PPP_InitTypeDef 

        Enum name                   HAL_PPP_StructnameTypeDef

        PPP 前缀是指外设功能模式,而不是外设本身。例如,如果 USART,PPP 可以是 USART、IRDA、UART 或 SMARTCARD,具体取决于外设模式。

        一个文件中使用的常量在此文件中定义。在多个文件中使用的常量在头文件中定义。所有常量都以大写形式写入,但外设驱动程序函数参数除外。

        typedef 变量名称应以 _TypeDef 为后缀。

        寄存器被视为常量。在大多数情况下,它们的名称为大写,并使用与 STM32F1 参考手册中相同的首字母缩略词。

        外设寄存器在 CMSIS 标头的 PPP_TypeDef 结构(例如 ADC_TypeDef)中声明:stm32f1xxx.h 对应于 stm32f100xb.h、stm32f100xe.h、stm32f101x6.h等

        外设函数名称以 HAL_ 为前缀,然后是相应的外设首字母缩略词(大写),后跟下划线。每个单词的首字母为大写(例如 HAL_UART_Transmit())。函数名称中只允许使用一个下划线,以将外设首字母缩略词与函数名称的其余部分分隔开。

        包含 PPP 外设初始化参数的结构命名为 PPP_InitTypeDef (例如 ADC_InitTypeDef)。

        包含 PPP 外设设备的特定配置参数的结构命名为 PPP_xxxxConfTypeDef (例如 ADC_ChannelConfTypeDef)。        

        外设句柄结构命名为 PPP_HandleTypedef (例如 DMA_HandleTypeDef)

        用于根据 PPP_InitTypeDef 中指定的参数初始化 PPP 外设的函数命名为 HAL_PPP_Init (例如 HAL_TIM_Init())。

        用于将 PPP 外设寄存器重置为默认值的函数命名为 HAL_PPP_DeInit (例如 HAL_TIM_DeInit())。

        MODE 后缀是指进程模式,可以是轮询、中断或 DMA。例如,当除了原生资源之外还使用 DMA 时,应该调用该函数:HAL_PPP_Function_DMA () 。

        Feature 前缀应引用新功能。示例:HAL_ADC_Start()是指注入模式。

5.2、HAL 一般命名规则

        对于共享外设和系统外设,不使用句柄或实例对象。此规则适用于以下外围设备:GPIO、 SYSTICK、NVIC、RCC、FLASH。

        GPIO示例:HAL_GPIO_Init() 只需要 GPIO 地址及其配置参数。

HAL_StatusTypeDef HAL_GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef *Init)
{
/*GPIO Initialization body */
}

        中断示例:在每个 peripheral/module driver中,定义了处理中断和特定时钟配置的宏。这些宏将导出到外设驱动程序头文件中使用它们。这些宏的列表定义如下:

__HAL_PPP_ENABLE_IT(__HANDLE__, __INTERRUPT__)         //中断使能
__HAL_PPP_DISABLE_IT(__HANDLE__,__INTERRUPT__)         //中断失能
__HAL_PPP_GET_IT (__HANDLE__, __ INTERRUPT __)         //获取中断IT标志
__HAL_PPP_CLEAR_IT (__HANDLE__, __ INTERRUPT __)       //清除中断IT标志
__HAL_PPP_GET_FLAG (__HANDLE__, __FLAG__)              //获取中断flag
__HAL_PPP_CLEAR_FLAG (__HANDLE__, __FLAG__)            //清除中断flag
__HAL_PPP_ENABLE(__HANDLE__)                           //使能外设
__HAL_PPP_DISABLE(__HANDLE__)                          //失能外设
__HAL_PPP_XXXX (__HANDLE__, __PARAM__)                 //特定的PPP HAL driver宏
__HAL_PPP_GET_ IT_SOURCE (__HANDLE__, __INTERRUPT __)  //获取中断源

        NVIC 和 SYSTICK 是 Arm® Cortex® 的两个核心功能。与这些功能相关的 API 位于 stm32f1xx_hal_cortex.c 文件中。

        (原书应该写错了)PPP_InitTypeDef句柄在使用 HAL_PPP_Init() API之前有效。init 函数在修改 handle 字段之前执行检查。如下形式:

hppp = HAL_PPP_Init(PPP_InitTypeDef) 
if(hppp == NULL){ return HAL_ERROR;}

        宏包括,条件宏:使用?:运算符而已。

#define ABS(x) (((x) > 0) ? (x) : -(x))

                      伪代码宏 (多指令宏):使用do{}while(0)包含多个指令而已。

#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD_, __DMA_HANDLE_) \ 
do{ \ 
(__HANDLE__)->__PPP_DMA_FIELD_ = &(__DMA_HANDLE_); \ 
(__DMA_HANDLE_).Parent = (__HANDLE__); \ 
} while(0)

5.3、HAL 中断处理程序和回调函数

        HAL 外设驱动程序还包括 中断处理程序HAL_PPP_IRQHandler()(在stm32f1xx_it.c),用户回调函数(具有 “weak” 属性的空函数,必须在用户代码中定义)。

        有三种类型的用户回调函数:外设初始化/去初始化回调:HAL_PPP_MspInit() 和 HAL_PPP_MspDeInit();处理完成回调:HAL_PPP_ProcessCpltCallback(); 错误回调:HAL_PPP_ErrorCallback()。

        回调函数 示例 

HAL_PPP_MspInit() / _DeInit()    
例如:HAL_USART_MspInit():HAL_PPP_Init() API 函数调用此函数,以执行外设系统级初始化(即初始化GPIO、时钟、DMA、中断)。 
HAL_PPP_ProcessCpltCallback()      
例如:HAL_USART_TxCpltCallback():当USART TX完成时由外设或DMA的中断处理程序调用 
HAL_PPP_ErrorCallback()
例如:HAL_USART_ErrorCallback(): 发生错误时由外设或DMA的中断处理程序调用

6、HAL 通用 API

        有4组通用API:

初始化/去初始化:HAL_PPP_Init()、HAL_PPP_DeInit()
IO 操作:HAL_PPP_Read()、HAL_PPP_Write()、HAL_PPP_Transmit()、HAL_PPP_Receive() 
控制功能:HAL_PPP_Set()、HAL_PPP_Get()。 
State 和 Errors 函数:HAL_PPP_GetState()、HAL_PPP_GetError()

        初始化和去初始化功能允许初始化外设和配置硬件资源,主要是时钟、GPIO、替代功能 (AF) 以及可能的 DMA 和中断。HAL_DeInit() 函数恢复 外设默认状态,释放硬件资源并删除与硬件的任何直接依赖关系。

        IO 操作函数对外设有效数据执行基本的写入和读取访问。

        控制功能用于动态更改外设设备配置,并设置另一种操作模式。

        外设状态和错误功能允许在运行时检索外设和数据流状态,并识别发生的错误类型。

下面的示例基于 ADC 外设。泛型 API 的列表并不详尽。它仅作为示例给出。

初始化组 
HAL_ADC_Init()   			//此函数初始化外设并配置相关资源(时钟、GPIO、AF 等)
HAL_ADC_DeInit() 			//此函数恢复外设默认状态,释放相关资源并消除与硬件的任何直接依赖关系。IO 操作组 
HAL_ADC_Start () 			//此函数在使用轮询方法时启动 ADC 转换 
HAL_ADC_Stop () 			//此函数在使用轮询方法时停止 ADC 转换 
HAL_ADC_PollForConversion() //此函数允许在使用轮询方法时等待转换结束。在这种情况下,超时值由用户根据应用程序指定。
HAL_ADC_Start_IT() 			//此函数在使用中断方法时启动 ADC 转换 
HAL_ADC_Stop_IT() 			//此函数在使用中断方法时停止 ADC 转换 
HAL_ADC_IRQHandler() 		//此函数处理 ADC 中断请求 
HAL_ADC_ConvCpltCallback() 	//在 IT 子例程中调用的回调函数,以指示当前进程的结束或当 DMA 传输完成时 
HAL_ADC_ErrorCallback() 	//在 IT 子例程中调用的回调函数,如果发生外设错误或 DMA 传输错误 控制组 
HAL_ADC_ConfigChannel() 	//此功能配置选定的 ADC 常规通道、定序器中的相应列和采样时间 
HAL_ADC_AnalogWDGConfig 	//此功能为选定的 ADC 配置模拟看门狗状态和错误组 
HAL_ADC_GetState() 			//此功能允许在运行时获取外设和数据流状态。
HAL_ADC_GetError() 			//此功能允许在运行时获取 IT 例程中发生的错误

7、HAL 扩展 API

        扩展 API 为特定系列或同一系列中的特定型号提供特定功能或覆盖修改后的 API。扩展API位于 stm32f1xx_hal_ppp_ex.c、stm32f1xx_hal_ppp_ex.h。

        基于 ADC 外设的示例:HAL_ADCEx_CalibrationStart()  //此功能用于启动自动 ADC 校准

        添加新功能的扩展API怎么扩展:5种方式如下:

        (1)在文件stm32f1xx_hal_ppp_ex.c(h)里增加API HAL_PPPEx_Function()

例如stm32f1xx_hal_adc_ex.c/h里

#if defined(STM32F101xG) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F
105xC) ||
defined (STM32F107xC) || defined (STM32F103xE) || defined(STM32F103xG)
/* ADC multimode */
HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint
32_t Length);
HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc);
#endif 

        (2)新增一个.c文件stm32f1xx_hal_newppp.c,并在stm32f1xx_hal_conf.h使用宏开启:#define HAL_NEWPPP_MODULE_ENABLED

        (3)将stm32f1xx_hal_ppp.c的API加__weak修饰,在文件stm32f1xx_hal_ppp_ex.c里覆写此API

           (4)  加入数据结构中,使用#if defined来控制开启

#if defined(STM32F100xB)
typedef struct
{
(...)
}PPP_InitTypeDef;
#endif /* STM32F100xB */

8、include头文件

        stm32f1xx_hal_conf.h:PPP 驱动程序是项目中使用的独立模块。用户必须在配置文件stm32f1xx_hal_conf.h中使用相应的 USE_HAL_PPP_MODULE define 语句来使能某个PPP驱动程序。例如:#define USE_HAL_USART_MODULE、 #define USE_HAL_IRDA_MODULE

        stm32f1xx_hal.h:stm32f1xx_hal.h包含了整个 HAL 库的通用配置。用户程序和 HAL C源文件中只需包含包含此头文件调用HAL资源。stm32f1xx_hal.h包含了stm32f1xx_hal_conf.h。

9、HAL 通用的定义

        在 stm32f1xx_hal_def.h 中定义了常见的枚举、结构和宏。 

待续,要去练车,科目三

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio gradle下载太慢了!怎么办?(已解决)

Android Studio!你到底干了什么?! 不能高速下载gradle,我等如何进行app编程?! 很简单,我修改gradle地址不就是了。 找到gradle-wrapper.properties文件 修改其中distributionUrl的地址。 将 ht…

本地电脑交叉编译ffmpeg 到 windows on arm64

本地电脑交叉编译ffmpeg 到 windows on arm64 我这里有编译好的win on arm 的 ffmpeg : https://github.com/wmx-github/ffmpeg-wos-arm64-build 使用 llvm-mingw 工具链 https://github.com/mstorsjo/llvm-mingw/releases 前缀 aarch64-w64-mingw32- 这个库是ubuntu 交叉编译…

ES配合高德地图JS-API实现地理位置查询

目录 实现功能点 技术选型 具体实现 Vue3整合高德地图JS API-2.0 添加商户:前端 添加商户:后端/ES 查询用户当前地理坐标 获取附近(指定距离)的商户 总结/测试Demo代码地址 测试概述:用户使用高德地图组件获取商户…

SpringBoot2:学SpringBoot前的知识准备-用IDEA创建传统的webapp工程,并整合SpringMVC

1、IDEA创建工程 基于Maven模板创建的SpringMVC工程 工程创建好后,只有webapp目录 这里,我们需要手动创建java目录和resources配置文件目录 创建好后,配置下目录属性 最终结构 至此,工程就创建好了 2、配置Tomcat 参考&am…

论文笔记:2023顶会SIGIR - Strategy-aware Bundle Recommender System

论文笔记:2023顶会SIGIR - Strategy-aware Bundle Recommender System

【Python报错已解决】`Provisional headers are shown Learn more`

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言:一、问题描述:1.1 报错示例:1.2 报错分析:1.3 解决思路&#xff…

145. 利用 Redis Bitmap实践: 用户签到统计

文章目录 一、Redis Bitmap简介二、Bitmap 的主要应用三、Go使用Redis实现签到统计用户签到查询用户签到状态统计今年累计签到天数统计当月的签到情况 总结 在现代应用程序中,用户签到是一个常见的功能。我们通常使用 MySQL 数据库来存储用户的签到记录。然而&#…

智能家居系统(基于STM32F103C8T6标准库+FreeRTOS+Qt串口开发实现)

视频演示:基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目_哔哩哔哩_bilibili 基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目: https://pan.baidu.com/s/1f41gAfOOnlcQoKoMx3o84A?pwd6j2g 提取码: 6j2g 注:本项目为学习完…

Windows I/O系统

硬件存储体系 寄存器 处理器内部定义的存储体,它们除了存储功能,往往还兼有其他的能力,比如参与运算,地址解析,指示处理器的状态,等等。寄存器是由处理器内部专门的触发器电路实现的,处理器往…

自动驾驶坐标转换(代码)

文章目录 1. lidar2ego 和 lidar2cam1.1 lidar2ego1.2 lidar2cam1.3 cam2img2. bev和ego的转换2.1 ego2bev2.2 bev2ego3 3d和2d坐标转换4 车道线插值5 车道线点的过滤6 畸变校正7 绘图7.1 3D lane7.2 绘制2d点1. lidar2ego 和 lidar2cam 1.1 lidar2ego 从.json标注文件中,解…

2024年高教杯国赛(B题)数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐,毕业于中国人民大学,对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在,我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

C#基础(2)枚举

前言 我们其实在前面已经了解过枚举到底有什么作用,但是那毕竟是概念性的语言,理解起来很抽象,今天我们会具体来讲一讲枚举,并谈一谈它的应用。 希望你能从今天的C#基础中有所收获。 基本概念 1.枚举:是一个比较特…

基于物联网的低成本便携式传感器节点用于火灾和空气污染的检测与报警

目录 摘要 引言 材料和方法 传感器节点 IoT 微控制器 颗粒物传感器 环境和气体传感器 MQTT代理 Node-Red监控平台 系统结构 数据存储 工作描述 实验结果 讨论 结论 致谢 参考文献 这篇论文的标题是《Low-cost IoT-based Portable Sensor Node for Fire and Air…

数据要素大市场打开新局面——数字经济背景下中国特色的数据产权三权分置

前言 数字经济飞速发展的大背景下,无论是数据要素大市场还是数据资产入表的发展和落地,都需要以数据产权基本制度为保障。对数据产权给与恰当的权利定位,有助于让数据成为创造和捕获价值的新经济资源。数据的价值在于使用,而传统…

链表leetcode-1

目录 1.常用技巧 1.1引入虚拟头结点 1.2对于变量,不要太吝啬,可以多定义,方便处理 1.3快慢双指针 2.例题 2.1两数相加 2.2两两交换链表中的节点 2.3重排链表 2.4合并K个升序链表 2.5K个一组翻转链表 1.常用技巧 1.1引入虚拟头结点 可…

【HTTP、Web常用协议等等】前端八股文面试题

HTTP、Web常用协议等等 更新日志 2024年9月5日 —— 什么情况下会导致浏览器内存泄漏? 文章目录 HTTP、Web常用协议等等更新日志1. 网络请求的状态码有哪些?1)1xx 信息性状态码2)2xx 成功状态码3)3xx 重定向状态码4&…

场景是人工智能第四要素,是垂直领域人工智能的第一要素。

"场景是人工智能的第四要素,与数据、算力、算法同等重要。"拿着技术找场景,还是拿着场景找技术?这个锤子和钉子的问题,一直困扰着各家AI大厂。从近5年的实践来看,拿着场景找技术是更为稳健的,否则…

哪款宠物空气净化器能更好的清理浮毛?希喂、352、IAM测评分享

家里这三只可爱的小猫咪,已然成为了我们生活中不可或缺的家庭成员,陪伴我们度过了说长不长说短不短的五年时光。时常庆幸自己当年选择养它们,在我失落的时候总能给我安慰,治愈我多时。 但这个温馨的背后也有一点小烦恼&#xff0…

ES6语法详解

以下是ES6常用的一些语法和特性: 声明变量的关键字变化:使用let和const、var来声明变量。 箭头函数:使用箭头(>)定义函数,简化函数的写法。 模板字符串:使用反引号(&#xff0…

Numpy中zeros、ones、empty的用法

目录 numpy基础介绍实例分析及结论 numpy基础介绍 Numpy 补充了Python语言所欠缺的数值计算能力,是其它数据分析及机器学习库的底层库。因其完全标准C语言实现,运行效率充分优化。最重要一点是开源免费。numpy的核心是矩阵(即多维数组)。 实…