51_按键_计数器
51计数器,下降沿
/**********************51单片机学习例程************************
* 平台:Keil U4 + STC89C52
* 名称:使用计数器0,每次按键触发,计数加一,数码管显示
* 编写:Tony
* 日期:2022-2-10
* QQ : 674749794
* 晶体:12MHZ
* 变更记录:无
******************************************************************/
#include <reg52.h>
#define GPIO_DIG P1 //数码管使用的段选IO
sbit K1=P3^6; //按键检测,测试用
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4; //138译码器,数码管的位选
#define GE {LSA=1;LSB=1;LSC=1;} //打开个位位选端
#define SHI {LSA=0;LSB=1;LSC=1;} //打开十位位选端
#define uchar unsigned char
uchar Key_Num;
uchar code DIG_CODE[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar num_ge,num_shi; //分别定义个位和十位的数组编号存储器
void timer0_init(void); //函数声明
void read_num(void);
void seg_display(unsigned char x,unsigned char y);
void Delay10ms();
void Read_Key();
/***************************************************
* 计数器0初始化子函数
* 计数模式,工作方式1,启动计数
****************************************************/
void timer0_init(void)
{
TMOD = 0x05; //计数模式,工作方式1 计数模式是计下降沿的个数,所以计数的按键必须有上拉电阻
TH0 = 0x00;
TL0 = 0x00; //计数单元从0开始
TR0 = 1; //启动计数器0
}
/***************************************************
* 取数子函数
* 读取TH0、TL0里面的值,确定个位和十位的数
****************************************************/
void read_num(void)
{
unsigned int count; //用来存储收到的负脉冲个数
count = TH0*256 + TL0; //计算负脉冲个数
if(count >99) //如果脉冲个数超过99
{
TH0 = 0x00; //从0重新开始
TL0 = 0x00;
count = 0;
}
num_ge = count%10; //计算个位数在数组中的编号
num_shi = count/10%10; //计算十位数在数组中的编号
}
void Read_Key()
{
uchar i;
if (K1==0)
{
Delay10ms();
if(K1==0)
{
Key_Num++;
if(Key_Num > 19)
{
Key_Num=0;
}
while((i<50)&&(K1==0))
{
Delay10ms();
i++;
}
i=0;
}
}
num_ge = Key_Num%10; //计算个位数在数组中的编号
num_shi = Key_Num/10%10;
}
/***************************************************
* 数码显示子函数
* 根据个位和十位的数字进行显示
****************************************************/
void seg_display(unsigned char x,unsigned char y)
{
unsigned int i; //延时用
GE; //打开个位位选
GPIO_DIG = DIG_CODE[y];
//GPIO_DIG = DIG_CODE[9]; //显示个位段选
for(i = 0;i<1000;i++); //延时一段时间
SHI; //打开十位位选
GPIO_DIG = DIG_CODE[x];
//GPIO_DIG = DIG_CODE[5]; //显示十位段选
for(i = 0;i<1000;i++); //延时一段时间
}
//主函数
void main(void)
{
GPIO_DIG = 0x00; //关闭数码管
timer0_init(); //定时器/计数器0初始化
while(1) //循环
{
read_num(); //读取个位和十位对应的数字
//Read_Key();
seg_display(num_shi,num_ge);//显示相应的数字
}
}
void Delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
浙公网安备 33010602011771号