根据电路图J21跳线帽要接在VCC与LE,否则74HC573打不开,段码送不了。 ![]() ![]() |
wulin 发表于 2019-1-4 11:21 多谢多谢 |
凛夏寒烟 发表于 2019-1-3 21:27 给你改写成单键操作8位24小时百分秒表,有详细注释,应该能看得懂,经仿真无误。 #include <AT89X52.H> #define number P0 #define wela P2 typedef unsigned int u16 ; typedef unsigned char u8 ; sbit key1=P3^0; //sbit key2=P3^1; //sbit wela_A=P2^2; //sbit wela_B=P2^3; //sbit wela_C=P2^4; u8 code smgduan[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 };//数码管转换表 u8 LedBuff[8];//数码管缓冲区 u8 Cntus=0,Cnt10ms=0,Cnt1s=0,Cnt1min=0,Cnthour=0; //中断计时变量 bit suspend=0; //暂停标志 void LedScan(); //显示程序声明 void keyscan(); //按键扫描程序声明 /***********按键扫描程序****************/ void keyscan() { static u8 count2=0,count1=0; //计数变量 static bit key_sign=0; //按键状态标志 if(key1==0) //检测输入如果为0 { count1++; //计数延时消抖 if((count1>=100)&&(key_sign==0))//检测按键如果为0 { key_sign=1; //按键状态标志置1,防止重复响应 count2++; if(count2>=3) count2=0; switch(count2) { case 0: Cntus=0; Cnt10ms=0; Cnt1s=0; Cnt1min=0; Cnthour=0; break;//清0 case 1: suspend=1; break;//计时 case 2: suspend=0; break;//暂停 } } } else { count1=0; //计数变量清0 key_sign=0; //按键状态标志清0 } } /***********定时器初始化程序****************/ void Timer0Init() //2500微秒@11.0592MHz { TMOD = 0x01; //设置定时器模式 TL0 = 0x00; //设置定时初值 TH0 = 0xF7; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 EA=1; //开总中断 ET0=1; //开定时器0中断 } void StopwatchDisplay()//数字分解 { LedBuff[0]=Cnthour/10; LedBuff[1]=Cnthour%10; LedBuff[2]=Cnt1min/10; LedBuff[3]=Cnt1min%10; LedBuff[4]=Cnt1s/10; LedBuff[5]=Cnt1s%10; LedBuff[6]=Cnt10ms/10; LedBuff[7]=Cnt10ms%10; } /***************主程序****************/ void main() { Timer0Init(); //定时器初始化 while(1) { keyscan(); //按键扫描 StopwatchDisplay(); } } /**************中断服务程序*****************/ void timer0() interrupt 1//2500微秒@11.0592MHz { TL0 = 0x00; //设置定时初值 TH0 = 0xF7; //设置定时初值 Cntus++; //中断变量Cntus自+1 if(Cntus>=4) //10ms { Cntus=0; //清0 if(suspend==1) //暂停/启动 Cnt10ms++; //毫秒计数 if(Cnt10ms>=100) { Cnt10ms=0; Cnt1s++; //秒计数 if(Cnt1s>=60) { Cnt1s=0; Cnt1min++; //分计数 if(Cnt1min>=60) { Cnt1min=0; Cnthour++; //时计数 if(Cnthour>=24) Cnthour=0; } } } } LedScan(); //显示程序 } void LedScan()//显示程序 { static u8 i=0; //计数变量 number=0x00; //消隐 wela=i<<2; //送位码 if((i%2==1)&&(i!=7))//送段码 number=smgduan[LedBuff]|0x80;//加点 else number=smgduan[LedBuff]; if(++i>=8) i=0; /* switch(i) { case 0: wela=i<<2; number=smgduan[LedBuff[0]];i++;break; case 1: wela=i<<2; number=smgduan[LedBuff[0]]|0x80;i++;break; case 2: wela=i<<2; number=smgduan[Cnt1min/10];it++;break; case 3: wela=i<<2; number=smgduan[Cnt1min%10]|0x80;i++;break; case 4: wela=i<<2; number=smgduan[Cnt1s/10];i++;break; case 5: wela=i<<2; number=smgduan[Cnt1s%10]|0x80;i++;break; case 6: wela=i<<2; number=smgduan[Cnt10ms/10];i++;break; case 7: wela=i<<2; number=smgduan[Cnt10ms%10];i=0;break; }*/ } |
HC6800-ES-V2.0 发表于 2019-1-2 08:23 而且复位之后无法重新启动,求帮助 |
HC6800-ES-V2.0 发表于 2019-1-2 08:23 我把程序改了下,可是按键时只有第一次按下有作用,有时复位键有作用,我怀疑是按键消抖作用需要时间太长,和扫描形成了时间差,您觉得是不是有这样的可能。普中的板子是会在长按按键一段时间后自动取消置高电平的吗?
|
一点看法吧——程序我还没有读通 第一:你照片上的右四位数码管的点亮的问题,不是什么数组初始化问题,是消隐问题 case(7): LSA=1;LSB=1;LSC=1; break;//显示第7位 } } P0 = LedBuff[i]; j=10; //扫描间隔时间设定 while(j--); P0=0x00;//消隐 我在你的显示函数中加点东西,就不亮了,就只有最左的数码管是亮的。 第二:看你的程序结构(虽然没全部读通),但你的显示和按键函数都放在中断里,是很不好的——一是让你的定时很不准确,二是显示和按键在不中断时不能执行——我有你同样的板子,按键根本没用,长按都不行,具体原因还没找到,但这个结构很不好,其实就是编程思路问题。 我这里有别人的一个程序,给你看看,功能是完整的哦——一键秒表 //上电待令,按键k3计时开始,再按计时停止,再按清0,再按开始,周而复始。 #include <reg51.h> #define uint unsigned int #define uchar unsigned char sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4;//连接译码器,选择点亮的数码管 sbit k3=P3^2;//外部中断按键 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; uchar Cntus=0,Cnt100ms,Cnt1s=0;//中断计时变量 bit zantin=0; //暂停标志 /***********定时器初始化程序****************/ void Timer0Init(void) //2500微秒@12.000MHz { TMOD= 0x01; //设置定时器模式 TL0 = 0x3C; //设置定时初值 TH0 = 0xF6; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 EA=1; //开总中断 ET0=1; //开定时器0中断 } /***********按键扫描程序****************/ void keyscan() { static uint count2=0,count1=0; //计数变量 static bit key_sign=0; //按键状态标志 if(k3==0) //检测输入如果为0 { count1++; //计数延时消抖 if((count1>=500)&&(key_sign==0))//检测按键如果为0 { key_sign=1; //按键状态标志置1,防止重复响应 count2++; if(count2>=3) count2=0; switch(count2) { case 0: Cntus=0; Cnt100ms=0; Cnt1s=0; break;//清0 case 1: zantin=1; break;//计时 case 2: zantin=0; break;//暂停 } } } else { count1=0; //计数变量清0 key_sign=0; //按键状态标志清0 } } void display()//显示程序 { static uchar i=0; P0=0x00;//消隐 switch(i) { case(0): LSA=0;LSB=1;LSC=1;P0=table[Cnt1s/10];i++; break;//显示第5位 case(1): LSA=1;LSB=0;LSC=1;P0=table[Cnt1s%10]|0x80;i++; break;//显示第6位 case(2): LSA=0;LSB=0;LSC=1;P0=table[Cnt100ms];i=0; break;//显示第7位 } } /***************主程序****************/ void main() { Timer0Init(); //定时器初始化 while(1) { keyscan(); //按键扫描 } } /**************中断服务程序*****************/ void timer0() interrupt 1//2500微秒@11.0592MHz { TL0 = 0x00; //设置定时初值 TH0 = 0xF7; //设置定时初值 Cntus++; //中断变量Cntus自+1 if(Cntus>=40) //10ms { Cntus=0; //清0 if(zantin==1) //暂停/启动 Cnt100ms++; //毫秒计数 if(Cnt100ms>=10) { Cnt100ms=0; Cnt1s++; //秒计数 if(Cnt1s>=60) Cnt1s=0; } } display(); //显示程序 } |