/*
独立按键与定时器的使用
实验要求:
*1:按下S2,使数码管显示的数字+1
*2:按下S3,使数码管显示的数字-1;
*3:按下S4,数码管清0
*4:首次按下S5,数码管的数值定时1s加1;再次按下,数码管暂停递增,保持不变
*5:当数码管定时递增时,其他按键按下无反应
需要掌握的:定时器的使用,按键的按下检测以及消抖,多函数的写法
*/
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit we = P2^7;
sbit du = P2^6;
sbit S2 = P3^0;
sbit S3 = P3^1;
sbit S4 = P3^2;
sbit S5 = P3^3;
uint cnt; //全局变量,控制数码管显示的数字的变化
uchar code arry[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uint i);//软件延时函数
void display(); //数码管显示函数
void dingshi();//定时器函数
void key_scan();//扫描固定按键函数
void check(); //检测cnt值变化函数
void check()
{
if(cnt == 99)//如果cnt=99,重置0,否则对本实验而言就会有乱码
cnt = 0;
}
void delay(uint i)//软件延时函数
{
uint a,c;
for(a = i;a > 0;a--){
for(c = 114;c > 0;c--);
}
}
void display()
{
uint ge,shi;
ge = cnt % 10;
shi = cnt / 10;
P0 = 0xff; //消影
we = 1;
P0 = 0xfe;
we = 0;
du = 1;
P0 = arry[shi];
du = 0;
delay(5); //防止重影
P0 = 0xff;
we = 1;
P0 = 0xfd;
we = 0;
du = 1;
P0 = arry[ge];
du = 0;
delay(5);
}
void dingshi() //定时器函数,主要知道怎么给初值,怎么检测是否到1S。
{
uchar sec;
if(TF0 == 1){
TH0 = 0x4b;
TF0 = 0xfc;
TF0 = 0;
sec++;
}
if(sec == 20){
cnt++;
check();
sec = 0;
}
}
void key_scan() //扫描按键函数
{
if(TR0 == 0){//如果数码管正在自动递增中,按下S2,S3.S4默认不会改变数码管的值
if(S2 == 0){ //检测是否按下按键,按下的话会置0;
delay(5); //软件消抖,因为键盘按下的瞬间,电平信号会有抖动
if(S2 == 0){
cnt++; //如果按下S2,让cnt+1,因为cnt是全局变量,所以数码管也会实时更新
check();//检测是否到了99s
}
while(!S2); //松手检测
}
if(S3 == 0){
delay(5);
if(S3 == 0){
cnt--; //按下S3,cnt减1
}
while(!S3);
}
if(S4 == 0){
delay(5);
if(S4 == 0){
cnt = 0; //按下S4,cnt置0
}while(!S4);
}
}
if(S5 == 0){
delay(5);
if(S5 == 0){
TR0 = ~TR0;//按下S5,TRO的状态就是取反上次TR0的状态,开始默认置0
while(!S5);
}
}
}
void main()//主函数
{
TMOD = 0x01;
TH0 = 0x4b;
TL0 = 0xfc;
while(1){
dingshi();
key_scan();
display();
}
}