一,独立按键注意一下几点
>按下的时候,电压被拉低,所以IO口要传低电平( 0x0 )
>按下的时候要消除抖动 ( 延时10ms ),在判断,是否还是低电平,再做业务处理
下面这段程序,就是通过一个独立按键连接到p1口,控制静态数码管的 一段 进行亮和灭的切换。
#include <reg52.h> sbit key_control = P1^0; sbit led = P0^0; typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } void key_press(){ if( key_control == 0x0 ) { delay( 1110 ); if( key_control == 0x0 ){ led = ~led; } while( !key_control ); } } void main (){ /* while( 1 ){ if( key_control == 0x0 ) { delay( 1110 ); //大概10ms if ( key_control == 0x0 ) { led = 1; } }else if( key_control == 0x1 ) { delay( 1110 ); if ( key_control == 0x1 ) { led = 0; } } } */ led = 0; while( 1 ) { key_press(); } }
二, 当按键比较多的时候,用矩阵按钮,因为如果不用矩阵按钮,一个独立按键需要一个IO口,浪费资源。
如: 16个独立按键需要16个io口, 而16个矩阵按键(4x4,一共8个管脚)需要8个IO口
下面的程序,通过16个矩阵按钮,控制静态数码管,显示0~F
#include <reg52.h> #define GPIO_DIG P0 //段选数码管 #define GPIO_KEY P1 //矩阵按键 typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } u8 key_value; //静态数码管段码 u8 character [16] = { 0xC0, 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92, 0x82 , 0xF8 , 0x80 , 0x90 , 0x88 , 0x83, 0xC6 , 0xA1 , 0x86 , 0x8E}; void key_down(){ u8 count = 0; //行列扫描 判断哪个键被按下 GPIO_KEY = 0x0F; //高四位全部输出低电平,低四位输出高电平-->判断被按下的按钮所在的列 if( GPIO_KEY != 0x0F ) { //有按键按下 delay( 1110 ); //消除抖动 if( GPIO_KEY != 0x0F ){ switch( GPIO_KEY ){ case 0x07: key_value = 0; //矩阵第1列的按钮被按下 break; case 0x0B: key_value = 1; //矩阵第2列的按钮被按下 break; case 0x0D: key_value = 2; //矩阵第3列的按钮被按下 break; case 0x0E: key_value = 3; //矩阵第4列的按钮被按下 break; } GPIO_KEY = 0xF0; //高四位输出高电平,低四位输出低电平-->判断被按下的按钮所在的行 switch( GPIO_KEY ){ case 0x70: key_value = key_value; //矩阵第1行的按钮被按下 break; case 0xB0: key_value = key_value + 4; //矩阵第2行的按钮被按下 break; case 0xD0: key_value = key_value + 8; //矩阵第3行的按钮被按下 break; case 0xE0: key_value = key_value + 12; //矩阵第4行的按钮被按下 break; } GPIO_DIG = character[key_value]; //如果一直按下按键,等待500ms,强制退出 while( ( count < 50 ) && ( GPIO_KEY != 0xF0 ) ) { count++; } } } } void main (){ while( 1 ) { key_down(); } }