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--); }