Ai8051 独立按键控制LED实验
Ai8051 独立按键控制LED实验一、实验目标用板载K1~K4独立按键控制对应LED1~LED4亮灭掌握按键消抖、按键扫描、IO口配置、模块化编程二、硬件电路原理图按键P3.2、P3.3、P3.4、P3.5低电平有效LEDP2.0、P2.1、P2.2、P2.3按键按下 → IO口为低电平0三、AiCube 配置步骤开启系统时钟主时钟内部高速 IRC系统时钟40MHz图形化IO配置按键端口P3.2~P3.5设为上拉输入LED端口P2.0~P2.3设为推挽输出勾选启用 P2、P3 端口四、完整代码逐行注释1. key.h按键头文件#ifndef_KEY_H// 防止头文件重复包含条件编译#define_KEY_H#includeconfig.h// 包含系统配置头文件Ai8051自动生成含IO/时钟定义// 按键引脚定义根据实际硬件修改此处为示例K1~K4对应P3.2~P3.5#defineKEY1P3_2// 定义KEY1为P3.2引脚#defineKEY2P3_3// 定义KEY2为P3.3引脚#defineKEY3P3_4// 定义KEY3为P3.4引脚#defineKEY4P3_5// 定义KEY4为P3.5引脚// 按键返回值宏定义增强代码可读性避免魔法数字#defineKEY1_PRESS1// KEY1按下返回1#defineKEY2_PRESS2// KEY2按下返回2#defineKEY3_PRESS3// KEY3按下返回3#defineKEY4_PRESS4// KEY4按下返回4// 按键扫描函数声明mode参数0单次扫描1连续扫描此处暂用0u8KEY_Scan(u8 mode);#endif// 结束条件编译2. key.c按键驱动#includekey.h/** * brief 按键扫描函数修复版单次触发双次消抖等待松开 * param mode0单次扫描按一次只触发一次1连续扫描 * retval 按键值1KEY12KEY23KEY34KEY40无按键 * note 增加“等待松开”“二次消抖”解决多次按才生效的问题 */u8KEY_Scan(u8 mode){staticu8 key_flag1;// 按键状态标记1未按下0已按下u8 key_val0;// 临时存储按键值// 只有按键未按下时才检测新的按键防止连触发if(key_flag1){// 第一步检测是否有按键按下低电平有效if(!KEY1||!KEY2||!KEY3||!KEY4){delay_ms(10);// 第一次消抖过滤按下时的机械抖动// 第二步二次确认按键确实按下避免误触发if(!KEY1)key_valKEY1_PRESS;elseif(!KEY2)key_valKEY2_PRESS;elseif(!KEY3)key_valKEY3_PRESS;elseif(!KEY4)key_valKEY4_PRESS;// 第三步如果检测到有效按键等待松开松开消抖if(key_val!0){key_flag0;// 标记按键已按下防止重复检测// 等待按键松开核心解决“多次按才生效”while(!KEY1||!KEY2||!KEY3||!KEY4);delay_ms(10);// 第二次消抖过滤松开时的机械抖动returnkey_val;// 返回有效按键值}}}// 第四步所有按键都松开后重置状态elseif(KEY1KEY2KEY3KEY4){key_flag1;// 重置标记允许下次检测}return0;// 无按键按下返回0}3. led.hLED头文件#ifndef_LED_H// 防止头文件重复包含#define_LED_H#includeconfig.h// 包含系统配置头文件// LED引脚定义根据实际硬件修改此处为示例LED1~LED4对应P2.0~P2.3#defineLED1P2_0// 定义LED1为P2.0引脚#defineLED2P2_1// 定义LED2为P2.1引脚#defineLED3P2_2// 定义LED3为P2.2引脚#defineLED4P2_3// 定义LED4为P2.3引脚#endif// 结束条件编译4. main.c主函数/******************************************* * 头文件包含 *******************************************/#includeconfig.h// 包含系统配置头文件由AiCube生成含时钟/IO初始化#includekey.h// 包含按键驱动头文件定义按键引脚和扫描函数#includeled.h// 包含LED驱动头文件定义LED引脚/******************************************* * 项目主函数 * 入口参数无 * 函数返回无 * 作用程序入口死循环执行按键扫描和LED控制 *******************************************/voidmain(void){u8 key_val0;// 定义变量存储按键返回值0无按键1~4对应KEY1~KEY4SYS_Init();// 系统初始化函数配置时钟、IO口模式等必须调用while(1)// 死循环单片机程序核心一直运行{// 按键扫描逻辑 // 调用按键扫描函数mode0 表示【单次扫描】// 效果按一次按键只触发一次必须松开后才能再次触发key_valKEY_Scan(0);// LED控制逻辑 // 根据key_val的值执行对应的LED动作switch(key_val){caseKEY1_PRESS:// 如果检测到KEY1按下LED1!LED1;// LED1状态翻转灭变亮亮变灭break;// 跳出switch防止case穿透caseKEY2_PRESS:// 如果检测到KEY2按下LED2!LED2;// LED2状态翻转break;caseKEY3_PRESS:// 如果检测到KEY3按下LED3!LED3;// LED3状态翻转break;caseKEY4_PRESS:// 如果检测到KEY4按下LED4!LED4;// LED4状态翻转break;default:// 默认分支无按键按下时不执行操作break;}// 主循环加短延时可选// 作用降低CPU占用避免程序跑飞不影响按键检测灵敏度delay_ms(5);}}五、关键注释说明静态变量key_flagstatic u8 key_flag 1;是单次扫描的核心静态变量只会初始化一次按键按下时设为0松开后重置为1避免“按一次触发多次”。消抖延时delay_ms(10)机械按键按下/松开时会有5~10ms的电平抖动必须加延时过滤否则会误判“没按键”或“多次按键”。!LED1翻转逻辑LED1 !LED1等价于LED1 (LED1 0) ? 1 : 0实现“按一下亮、再按灭”的效果。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2417094.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!