【STM32按键开发】

本文详细介绍了如何使用STM32CubeMX和Keil5开发STM32按键控制LED灯的应用,涵盖按键原理、GPIO配置、中断驱动、源码解析和实训案例,适合物联网技术学习者。
摘要由CSDN通过智能技术生成

提示:此文章适用 物联网技术应用与维护 技能大赛参考


前言

提示:芯片类型为:STM32L151C8T6(物联网技能大赛开发板):

本章节介绍STM32 MCU的GPIO的配置原理及应用开发,GPIO中断驱动原理的基本应用开发。


提示:以下是本篇文章正文内容,下面案例可供参考

一、案例介绍:按键控制LED灯开关

利用STM32CubeMX和Keil5协同开发, 完成以下的功能:
【1】按下KEY2按键,切换LED1的开关状态。
【2】按下KEY3按键,松开后,切换LED2的开关状态。
【3】按下KEY4按键,把点亮的LED灯全部关闭。

二、学习目录

1.按键控制原理

按键信号是如何识别的?
  一般来言,按键的两个引脚的一端通过电阻上拉到高电平,另一端则接地。按键通过判断高低电平的输入输出判断按键是否触发。
  然而按键高低电平的产生不一定肯定是按键的触发产生的,是干扰信号,因此检测到按键输入引脚有低电平后,需要稍作10ms左右的延时,再次读取该引脚,确认为按键触发信号,还是为干扰信号,不予处理。

2.电路原理图

key2
key2 连接STM32 GPIOC,GPIO_PIN_13
key3
key3 连接STM32 GPIOB,GPIO_PIN_1
key4
key3 连接STM32 GPIOB,GPIO_PIN_5
LED1+LED2
LED1 连接STM32 GPIOA,GPIO_PIN_3
LED2 连接STM32 GPIOB,GPIO_PIN_8

3.GPIO基础知识

 GPIO:General Purpose Input & Output
 STM32芯片拥有GPIOA、GPIOB、GPIOC等七组端口,每组端口拥有Pin0、Pin1、Pin2等16个引脚
  STM32每个IO端口都可以自由编程,且必须按照32位字节被访问。
STM32的IO端口可以配置8种模式:

输入模式
模拟输入GPIO_Mode_AIN
浮空输入GPIO_Mode_IN_FLOATING
下拉输入GPIO_Mode_IPD
上拉输入GPIO_Mode_IPU
输出模式
开漏输出GPIO_Mode_Out_OD
推挽输出GPIO_Mode_Out_PP
复用开漏输出GPIO_Mode_AF_OD
复用推挽输出GPIO_Mode_AF_PP

4.配置外设

  双击STM32CubeMX图形化软件
软件
1.选择芯片类型为STM32L151,创建工程
2.我们在SYS中配置Debug为 Serial Write
SYS配置
3.在右侧芯片图形化界面中设置引脚功能。
MCU配置
按键是输入设备。此实验配置3个按键参数:

GPIO管脚管脚功能选择ModePull-Up/Pull-Downlabel
PC_13GPIO_InputInputPull-Downkey2
PB_1GPIO_InputInputPull-Downkey3
PB_5GPIO_InputInputPull-Downkey4

设置按键
设置模式

LED是输出设备。此实验配置2个LED参数:

GPIO管脚管脚功能选择ModePull-Up/Pull-DownMaximun output speedlabel
PA_3GPIO_OutputOutputPull-DownLowLED1
PB_8GPIO_OutputOutputPull-DownLowLED2

设置LED
设置模式
4.必须将工程名称、存储位置、开发环境设置
  工程名称不可以出现特殊符号、中文。(否则STM32CubeMX生成MDK会提示项目有问题)
工程名称
在这里插入图片描述

5.配置完成后,双击界面右上角"GENERATE CODE"生成工程代码

5.keil v5 GPIO初始化函数源码解析

  双击打开project.CSDN.uvprojx文件
目录
  首先进入(最好)编译工程项目
  在生成“gpio.c”文件中,STM32CubeMX为上面配置key2/key3/key4,LED1/LED2外设对应的引脚生成相应的初始化代码,“MX_GPIO_Init()”函数,如下:

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */  /GPIO端口时钟使能/
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */  /配置GPIO端口引脚的初始化输出电平/
  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */  /配置GPIO端口引脚的初始化输出电平/
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PtPin */  /配置GPIO端口输入引脚:key2/
  GPIO_InitStruct.Pin = key2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(key2_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */  /配置GPIO端口输出引脚:LED2/
  GPIO_InitStruct.Pin = LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : PBPin PBPin */  /配置GPIO端口输入引脚:key3、key2/
  GPIO_InitStruct.Pin = key3_Pin|key4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : PtPin */  /配置GPIO端口输入引脚:LED1/
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);

}

6.代码思维导图

思维导图

7.实训案例解析

void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define KEY2 HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)  //自定义外设名称
#define KEY3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KEY4 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5)

void Scan_Keys()
{
    if(KEY2 == GPIO_PIN_RESET)  //判断GPIO引脚状态
    {
        HAL_Delay(5);  //延迟5毫秒
        if(KEY2 == GPIO_PIN_RESET)  //判断GPIO引脚状态
        {
            HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_3);  //电平翻转
            while(KEY2 == GPIO_PIN_RESET);  //判断GPIO引脚状态
        }
    }
    if(KEY3 == RESET)  //判断GPIO引脚状态
    {
        HAL_Delay(5);  //延迟5毫秒
        if(KEY3 == RESET)  //判断GPIO引脚状态
        {
            while(KEY3 == RESET);  //判断GPIO引脚状态
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);  //电平翻转
        }
    }
    if(KEY4 == 0)  //判断GPIO引脚状态
    {
        HAL_Delay(5);  //延迟5毫秒
        if(KEY4 == 0)  //判断GPIO引脚状态
        {
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);  //GPIO电平输出
		    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);  //GPIO电平输出
            while(KEY2 == 0);  //判断GPIO引脚状态
        }
    }
}
/* USER CODE END 0 */

 while (1)
  {
    /* USER CODE END WHILE */
		Scan_Keys();
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

总结

STM32l151C8T6芯片:低电平点亮,高电平熄灭
高电平–GPIO_PIN_SET,低电平–GPIO_PIN_RESET。

GPIO输入电平读取HAL库函数

HAL_GPIO_ReadPin( GPIO_TypeDef* GPIOx,  uint16_t GPIO_Pin);

参数1:GPIOx,端口号,如:GPIOB,GPIOF。
参数2:GPIO_Pin,引脚号,如:GPIO_PIN_9,GPIO_PIN_12。
返回值:GPIO_PinState,引脚的电平状态。高电平--GPIO_PIN_SET,低电平--GPIO_PIN_RESET。

GPIO电平翻转HAL库函数

HAL_GPIO_TogglePin( GPIO_TypeDef* GPIOx,  uint16_t GPIO_Pin);
参数1:GPIOx,端口号,如:GPIOB,GPIOF。
参数2:GPIO_Pin,引脚号,如:GPIO_PIN_9,GPIO_PIN_12。

GPIO电平输出HAL库函数

HAL_GPIO_WritePin( GPIO_TypeDef* GPIOx,  uint16_t GPIO_Pin,GPIO_PinState PinState);

参数1:GPIOx,端口号,如:GPIOB,GPIOF。
参数2:GPIO_Pin,引脚号,如:GPIO_PIN_9,GPIO_PIN_12。
参数3:GPIO_PinState,引脚的电平状态。高电平--GPIO_PIN_SET,低电平--GPIO_PIN_RESET。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值