STM32开发速查笔记

摘要

STM32标准库已经不再维护,只有历史项目会用到标准库,底层上标准库相比HAL库更加精简,但外在区别只有函数名,打开正点原子的示例代码就可以对照修改,所以就不介绍标准库了。

现在的STM32开发一般有两种,一种是用CubeMX软件另一种是调库,调库显然更麻烦,但是有些历史项目是调库的或者团队负责人更喜欢调库模式,所以这两种开发方式都得会,这两种开发方式只有在初始化外设时会有不同,所以写初始化代码时就可以先用CubeMX软件生成对应代码然后复制粘贴到项目。

STM32外设很多,各配置项比较复杂,而各种文档内容很多但平时查起来很麻烦,所以本文将常用配置项的含意、函数的作用以及用途做一个汇总。

软件安装及其他教程 点击打开可查看专栏【STM32Cube开发方式】

新建项目的操作可以点击链接跳转到我的文章:STM32-keil+CubeMX快速开发【外设配置篇】:新建项目

外设通用套路

外设的函数原型可以在 "stm32xxx_hal_xxx.c" 文件中查看。

外设的结构体、中断标志等可以在 "stm32xxx_hal_xxx.h" 文件中查看。

外设初始化配置

先根据需求在CubeMX软件中配置外设和时钟,然后在对应外设的".c/.h"文件中可以看到类似下面伪代码的代码就是外设配置代码,CubeMX生成的系统时钟配置函数 "SystemClock_Config" 在 "main" 函数的后面)

伪代码如下,其中XXX和xxx表示某外设。

XXX_HandleTypeDef hxxx; // 结构体的定义在"stm32xxx_hal_xxx.h"中,在keil软件中全局搜索对应的 "XXX_InItTypeDef;"即可快速查看结构体成员的意义

/* 外设初始化函数 */

void XXX_Init(void)

{

// hxxx 结构体赋值,与MX软件中配置项相对应,此处省略

if (HAL_XXX_Init(&hxxx) != HAL_OK)

{

Error_Handler();

}

}

/* 此函数在HAL_XXX_Init(&hxxx)中被调用,用于时钟使能、引脚配置和中断优先级设置 */

void HAL_XXX_MspInit(XXX_HandleTypeDef* xxxHandle)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

if(xxxHandle->Instance==XXX)

{

/* 外设时钟使能 */

__HAL_RCC_XXX_CLK_ENABLE();

__HAL_RCC_GPIOX_CLK_ENABLE(); //外设引脚时钟使能

/* 引脚配置 */

// GPIO_InitStruct 结构体赋值

HAL_GPIO_Init(GPIOX, &GPIO_InitStruct);

/* 中断优先级配置 */

HAL_NVIC_SetPriority(XXX_IRQn, X, X);

HAL_NVIC_EnableIRQ(XXX_IRQn);

}

}

外设中断处理框架

CubeMX生成的全部中断处理函数都在 "stm32xxx_it.c" 文件中的最后部分,伪代码如下。

void XXX_IRQHandler(void)

{

HAL_XXX_IRQHandler(&hxxx);

}

各外设中断的回调函数名(Callback函数)可以在 "stm32xxx_hal_xxx.c"文件的代码生成日志中查看,以"stm32f4xxx_hal_tim.c"为例,如下所示。

各外设内容

中断与NVIC

流程

  1. 选择优先级策略
  2. 打开对应中断
  3. 配置优先级

中断常用HAL函数

下表中的"XXX"表示某外设

|-----------------------------------------|------------------------------------|
| 函数/宏函数 | 功能 |
| HAL_XXX_xxx_IRQHandler | 中断ISR中调用的通用处理函数 |
| HAL_XXX_xxx_Callback | 中断处理的回调函数,需要用户重新实现 |
| __HAL_XXX_ENABLE | 启用某个外设XXX |
| __HAL_XXX_DISABLE | 禁用某个外设XXX |
| __HAL_XXX_ENABLE_IT | 允许某个事件触发硬件中断 |
| __HAL_XXX_DISABLE_IT | 禁止某个事件触发硬件中断 |
| __HAL_XXX_GET_IT_SOURCE | 判断某个事件的中断是否开启,返回值为SET或RESET |
| __HAL_XXX_GET_FLAG | 判断某个事件的挂起标志位是否被置位,返回值为TRUE 或 FALSE |
| __HAL_XXX_CLEAR_FLAG __HAL_XXX_CLEAR_IT | 清除某个事件的挂起标志位 |

NVIC常用HAL函数

|------------------------------|---------------------|
| 函数名 | 功能 |
| HAL_NVIC_SetPriorityGrouping | 设置4位二进制数的优先级分组策略 |
| HAL_NVIC_SetPriority | 设置某个中断的抢占优先级和次优先级 |
| HAL_NVIC_EnableIRQ | 启用某个中断 |
| HAL_NVIC_DisableIRQ | 禁用某个中断 |
| HAL_NVIC_GetPriorityGrouping | 返回当前的优先级分组策略 |
| HAL_NVIC_GetPriority | 返回某个中断的抢占优先级、次优先级数值 |
| HAL_NVIC_GetPendingIRQ | 检查某个中断是否被挂起 |
| HAL_NVIC_SetPendingIRQ | 设置某个中断的挂起标志,表示发生了中断 |
| HAL_NVIC_ClearPendingIRQ | 清除某个中断的挂起标志 |

GPIO

流程

  1. 选择GPIO引脚选择模式
  2. 添加用户标签
  3. 配置默认输出电平、模式、上下拉、速度

各配置项的意义

GPIO output level:配置GPIO初始状态下的输出电平。

