ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

STM32 04 按键控制LED

STM32 04 按键控制LED 一、学习背景与进阶目标在之前的学习中我们已经掌握了如何点亮 LED 和驱动蜂鸣器但代码都集中在 main.c 中。随着功能增加主函数会变得臃肿难读。本实验的目标是实现“按键控制 LED”更重要的是学习代码的模块化封装。我们将把 LED 初始化和按键检测的逻辑分别封装到独立的 .c 和 .h 文件中让 main.c 只负责核心逻辑调度这是嵌入式开发中非常重要的工程化思维。二、硬件连接说明LED 模块通常连接在 GPIO 输出引脚如 PB1、PB2低电平点亮按键模块连接在 GPIO 输入引脚如 PB3、PB4按下时接地低电平原理简述通过读取按键引脚的电平变化判断用户操作进而翻转对应 LED 的状态。三、代码块main主函数#includestm32f10x.h// Device header#includedelay.h#includeLED.h#includeKey.hintmain(){uint8_tnumber;LED__init();Key__init();while(1){numberKey_GetNum();if(number1){LED1_turn();}if(number2){LED2_turn();}}}LED.c#includestm32f10x.h// Device headervoidLED__init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct1;GPIO_InitStruct1.GPIO_ModeGPIO_Mode_Out_PP;GPIO_InitStruct1.GPIO_PinGPIO_Pin_1|GPIO_Pin_2;GPIO_InitStruct1.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStruct1);GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);}voidLED1_on(void){GPIO_ResetBits(GPIOA,GPIO_Pin_1);}voidLED1_off(void){GPIO_SetBits(GPIOA,GPIO_Pin_1);}voidLED2_on(void){GPIO_ResetBits(GPIOA,GPIO_Pin_2);}voidLED2_off(void){GPIO_SetBits(GPIOA,GPIO_Pin_2);}voidLED1_turn(void){if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)0){GPIO_SetBits(GPIOA,GPIO_Pin_1);}else{GPIO_ResetBits(GPIOA,GPIO_Pin_1);}}voidLED2_turn(void){if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)0){GPIO_SetBits(GPIOA,GPIO_Pin_2);}else{GPIO_ResetBits(GPIOA,GPIO_Pin_2);}}Key.c#includestm32f10x.h// Device header#includeDelay.hvoidKey__init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStruct2;GPIO_InitStruct2.GPIO_ModeGPIO_Mode_IPU;GPIO_InitStruct2.GPIO_PinGPIO_Pin_1|GPIO_Pin_11;GPIO_InitStruct2.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStruct2);GPIO_SetBits(GPIOB,GPIO_Pin_1|GPIO_Pin_11);}uint8_tKey_GetNum(void){uint16_tKeyNum0;if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)0){Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)0);Delay_ms(20);KeyNum1;}if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)0){Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)0);Delay_ms(20);KeyNum2;}returnKeyNum;}四、个人学习心得与踩坑记录作为一个刚入门 STM32 的初学者这次尝试模块化编程让我既兴奋又有点“头大”。虽然代码跑通了但在编写过程中也遇到了一些小插曲这里如实记录下来希望能给同样在摸索的朋友一点参考关于文件包含的困惑刚开始我把 LED.c 和 Key.c 建好了但在 main.c 里编译总是报错“未定义”。后来查资料才知道光有 .c 文件不行还得写对应的 .h 头文件来声明函数并且在工程目录里要把这些文件都添加进去。这一步卡了我好久但也让我明白了“声明”和“定义”分离的重要性。对“封装”的浅显理解以前我觉得把代码写在一个文件里挺方便的现在试着拆分后发现 main 函数确实清爽了很多。虽然目前只是简单的函数搬运但我隐约感觉到如果以后项目变大了这种“各司其职”的写法肯定能救命。按键消抖的疑惑目前的 Key_GetNum() 函数里我加了一点延时来做消抖但我不确定这是否是最高效的方法。如果有前辈看到这篇笔记欢迎在评论区指点一下有没有更优雅的消抖思路我会非常感激五、存在的不足与改进方向目前的程序虽然实现了“按键控制 LED”但我深知这只是最基础的入门水平代码里还有很多不成熟的地方阻塞式延时的局限现在的 Delay_ms 是死等这意味着在等待灯闪烁或者按键消抖的时候CPU 是什么都做不了的。我知道这在复杂项目里是大忌但目前我还不太会用定时器中断来替代它这是我接下来的重点攻克目标。代码的扩展性现在只有两个按键和两个 LED如果以后要控制 10 个灯怎么办难道要写 10 个 if 吗我听说可以用数组或者结构体来优化但这超出了我目前的知识范围只能先挖个坑等学会了再来填。缺乏异常处理如果按键坏了或者接触不良程序目前没有保护措施。
返回列表