当前位置: 首页 > article >正文

通过按键控制stm32最小系统板上LED的亮灭状态

 按键接在PA1引脚上,按下引脚电平被拉低

void Key_Init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    EXTI_InitTypeDef exti_initstruct;
    NVIC_InitTypeDef nvic_initstruct;

GPIO_InitTypeDef、EXTI_InitTypeDef、NVIC_InitTypeDef:这些是结构体类型,分别用于配置GPIO(通用输入输出)、EXTI(外部中断)和NVIC(嵌套向量中断控制器)。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd:用于使能APB2总线上的外设时钟。这里使能了GPIOA和AFIO(复用功能IO)的时钟。

    gpio_initstruct.GPIO_Mode = GPIO_Mode_IPU;
    gpio_initstruct.GPIO_Pin = GPIO_Pin_1;
    gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpio_initstruct);

gpio_initstruct.GPIO_Mode = GPIO_Mode_IPU:将GPIOA的第1引脚配置为输入模式,并且内部上拉(IPU:Input Pull-Up)。
gpio_initstruct.GPIO_Pin = GPIO_Pin_1:选择GPIOA的第1引脚。
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz:设置GPIO的速率为50MHz。
GPIO_Init(GPIOA, &gpio_initstruct):初始化GPIOA的第1引脚。

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);

GPIO_EXTILineConfig:将GPIOA的第1引脚与EXTI的第1线连接起来,使得该引脚的状态变化可以触发EXTI中断。

    exti_initstruct.EXTI_Line = EXTI_Line1;
    exti_initstruct.EXTI_Mode = EXTI_Mode_Interrupt;
    exti_initstruct.EXTI_Trigger = EXTI_Trigger_Falling;
    exti_initstruct.EXTI_LineCmd = ENABLE;
    EXTI_Init(&exti_initstruct);

exti_initstruct.EXTI_Line = EXTI_Line1:选择EXTI的第1线。
exti_initstruct.EXTI_Mode = EXTI_Mode_Interrupt:将EXTI配置为中断模式。
exti_initstruct.EXTI_Trigger = EXTI_Trigger_Falling:设置中断触发方式为下降沿触发(即按键从高电平变为低电平时触发中断)。
exti_initstruct.EXTI_LineCmd = ENABLE:使能EXTI线。
EXTI_Init(&exti_initstruct):初始化EXTI。

    nvic_initstruct.NVIC_IRQChannel = EXTI1_IRQn;
    nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 2;
    nvic_initstruct.NVIC_IRQChannelSubPriority = 2;
    nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic_initstruct);

nvic_initstruct.NVIC_IRQChannel = EXTI1_IRQn:选择EXTI1的中断通道。
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 2:设置抢占优先级为2。
nvic_initstruct.NVIC_IRQChannelSubPriority = 2:设置子优先级为2。
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE:使能EXTI1的中断通道。
NVIC_Init(&nvic_initstruct):初始化NVIC。

void EXTI1_IRQHandler(void)
{
    DelayMs(10);
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0)
    {
        if(led_info.Led_Status == LED_ON)
        {
            Led_Set(LED_OFF);
        }
        else
        {
            Led_Set(LED_ON);
        }
    }
    EXTI_ClearITPendingBit(EXTI_Line1);
}

EXTI1_IRQHandler:这是EXTI1的中断服务函数,当EXTI1线检测到下降沿时,会进入这个函数。
DelayMs(10):延时10毫秒,用于按键消抖。
GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0:读取GPIOA的第1引脚的状态,如果为0(低电平),表示按键被按下。
if(led_info.Led_Status == LED_ON):检查LED的当前状态,如果LED是打开的,则关闭它;如果LED是关闭的,则打开它。
EXTI_ClearITPendingBit(EXTI_Line1):清除EXTI1的中断标志位,以便下次中断能够正常触发。

完整代码如下

//单片机头文件
#include "stm32f10x.h"

//硬件驱动
#include "key.h"
#include "delay.h"
#include "led.h"

/*
************************************************************
*	函数名称:	Led_Init
*
*	函数功能:	蜂鸣器初始化
*
*	入口参数:	无
*
*	返回参数:	无
*
*	说明:		
************************************************************
*/
void Key_Init(void)
{

	GPIO_InitTypeDef gpio_initstruct;
	
	EXTI_InitTypeDef exti_initstruct;
	
	NVIC_InitTypeDef nvic_initstruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//打开GPIOB的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);		//打开GPIOB的时钟
	
	gpio_initstruct.GPIO_Mode = GPIO_Mode_IPU;				//设置为输出
	gpio_initstruct.GPIO_Pin = GPIO_Pin_1;						//将初始化的Pin脚
	gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;				//可承载的最大频率
	
	GPIO_Init(GPIOA, &gpio_initstruct);							//初始化GPIO
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
	
	exti_initstruct.EXTI_Line = EXTI_Line1;
	exti_initstruct.EXTI_Mode = EXTI_Mode_Interrupt;
	exti_initstruct.EXTI_Trigger = EXTI_Trigger_Falling;
	exti_initstruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&exti_initstruct);
	
	nvic_initstruct.NVIC_IRQChannel =  EXTI1_IRQn;
	nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 2;
	nvic_initstruct.NVIC_IRQChannelSubPriority = 2;
	nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic_initstruct);
	
}

void EXTI1_IRQHandler(void)
{
	DelayMs(10);
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == 0)
	{
		if(led_info.Led_Status ==LED_ON)
		{
			Led_Set(LED_OFF);
		}
		else
		{
			Led_Set(LED_ON);
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line1);
}

#ifndef _KEY_H_
#define _KEY_H_

void Key_Init(void);

#endif

总结
1初始化GPIOA的第1引脚为输入模式,并配置为内部上拉。
2配置EXTI1线为下降沿触发中断。
3配置NVIC,使能EXTI1的中断通道。
4在中断服务函数中,检测按键是否按下,并根据LED的当前状态切换其开关状态。通过这种方式,按键的按下事件可以实时响应,并且通过延时消抖来避免误触发
 


http://www.kler.cn/a/610842.html

相关文章:

  • 全文 - MLIR Toy Tutorial Chapter 1: Toy Language and AST
  • CAT1模块 EC800M HTTP 使用后续记录
  • PSA方法计算器(PSA Method Calculator): 鼠标完美灵敏度测试网站
  • 【计算机网络】计算机网络协议、接口与服务全面解析——结合生活化案例与图文详解
  • Jmeter:常用线程组设置策略
  • Axure RP9.0 教程:左侧菜单列表导航 ( 点击父级菜单,子菜单自动收缩或展开)【响应式的菜单导航】
  • 基于人工智能的扫阅卷和数据分析服务需求文档
  • 基于Spring Boot的网上购物商城系统的设计与实现(LW+源码+讲解)
  • 一. 相机模组摆放原理
  • redux ,react-redux,redux-toolkit 简单总结
  • 前端使用WPS WebOffice 做在线文档预览与编辑
  • uniapp主题切换功能,适配H5、小程序
  • 用DrissionPage升级网易云音乐爬虫:更稳定高效地获取歌单音乐(附原码)
  • element-plus 的简单应用
  • 在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 MineCraft 服务器,并实现远程联机,详细教程
  • 【Linux】MAC帧
  • ngx_http_escape_location_name
  • 解决在客户端本地无法访问服务器http方式访问麦克风与摄像头的问题
  • 嵌入式八股RTOS与Linux---网络系统篇
  • 自动化框架的设计与实现