小白向单片机笔记四:按键
前言
独立按键和矩阵按键,原理及代码
一、按键原理
当按键按下时,从高电平到低电平,从低电平到高电平会产生电流抖动。抖动时延一般为5ms到10ms
开发板没有对按键进行硬件消抖处理,需要进行软件消抖(增加时延
)。
1. 独立按键原理
如原理图所示,C51芯片引脚默认输出高电平。当按键按下,该引脚即接地导通,即该引脚为低电平。即当检测到引脚为低电平,说明按键按下。
2. 矩阵按键原理
矩阵按键原理与独立按键相似。关键在于如何检测按下的键为哪一个。
其中一个方法:
- 先给所有行(P17-P14)输出低电平,检测所有列(P13-P10)中哪一列为低电平(
确定按键的列
)。 - 给所有列(P13-P10)输出低电平,检测所有行(P17-P14)中哪一行为低电平(
确定按键的行
)。
二、代码
1.独立按键实验代码
四个独立按键分别控制8个LED灯中的第一、二、三、四个LED的亮灭。
#include "reg52.h"
typedef unsigned int uint;
typedef unsigned char uchar;
sbit Button1=P3^1;//K1
sbit Button2=P3^0;//K2
sbit Button3=P3^2;//k3
sbit Button4=P3^3;//K4
sbit LED1 = P2^0;//LED1
sbit LED2 = P2^1;//LED2
sbit LED3 = P2^2;//LED3
sbit LED4 = P2^3;//LED4
void delay(uint i){
while(i--){}
}
void main(){
/*检测按键*/
while(1){
delay(10000);
if(!Button1) LED1=!LED1;
if(!Button2) LED2=!LED2;
if(!Button3) LED3=!LED3;
if(!Button4) LED4=!LED4;
delay(10000);
}
}
2.矩阵按键实验代码
矩阵按键扫描代码
#ifndef __SCAN_BUTTON_H__
#define __SCAN_BUTTON_H__
/*扫描矩阵按键*/
#include "reg52.h"
typedef unsigned int uint;
typedef unsigned char uchar;
sbit line0 = P1^7;
sbit line1 = P1^6;
sbit line2 = P1^5;
sbit line3 = P1^4;
sbit col0 = P1^3;
sbit col1 = P1^2;
sbit col2 = P1^1;
sbit col3 = P1^0;
uint Table16[4][4] = {{0x3f,0x06,0x5b,0x4f},
{0x66,0x6d,0x7d,0x07},
{0x7f,0x6f,0x77,0x7c},
{0x39,0x5e,0x79,0x71}
} ;
/*确定行*/
uint get_line(void){
uint retVal=4;
col0=0;
col1=0;
col2=0;
col3=0;
if(!line0) retVal=0;
if(!line1) retVal=1;
if(!line2) retVal=2;
if(!line3) retVal=3;
col0=1;//重置引脚默认输出
col1=1;
col2=1;
col3=1;
return retVal;
}
/*确定列*/
uint get_col(void){
uint retVal=4;
line0=0;
line1=0;
line2=0;
line3=0;
if(!col0) retVal=0;
if(!col1) retVal=1;
if(!col2) retVal=2;
if(!col3) retVal=3;
line0=1;
line1=1;
line2=1;
line3=1;
return retVal;
}
#endif
显示代码
#ifndef __DISPLAY_UTILS_H__
#define __DISPLAY_UTILS_H__
#include "reg52.h"
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
void choose_display(uint i){
switch(i){
case 0: P24=1;P23=1;P22=1;break;
case 1: P24=1;P23=1;P22=0;break;
case 2: P24=1;P23=0;P22=1;break;
case 3: P24=1;P23=0;P22=0;break;
case 4: P24=0;P23=1;P22=1;break;
case 5: P24=0;P23=1;P22=0;break;
case 6: P24=0;P23=0;P22=1;break;
case 7: P24=0;P23=0;P22=0;break;
}
}
#endif
实验一:主函数
按下按键矩阵中的按键,在第一个数码管显示
#include "Scan_Button.h"
#include " display_utils.h"
void delay(uint i){
while(i--){}
}
void main(){
while(1){
uint line=4;
uint col=4;
/*获取矩阵按键位置*/
delay(10000);
line = get_line();
col = get_col();
delay(10000);
if(line<4 && col<4){
P0= Table16[line][col];
}
}
}
实验二:主函数
按下字符后依次显示
#include "Scan_Button.h"
#include " display_utils.h"
void delay(uint i){
while(i--){}
}
void main(){
uint buffer[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
int index=0;
while(1){
uint line=4;
uint col=4;
uint i;
/*获取矩阵按键位置*/
delay(6000);
line = get_line();
col = get_col();
delay(6000);
if(line<4 && col<4){
if(index>7) index=0;
buffer[index++]= Table16[line][col];
}
for(i=0 ; i<8 ; ++i){
choose_display(i);
delay(100);
P0=buffer[i];
delay(100);
P0=0x00;
}
}
}
代码解释
1. 独立按键实验中if语句?
按键的作用为更改LED的状态,当按键按下,引脚为低电平(if语句中的条件),则更改LED状态,亮则熄灭,灭则点亮。
总结
实验二中矩阵按键检测和数码管显示的时延比较难调整,按键速度要快,不然容易检测到多个按键操作。