第 3 篇:按键——让单片机"听话"
前两篇都是单片机"输出"(控制 LED 亮灭)。这篇开始学"输入"——让单片机读取按键状态。
1. 按键电路
VCC(5V) │ 10kΩ(上拉电阻) │ ├── 接到 P3.2(单片机读取) │ 按键 │ GND 没按:P3.2 = 1(被上拉电阻拉到 5V) 按下:P3.2 = 0(直接接地)2. 按键消抖——必知必会
按键按下去的瞬间,金属触点会弹跳("哒哒哒"振动),导致单片机读到一连串 0 和 1。消抖 = 读到第一次变化后,等 20ms 再读一次。
sbit KEY=P3^2;unsignedcharkey_scan(void){if(KEY==0)// 检测到按下(低电平){delay(20);// 消抖:等 20msif(KEY==0)// 再次确认——真的按下了{while(KEY==0);// 等待松开return1;// 返回"按下"}}return0;// 没按}3. 按键控制 LED 开关
sbit LED=P1^0;sbit KEY=P3^2;voidmain(){LED=1;// 初始灭while(1){if(key_scan()){LED=~LED;// 取反:亮变灭,灭变亮}}}4. 按键切换流水灯模式
unsignedcharmode=0;// 当前模式voidmain(){while(1){if(key_scan()){mode++;if(mode>=3)mode=0;}switch(mode){case0:run_flow_left();break;// 单灯左移case1:run_pingpong();break;// 来回跑case2:run_all_blink();break;// 全闪}}}5. 按键状态机——检测短按、长按
unsignedcharkey_state=0;unsignedinthold_time=0;unsignedcharkey_process(void)// 调用间隔 1ms{if(KEY==0){hold_time++;if(hold_time==1000)// 按住 1 秒 → 长按returnKEY_LONG;}else{if(hold_time>20&&hold_time<1000){// 按过但不到 1 秒 → 短按hold_time=0;returnKEY_SHORT;}hold_time=0;}returnKEY_NONE;}6. 小结
- 按键必须消抖(延时 20ms 两次确认)
- 按键要等松开(while(KEY==0); 防止重复触发)
- 状态机可以区分短按和长按——这已经是产品级代码了
下一篇:数码管——学会"显示数字"
下一篇:数码管——学会"显示数字"