GPIO mode:进一步配置GPIO模式

output模式下可选择推挽输出或者开漏输出。

EXTI模式下可选择中断触发模式。

GPIO Pull-up/Pull-down:配置引脚上下拉模式。

Maximum speed:配置引脚的最大速度,配置项与速度值对应如下表。

|-----------|------------|
| LOW | 2MHz |
| MEDIUM | 12.5-50MHz |
| HIGH | 25-100MHZ |
| VERY_HIGH | 50-200MHZ |

User Lable:用户标签设置。

GPIO常用HAL函数

|--------------------|------------------------|
| 函数名 | 功能描述 |
| HAL_GPIO_Init | GPIO引脚初始化 |
| HAL_GPIO_DeInit | GPIO引脚反初始化,恢复为复位后的状态 |
| HAL_GPIO_WritePin | 使引脚输出0或1 |
| HAL_GPIO_ReadPin | 读取引脚的输入电平 |
| HAL_GPIO_TogglePin | 翻转引脚的输出 |
| HAL_GPIO_LockPin | 锁定引脚配置,而不是锁定引脚的输入或输出状态 |

定时器是MCU的关键功能,其功能多样、配置复杂,所以拆分成多个模式。

TIM基础定时模式

所有定时器都可实现此功能。

流程

  1. 选择定时器
  2. 选择定时器模式(基础定时器勾选"Activated",通用/高级定时器勾选/选择"Internal Clock")
  3. 单次定时模式需要勾选"One Pulse Mode"项
  4. 根据公式计算并配置;公式:定时时间 = (Prescaler+1)*(Counter Period+1)/(APB Timer clocks)
  5. 设置触发模式

所需配置项及意义

Prescaler :预分频器值,比实际值小1。

Counter Mode :计数模式,定时模式配置为UP即可。

Counter Period :计数周期,也就是重装载寄存器的值,比实际值小1。

auto-reload preload:自动重装载,如果需要在运行时修改定时时间并且需要等待此次定时完成后再修改"Counter Period "的值时,需要使能此项。

Trigger Event Selection:主模式下触发输出信号(TRGO)信号源选择。有3种选项:

  • Reset,定时器启动时触发中断且每次溢出后触发中断,使用定时器的复位信号作为TRGO输出;
  • Enable,定时器使能后触发一次中断,使用计数器的使能信号作为TRGO输出;
  • Update Event,仅在每次溢出后触发中断,使用定时器的溢出事件信号作为TRGO输出。

TIM常用HAL函数

|------------------------|---------------------------------------------------------|
| 函数名 | 功能描述 |
| HAL_TIM_Base_Init | 定时器初始化,设置各种参数和连续定时模式 |
| HAL TIM_OnePulse_Init | 将定时器配置为单次定时模式,需要先执行HAL_TIM_Base_Init |
| HAL_TIM_Base_MspInit | MSP弱函数,在HAL_TIM_BaseInitO里被调用,重新实现的这个函数一般用于定时器时钟使能和中断设置 |
| HAL TIM_Base_Start | 以轮询工作方式启动定时器,不会产生中断 |
| HAL TIM Base Stop | 停止轮询工作方式的定时器 |
| HAL_TIM_Base_Start_IT | 以中断工作方式启动定时器,发生UEV事件时产生中断 |
| HAL_TIM Base Stop_IT | 停止中断工作方式的定时器 |
| HAL TIM Base_Start_DMA | 以DMA工作方式启动定时器 |
| HAL_TIM_Base_Stop_DMA | 停止DMA工作方式的定时器 |
| HAL TIM Base_GetState | 获取基础定时器的当前状态 |
| HAL_TIM_ENABLE | 启用某个定时器 |
| HAL TIM DISABLE | 禁用某个定时器 |
| HAL TIM_GET_COUNTER | 在运行时读取定时器的当前计数值 |
| HAL TIM SET COUNTER | 在运行时设置定时器的计数值 |
| HAL_TIM_GET_AUTORELOAD | 在运行时读取自重载寄存器 |
| HAL_TIM_SET_AUTORELOAD | 在运行时设置自重载寄存器值 |
| HAL_TIM_SET_PRESCALER | 在运行时设置预分频系数 |

TIM的PWM输出模式

除基础定时器外都可实现此功能。

流程

TIM的输入比较模式

TIM的PWM输入、输入捕获模式

RTC

DMA

USART

IIC

CAN

相关推荐
FreakStudio2 小时前
硬件版【Cursor】?aily blockly IDE尝鲜封神,实战硬伤尽显
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
SmartRadio7 小时前
STM32WLE5 LoRa 射频匹配优化(V1.1 版)
stm32·单片机·嵌入式硬件·阻抗匹配
wearegogog1238 小时前
三电平SVPWM逆变器仿真指南
单片机·算法
笨笨饿8 小时前
74_SysTick滴答定时器中断
c语言·开发语言·人工智能·单片机·嵌入式硬件·算法·学习方法
chao1898449 小时前
基于 STM32 的 Modbus RTU 串口通讯程序
stm32·单片机·嵌入式硬件
fie88899 小时前
基于 STC15F104E 的 T12 白光烙铁控制器方案
stm32·单片机
yuan1999710 小时前
基于 STM32 的工程级扫地机器人方案
stm32·嵌入式硬件·机器人
绿竹-大地11 小时前
韦东山开发板imx6ull移植WS1-CBS-Kit
嵌入式硬件·wifi
qq_4112624211 小时前
wifi自适应
stm32·单片机·嵌入式硬件
洋九八11 小时前
STM32 (NVIC)中断
stm32·单片机·嵌入式硬件