键盘是电子系统中人机对话的重要组成部分,是人向机器发出指令、输入信息的必须设备
键盘在单片机应用系统中是使用最广泛的一种数据输入设备。键盘是由多个按键组成的。
按键通常是一种常开型开关,常态下按键的两个触点处于断开状态,按下按键时它们才闭合。
以下是 轻触开关和轻触按键 图
通常键盘有编码键盘和非编码键盘两种。编码键盘通过硬件电路产生被按按键的键值码,这种键盘使用方便,所需程序简单,但硬件电路复杂,
如计算机的键盘,单片机则通常不采用编码键盘。
而软件编程来识别的称为非编码键盘,非编码键盘硬件电路简单。
在单片机组成的各种系统中,最常用的是非编码键盘。
非编码键盘分为独立键盘和矩阵键盘。
独立键盘特点:每个按键占用一个IO口,当按键数量较多时,IO口利用效率不高,但程序简单,适用于所需按键较少的场合。
矩阵键盘特点:电路连接复杂,但提高了IO口利用率,软件编程较复杂。适用于使用大量按键的场合。
按键一端与IO口连接,另外一端接地。通过控制IO口输出高电平即可检测按键是否按下,当按下时IO口会被拉低,松开后IO口回到高电平。
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
uchar num;//数码管显示的值
uchar count;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z){
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main()//main函数自身会循环
{
while(1)
{
if(key_s2 == 0)//判断S2是否被按下
{
delay(20);//按键消抖
if(key_s2 == 0)
{
if( count == 0){ // 当 count = 0 的时候 点亮LED1灯
P1 = 0XFE; // 点亮 LED1 灯
count = 1;
}else if(count == 1){ // 当 count = 1 的时候 关闭LED1灯
P1 = 0xff; // 关闭所有的LED 灯
count = 0;
}
}
while(!key_s2);//松手检测
}
}
}
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
uchar num;//数码管显示的值
uchar count;
uchar temp; // LED灯相关变量
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main() {//main函数自身会循环
if(count == 0){
temp = 0xfe;
P1 = temp; // 1111 1110
delay(100);
} else if(count == 1) {
P1 = 0xff;
}
while(1){
if(count == 0){
temp = _crol_(temp, 1); // 循环左移
P1 = temp;
delay(100);
} else if(count == 1) {
P1 = 0xff;
}
if(key_s2 == 0){//判断S2是否被按下
delay(20);//按键消抖
if(key_s2 == 0){
if( count == 0){
delay(100); // 延时 100毫秒 通过增加延时的时间或减少延时的时间,来控制流水灯的速度
count = 1;
}else if(count == 1){
P1 = 0xff; // 关闭所有的LED 灯
count = 0;
}
}
}
while(!key_s2);//松手检测
}
}
方法一:
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
sbit key_s4 = P3^2;//独立按键S2
uchar num1 = 0, num2 = 0;//数码管显示的值
uchar count = 0;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
}
void main()//main函数自身会循环
{
display(num1, num2); //数码管显示函数
while(1)
{
if(key_s3 == 0)//判断S2是否被按下
{
delay(20);//按键消抖
if(key_s3 == 0)
{
num2++;
if(num2 == 10){
num1 = 1;
num2 = 0;
count++;
} else if(count == 1){
num1 = 0;
num2 = 0;
count = 0;
display(num1, num2);
}
while(!key_s3);//松手检测
}
}
display(num1, num2);
}
}
方法二:
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s3 = P3^1;//独立按键S3
uchar display_num = 0; // 对数码管显示的数值初始化
uchar num1 = 0, num2 = 0;//数码管显示的值
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
}
void main()//main函数自身会循环
{
display(num1, num2); //数码管显示函数
while(1)
{
if(key_s3 == 0)//判断S2是否被按下
{
display_num++; // 每按一次独立按键,数码管显示的值加 1
delay(20);//按键消抖
if(key_s3 == 0)
{
switch(display_num){ // 通过 switch case 语句对 数码管的数值进行精准的管理
case 0 :
num1 = 0;
num2 = 0;
break;
case 1 :
num1 = 0;
num2 = 1;
break;
case 2 :
num1 = 0;
num2 = 2;
break;
case 3 :
num1 = 0;
num2 = 3;
break;
case 4 :
num1 = 0;
num2 = 4;
break;
case 5 :
num1 = 0;
num2 = 5;
break;
case 6 :
num1 = 0;
num2 = 6;
break;
case 7 :
num1 = 0;
num2 = 7;
break;
case 8 :
num1 = 0;
num2 = 8;
break;
case 9 :
num1 = 0;
num2 = 9;
break;
case 10 :
num1 = 1;
num2 = 0;
break;
default : // 当display_num数值大于10的时候,display_num 重新赋值0,不能使 display_num 大于 10
display_num = 0;
num1 = 0;
num2 = 0;
}
while(!key_s3);//松手检测
}
}
display(num1, num2);
}
}
方法一:
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
sbit key_s4 = P3^2;//独立按键S2
uchar num1 = 0, num2 = 0;//数码管显示的值
uchar count = 0;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
}
void main()//main函数自身会循环
{
display(num1, num2); //数码管显示函数
while(1)
{
if(key_s4 == 0)//判断S2是否被按下
{
delay(20);//按键消抖
if(key_s4 == 0)
{
if(count == 0){
num1 = 1;
num2 = 0;
count++;
} else if(count == 1){
num1 = 0;
num2 = 9;
count++;
} else if(count < 11){
num2--;
count++;
} else {
count = 0;
}
if(count == 0){
num1 = 1;
num2 = 0;
count++;
}
while(!key_s4);//松手检测
}
}
display(num1, num2);
}
}
方法二:
/*********************************************************************************
* 【作 者】: vvcat
* 【版 本】: V1.0
* 【外部晶振】: 11.0592mhz
* 【主控芯片】: STC89C52
* 【编译环境】: Keil μVisio4
* 【程序功能】: 独立按键识别
* 【使用说明】: 每次按动按键 S4,控制数码管显示数字减 1,当数码管数字变为 00 时, 按动按键 S4,会让数码管重新变为 10。
**********************************************************************************/
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s4 = P3^2;//独立按键S4
uchar display_num = 0; // 对数码管显示的数值初始化
uchar num1 = 0, num2 = 0;//数码管显示的值
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2)
{
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(1);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(1);
}
void main()//main函数自身会循环
{
display(num1, num2); //数码管显示函数
while(1)
{
if(key_s4 == 0)//判断S4是否被按下
{
display_num--; // 每按一次独立按键,数码管显示的值减去1
delay(20);//按键消抖
if(key_s4 == 0)
{
switch(display_num){ // 通过 switch case 语句对 数码管的数值进行精准的管理
case 0 :
num1 = 0;
num2 = 0;
break;
case 1 :
num1 = 0;
num2 = 1;
break;
case 2 :
num1 = 0;
num2 = 2;
break;
case 3 :
num1 = 0;
num2 = 3;
break;
case 4 :
num1 = 0;
num2 = 4;
break;
case 5 :
num1 = 0;
num2 = 5;
break;
case 6 :
num1 = 0;
num2 = 6;
break;
case 7 :
num1 = 0;
num2 = 7;
break;
case 8 :
num1 = 0;
num2 = 8;
break;
case 9 :
num1 = 0;
num2 = 9;
break;
case 10 :
num1 = 1;
num2 = 0;
break;
default : // 当display_num数值小于0的时候,display_num 重新赋值10,不能使 display_num 变为负数
display_num = 10;
num1 = 1;
num2 = 0;
}
while(!key_s4);//松手检测
}
}
display(num1, num2);
}
}
/*********************************************************************************
* 【作 者】: vvcat
* 【版 本】: V1.0
* 【外部晶振】: 11.0592mhz
* 【主控芯片】: STC89C52
* 【编译环境】: Keil μVisio4
* 【程序功能】: 独立按键识别
* 【使用说明】: 按下开发板左下角S3按键数码管值+1,最大到10
按下S4按下,值减一,最小减到0
按下s5复位
**********************************************************************************/
#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s3 = P3^1;//独立按键S3
sbit key_s4 = P3^2;//独立按键S4
sbit key_s5 = P3^3;//独立按键S5
uchar num1 = 0, num2 = 0;//数码管显示的值
uchar count = 0;
uchar count2 = 0;
//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
/*====================================
描述 :两位共阴数码管动态显示
====================================*/
void display(uchar num1, uchar num2){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num1];//
DU = 0;//锁存段选数据
delay(2);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = tabel[num2];//
DU = 0;//锁存段选数据
delay(2);
}
/*====================================
描述 :两位共阴数码管复位函数显示 0.0.
====================================*/
void restoration(){
/*第一位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = 0XBF;// 1011 1111
DU = 0;//锁存段选数据
delay(2);
/*第二位显示*/
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据
DU = 1;//打开段选锁存器
P0 = 0XBF;// 1011 1111
DU = 0;//锁存段选数据
delay(2);
}
void main()//main函数自身会循环
{
while(1){
if(count2 == 1){
restoration();
}else if(count2 == 0){
display(num1, num2); //数码管显示函数
}
if(key_s3 == 0)//判断S2是否被按下
{
count2 = 0; // 目的是为了调用 display(num1, num2); 数码管显示函数
count++;
delay(20);//按键消抖
switch(count){ // 通过 switch case 语句对 数码管的数值进行精准的管理
case 0 :
num1 = 0;
num2 = 0;
break;
case 1 :
num1 = 0;
num2 = 1;
break;
case 2 :
num1 = 0;
num2 = 2;
break;
case 3 :
num1 = 0;
num2 = 3;
break;
case 4 :
num1 = 0;
num2 = 4;
break;
case 5 :
num1 = 0;
num2 = 5;
break;
case 6 :
num1 = 0;
num2 = 6;
break;
case 7 :
num1 = 0;
num2 = 7;
break;
case 8 :
num1 = 0;
num2 = 8;
break;
case 9 :
num1 = 0;
num2 = 9;
break;
case 10 :
num1 = 1;
num2 = 0;
break;
default : // 当count数值大于10的时候,count 重新赋值0,不能使count 大于 10
count = 0;
num1 = 0;
num2 = 0;
}
while(!key_s3);//松手检测
display(num1, num2); // 调用函数显示数值
}
if(key_s4 == 0)//判断S4是否被按下
{
count2 = 0; // 目的是为了调用 display(num1, num2); 数码管显示函数
count--; // 每次按下 独立按键S4 数码管数值减一
delay(20);//按键消抖
if(key_s4 == 0)
{
switch(count){
case 0 :
num1 = 0;
num2 = 0;
break;
case 1 :
num1 = 0;
num2 = 1;
break;
case 2 :
num1 = 0;
num2 = 2;
break;
case 3 :
num1 = 0;
num2 = 3;
break;
case 4 :
num1 = 0;
num2 = 4;
break;
case 5 :
num1 = 0;
num2 = 5;
break;
case 6 :
num1 = 0;
num2 = 6;
break;
case 7 :
num1 = 0;
num2 = 7;
break;
case 8 :
num1 = 0;
num2 = 8;
break;
case 9 :
num1 = 0;
num2 = 9;
break;
case 10 :
num1 = 1;
num2 = 0;
break;
default : // 当count数值小于0的时候,count 重新赋值10,不能使count 变为负数
count = 10;
num1 = 1;
num2 = 0;
}
while(!key_s4);//松手检测
display(num1, num2);
}
}
if(key_s5 == 0)//判断S3是否被按下
{
delay(20);//按键消抖
if(key_s5 == 0)
{
count = 0; // 按下后count 初始化为0,数码管的值会从0开始重新计数
count2 = 1; // 目的是为了调用 restoration 数码管显示函数 显示0.0.
num1 = 0; // 将数码管第一位的值初始化为0
num2 = 0; // 将数码管第二位的值初始化为0
while(!key_s5); // s5松手检测
restoration(); // 目的是为了调用 restoration 数码管显示函数
}
}
}
}