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

news/2025/3/26 2:53:04/

 按键接在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);							//初始化GPIOGPIO_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.ppmy.cn/news/1582631.html

相关文章

Unity Shader编程】之透明物体渲染

以下是针对您提出的关于 Unity Shader 渲染 Pass 的查看方法、多个 Pass 的影响、Pass 的含义,以及 Unity 渲染物体的流程和处理多个透明/半透明/不透明物体的详细解答。 1. Unity Shader 渲染 Pass 的查看方法 查看 Pass 的方法 通过 Shader 代码: 打开…

第3章:Docker架构详解:从守护进程到镜像仓库

第3章:Docker架构详解:从守护进程到镜像仓库 作者:DogDog_Shuai 阅读时间:约25分钟 难度:中级 目录 第3章:Docker架构详解:从守护进程到镜像仓库 目录1. 引言2. Docker整体架构 2.1 架构图

海康工业摄像机rtmp推流和fastlio部署

作者: DWDROME 配置环境: OS: Ubuntu 20.04.6 LTS on Windows 11 x86_64Kernel: 5.15.167.4-microsoft-standard-WSL2ros-noetic wsl连接: 海康摄像机usb口: Connect USB devices powershell管理员下: inget install usbipd usb…

AI 赋能应急管理:ChatGPT、DeepSeek、Grok 的应用探索

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 随着人工智能(AI)技术的快速发展,大语言模型(LLM)在应急管理…

使用Python开发智能家居系统:基于语音命令的设备控制

友友们好! 我是Echo_Wish,我的的新专栏《Python进阶》以及《Python!实战!》正式启动啦!这是专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会…

开源AI大模型赋能私域流量:S2B2C场景下品牌文化建构的智能路径研究

摘要:在私域流量时代,品牌与用户的关系正在经历从单向传播到双向共生的范式转变。本文以星巴克、喜茶等典型案例为切入点,结合开源AI大模型的技术特性,探讨AI智能名片、S2B2C商城小程序源码等数字化工具如何重构品牌与用户对话的底…

前后端+数据库的项目实战:hbu迎新网-较复杂(上)

目录 一、准备工作 二、创建数据库 三、前端htmlcss搭建好 四、把数据库的信息显示到页面-实现查找全部操作 (1)写js文件进行交互 (2)创建服务器后端通过js与前端页面进行相响应 ​五、实现查找部分信息 (1&…

无阻塞UI:通过Web Worker提升用户体验的新途径

1.Web Worker 的定义 Web Worker 是浏览器提供的 JavaScript 多线程解决方案,允许在主线程之外运行脚本,执行耗时任务而不阻塞用户界面, 适用于处理耗时任务,避免阻塞主线程,提升用户体验。通过 postMessage 和 onmessage 实现主…