设计常去的网站,全国物流网站有哪些平台,壁纸公司网站源码,深圳app搭建由于机械点的弹性作用#xff0c;按键开关在闭合时不会马上稳定的接通#xff0c;在断开时也不会一下子断开#xff0c;因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的#xff0c;一般为 5ms 到 10ms#xff0c;为了确保 CPU 对按键的…由于机械点的弹性作用按键开关在闭合时不会马上稳定的接通在断开时也不会一下子断开因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的一般为 5ms 到 10ms为了确保 CPU 对按键的一次闭合仅作一次处理必须进行消抖 普中开发板是采用软件消抖一般来说一个简单的按键消抖就是先读取按键的状态如果得到按键按下之后延时 10ms再次读取按键的状态如果按键还是按下状态那么说明按键已经按下。其中延时10ms 就是软件消抖处理
1、独立按键实验 P3.1控制K1 P3.0控制K2 P3.2控制K3 P3.3控制K4
软件去抖动方法
1先设置 IO 口为高电平由于开发板 IO 都有上拉电阻所以默认 IO 为高电平
2读取 IO 口电平确认是否有按键按下
3如有 IO 电平为低电平后延时几个毫秒
4再读取该 IO 电平如果仍然为低电平说明按键按下
5执行按键控制程序
要实现的功能是通过开发板上的独立按键K1控制D1指示灯亮灭 #include reg51.h typedef unsigned int u16; typedef unsigned char u8; void delay(u16 time){ while(time--); } //控制D1-D4指示灯 sbit LED1P2^0; sbit LED2P2^1; sbit LED3P2^2; sbit LED4P2^3; //使用宏定义的方法定义独立按键的键值 #define KEY1_PRESS 1 #define KEY2_PRESS 2 #define KEY3_PRESS 3 #define KEY4_PRESS 4 #define KEY_UNPRESS 0 //定义按键对应的管脚口 sbit KEY1P3^1; sbit KEY2P3^0; sbit KEY3P3^2; sbit KEY4P3^3; //封装一个函数按键返回一个键值 u8 key_scan(u16 mode){ //mode模式有0和1操作如果操作0单次扫描如果操作1连续扫描 //打一个标志 static u16 key1; if(mode1){ key1; } if(key1(KEY10||KEY20||KEY30||KEY40)){ //消抖处理需要延时5ms-10ms delay(1000); key0; //如果仍是按下信号稳定 if(KEY10){ return KEY1_PRESS; }else if(KEY20){ return KEY2_PRESS; }else if(KEY30){ return KEY3_PRESS; }else if(KEY40){ return KEY4_PRESS; } }else if(KEY11KEY21KEY31KEY41){ key1; return KEY_UNPRESS; } } void main(){ u8 key0; while(1){ keykey_scan(0); if(keyKEY1_PRESS){ LED1!LED1; delay(1000); //加一下延时可以验证单次扫描和连续扫描的情况 }else if(keyKEY2_PRESS){ LED2!LED2; }else if(keyKEY3_PRESS){ LED3!LED3; }else if(keyKEY4_PRESS){ LED4!LED4; } } } 2、矩阵按键实验 P1端控制矩阵键盘
P1.7连接矩阵键盘的第1行P1.6连接矩阵键盘的第2行P1.5连接矩阵键盘的第3行P1.4连接矩阵键盘的第4行
P1.3连接矩阵键盘的第1列P1.2连接矩阵键盘的第2列P1.1连接矩阵键盘的第3列P1.0连接矩阵键盘的第4列 0 0 0 0 0 0 0 0
--------------------------------------------------------------------------
P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 独立键盘有一端固定为低电平此种方式编程比较简单。 而矩阵键盘两端都与单片机 I/O 口相连因此在检测时需编程通过单片机 I/O 口送出低电平。
单片机 I/O 口送出低电平检测方法有多种最常用的是行列扫描和线翻转法 1行列扫描法先送一列为低电平其余几列全为高电平(此时我们确定了列数)然后立即轮流检测一次各行是否有低电平若检测到某一行为低电平(这时我们又确定了行数)则我们便可确认当前被按下的键是哪一行哪一列的 2线翻转法就是使所有行线为低电平时检测所有列线是否有低电平如果有就记录列线值然后再翻转使所有列线都为低电平检测所有行线的值由于有按键按下行线的值也会有变化记录行线的值。从而就可以检测到全部按键 2.1 行列扫描法
行列扫描法先送一列为低电平其余几列全为高电平(此时我们确定了列数)然后立即轮流检测一次各行是否有低电平若检测到某一行为低电平(这时我们又确定了行数)则我们便可确认当前被按下的键是哪一行哪一列的 #include reg51.h typedef unsigned int u16; typedef unsigned char u8; void delay(u16 time){ while(time--); } //使用宏定义定义矩阵按键的管脚 #define KEY_MATRIX_PORT P1 //数码管静态数码管操作 #define SMG_A_DP_PORT P0 //0-F u16 gmsg_code[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; u16 key_matrix_scan(){ //定义一个变量返回 u16 key_value0; //给第一列赋值0其余全为1 KEY_MATRIX_PORT0xf7; if(KEY_MATRIX_PORT!0xf7){ //消抖 delay(1000); //检测行 switch(KEY_MATRIX_PORT){ case 0x77: key_value1; break; case 0xb7: key_value5; break; case 0xd7: key_value9; break; case 0xe7: key_value13; break; } } //等待按键松开 while(KEY_MATRIX_PORT!0xf7); //给第二列赋值0其余全为1 KEY_MATRIX_PORT0xfb; if(KEY_MATRIX_PORT!0xfb){ //消抖 delay(1000); //检测行 switch(KEY_MATRIX_PORT){ case 0x7b: key_value2; break; case 0xbb: key_value6; break; case 0xdb: key_value10; break; case 0xeb: key_value14; break; } } //等待按键松开 while(KEY_MATRIX_PORT!0xfb); //给第三列赋值0其余全为1 KEY_MATRIX_PORT0xfd; if(KEY_MATRIX_PORT!0xfd){ //消抖 delay(1000); //检测行 switch(KEY_MATRIX_PORT){ case 0x7d: key_value3; break; case 0xbd: key_value7; break; case 0xdd: key_value11; break; case 0xed: key_value15; break; } } //等待按键松开 while(KEY_MATRIX_PORT!0xfd); //给第四列赋值0其余全为1 KEY_MATRIX_PORT0xfe; if(KEY_MATRIX_PORT!0xfe){ //消抖 delay(1000); //检测行 switch(KEY_MATRIX_PORT){ case 0x7e: key_value4; break; case 0xbe: key_value8; break; case 0xde: key_value12; break; case 0xee: key_value16; break; } } //等待按键松开 while(KEY_MATRIX_PORT!0xfe); //返回值 return key_value; } void main(){ u16 key0; while(1){ keykey_matrix_scan(); if(key!0){ SMG_A_DP_PORTgmsg_code[key-1]; } } } 2.2 线翻转法
线翻转法就是使所有行线为低电平时检测所有列线是否有低电平如果有就记录列线值然后再翻转使所有列线都为低电平检测所有行线的值由于有按键按下行线的值也会有变化记录行线的值。从而就可以检测到全部按键 #include reg51.h typedef unsigned int u16; typedef unsigned char u8; void delay(u16 time){ while(time--); } //使用宏定义定义矩阵按键的管脚 #define KEY_MATRIX_PORT P1 //数码管静态数码管操作 #define SMG_A_DP_PORT P0 //0-F u16 gmsg_code[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; u16 key_matrix_flip_scan(){ u16 key_value0; //使所有行线为低电平,列线为高电平 KEY_MATRIX_PORT0x0f; if(KEY_MATRIX_PORT!0x0f){ //消抖 delay(1000); if(KEY_MATRIX_PORT!0x0f){ //测试列,使所有行线为低电平,列线为高电平 KEY_MATRIX_PORT0x0f; switch(KEY_MATRIX_PORT){ case 0x07: key_value1; //暂时赋一个值 break; case 0x0b: key_value2; break; case 0x0d: key_value3; break; case 0x0e: key_value4; break; } //测试行,使所有列线为低电平,行线为高电平 KEY_MATRIX_PORT0xf0; switch(KEY_MATRIX_PORT){ case 0x70: key_valuekey_value; break; case 0xb0: key_valuekey_value4; break; case 0xd0: key_valuekey_value8; break; case 0xe0: key_valuekey_value12; break; } while(KEY_MATRIX_PORT!0xf0); }else{ key_value0; } return key_value; } } void main(){ u16 key0; while(1){ keykey_matrix_flip_scan(); if(key!0){ SMG_A_DP_PORTgmsg_code[key-1]; } } }