大家好,又见面了,我是你们的朋友全栈君。
前言
上一节我们讲解了STM32CubeMX的基本使用和工程的配置,那么这一节我们正式来学习CubeMX配置STM32的各个外设功能了
今天我们会详细的带你学习STM32CubeMX配置外部中断,并且讲解HAL库的GPIO的各种函数,带你学习不一样的STM32
如果还没有配置过工程,请参看上一篇博客 《STM32CubeMX教程二–基本使用(新建工程点亮LED灯)》
那么话不多说,我们开始正式的讲解吧!
准备工作:
1、STM32开发板(我的是STM32F407ZE和STM32F103RC)
2、STM32CubeMx软件、 IDE: Keil软件
3、STM32F1xx/STM32F4xxHAL库
4、按键管脚 PA11 PB4
5 LED管脚 PC4 PC5 PB0 PB1
1新建工程
1.1New Project
- 1 搜索芯片型号
- 2选择芯片
- 3创建工程
1.2设置RCC
- 1 点击RCC
- 2高速时钟(HSE)选择外部晶振
- 3 软件自动配置管脚
1.3GPIO初始化
LED:4个GPIO_OUTPUT (输出模式)
按键:2个GPIO_EXITx(外部中断模式)
- 1 点击对应管脚
- 2 设置对应模式
GPIO的各种模式设置
- GPIO output level 引脚电平设置 高/低
- GPIO mode GPIO模式 推挽输出/开漏输出
- GPIO Pull-up/Pull-dowm 上拉下拉电阻 上拉电阻/下拉电阻/无上拉或下拉
- Maxinum output speed 引脚速度设置 低速/中速/高速
- User Label 用户标签 给引脚设置名称 如LED0
这里可以看出看和我们使用库函数的时候配置是一样的,但我们只需要动几下鼠标便可以完成操作,这正是STM32CubeMX的强大之处
GPIO_EXIT的6种模式
我们的按键选择下降沿触发
1.4设置NVIC(嵌套向量中断控制器)
- 1点击NVIC2 勾选EXIT Line
- 2 interrupt 和 EXIT Line[15:12] interrupt 使能中断
1.5时钟源设置
- 1选择外部时钟HSE 8MHz
- 2PLL锁相环倍频9倍
- 3系统时钟来源选择为PLL
- 4设置APB1分频器为 /2
32的时钟树框图 如果不懂的话请看《【STM32】系统时钟RCC详解(超详细,超全面)》
1.6项目文件设置
- 1 设置项目名称
- 2 设置存储路径
- 3 选择所用IDE
1.7创建工程文件
然后点击GENERATE CODE 创建工程
随后我们可以在stm32f1xx_it.c中看到我们所配置的中断服务函数 并且可以看到gpio的初始化分到了gpio.c里面
、
我们看到他有一个HAL_GPIO_EXTI_IRQHandler();函数
Go To Definition 查看一下函数代码
和我们库函数配置差不多,就是清除中断标志位,之后进入中断回调函数中
在HAL库中,中断运行结束后不会立刻退出,而是会先进入相对应的中断回调函数,处理该函数中的代码之后,才会退出中断,所以在HAL库中我们一般将中断需要处理代码放在中断回调函数中,
配置下载工具
新建的工程所有配置都是默认的 我们需要自行选择下载模式,勾选上下载后复位运行
所有自己编写的代码请放在/* USER CODE BEGIN XXX */ /* USER CODE END XXX */之间
这样我们修改工程的时候你自己写的代码就不会被删除
HAL库 GPIO函数库讲解
在正常使用中,除了STM32CubeMX配置之外,我们有时候还需要自己配置一些东西,学习并理解HAL库,也是我们必须要学习的一个地方
首先打开stm32f4xx_hal_gpio.h 发现一共定义有8个函数
代码语言:javascript复制void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
代码语言:javascript复制void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
功能: GPIO初始化
实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
代码语言:javascript复制void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
代码语言:javascript复制GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:读取引脚的电平状态、函数返回值为0或1
实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
代码语言:javascript复制void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
功能:引脚写0或1
实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);
代码语言:javascript复制void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
翻转引脚的电平状态
实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4); 常用在LED上
代码语言:javascript复制HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:锁住引脚电平,比如说一个管脚的当前状态是1,当这个管脚电平变化时保持锁定时的值。
实例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);
代码语言:javascript复制void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
功能: 外部中断服务函数,清除中断标志位
实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
代码语言:javascript复制void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
功能: 中断回调函数,可以理解为中断函数具体要响应的动作。
实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);
GPIO_InitTypeDef结构体定义
代码语言:javascript复制typedef struct
{
uint32_t Pin; /*!< 选择引脚
*/
uint32_t Mode; /*!< 设置引脚模式
*/
uint32_t Pull; /*!< 引脚是否上拉或下拉
*/
uint32_t Speed; /*!< 设置引脚速度
*/
} GPIO_InitTypeDef;
同时,不管是标准库还是HAL库,都是基于寄存器开发的,寄存器编程在哪个库都是适用的
GPIO的相关配置寄存器
STM32的每组GPIO口包括7个寄存器。也就是说,每个寄存器可以控制一组GPIO的16个GPIO口。这7个寄存器分别为:
GPIOx_CRL:端口配置低寄存器(32位) GPIOx_CRH:端口配置高寄存器(32位) GPIOx_IDR:端口输入寄存器(32位) GPIOx_ODR:端口输出寄存器(32位) GPIOx_BSRR:端口位设置/清除寄存器(32位) GPIOx_BRR:端口位清除寄存器(16位) GPIOx_LCKR:端口配置锁存寄存器(32位)
具体我们这里就不讲了,篇幅有限,可以到《STM32中文参考手册》中查看
关于GPIO的八种模式请参看 《STM32 GPIO八种模式及工作原理详解》
按键消抖:
代码语言:javascript复制/**
* 函数功能: 按键外部中断回调函数
* 输入参数: GPIO_Pin:中断引脚
* 返 回 值: 无
* 说 明: 无
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==KEY1_GPIO_PIN)
{
if(HAL_GPIO_ReadPin(KEY1_GPIO,KEY1_GPIO_PIN)==KEY1_DOWN_LEVEL)
{
BEEP_TOGGLE;
LED1_ON;
LED2_ON;
LED3_ON;
}
__HAL_GPIO_EXTI_CLEAR_IT(KEY1_GPIO_PIN);
}
else if(GPIO_Pin==KEY2_GPIO_PIN)
{
if(HAL_GPIO_ReadPin(KEY2_GPIO,KEY2_GPIO_PIN)==KEY2_DOWN_LEVEL)
{
BEEP_TOGGLE;
LED1_OFF;
LED2_OFF;
LED3_OFF;
}
__HAL_GPIO_EXTI_CLEAR_IT(KEY2_GPIO_PIN);
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/131988.html原文链接:https://javaforall.cn