标题: 秒表程序有问题了,求大神帮助 [打印本页]
作者: 259171 时间: 2018-5-14 10:53
标题: 秒表程序有问题了,求大神帮助
设计了一个三位数的秒表,通过按k3按键暂停计数。秒表计数正常,不知为何数码管平时不显示数字,按下K3后才会显示当时的秒数。不知什么原因,求大神解答。
代码如下:
#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;//连接译码器,选择点亮的数码管
sbit k3=P3^2;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~f
u16 s,n;
u8 sec,mb[7];
void Timer0Init()//使定时器0初始化的函数
{
TMOD|=0X01;//选择定时器0模式,工作方式为1,仅用TR0打开
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
TR0=1;//打开定时器
}
void delay(u16 i)//延时函数
{
while(i--);
}
void miaoDisplay()//数码管动态扫描,循环扫描显示三位秒表数字
{
u8 i;
for(i=4;i<7;i++)
{
switch(i) //位选,选择点亮的数码管
{
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第5位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第6位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第7位
}
P0=smgduan[mb[i]];//发送段码
delay(1); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void dingshi()//设置一个定时函数
{
while(n)
{
if(TF0==1)
{
TF0=0;
TH0=0XFC; //定时器赋初值,定时1ms
TL0=0X18;
s++;
}
if(k3==0)//检测到K3按下,n置零,跳出循环
{
delay(1000);
if(k3==0)
{
n=0;
break;
}
}
if(s==985) //到达1S时间
{
s=0;
sec++;
if(sec==600)sec=0; //到达600秒,重新开始计数
}
}
}
void miao()//显示秒数
{
dingshi();
mb[4]=sec%10; //显示个位
mb[5]=sec/10-(sec/100)*10; //显示十位
mb[6]=sec/100; //显示百位
miaoDisplay();
}
void main()
{
Timer0Init();
n=1;
while(1)
{
miao();
}
}
-
1.PNG
(23.34 KB, 下载次数: 62)
-
2.PNG
(65.87 KB, 下载次数: 54)
作者: zhdp 时间: 2018-5-14 15:02
改大delay(i);,时间太短频率高,显示不出
作者: 明白 时间: 2018-5-14 15:28
改大delay(i);,不能及时响应按键,建议按键采用外中断
作者: HC6800-ES-V2.0 时间: 2018-5-14 16:47
你的程序我简单看了一下,楼上的几位都没说到点子上。
问题在你的dingshi()子函数中。
你这个子函数中,有一个while(n),而n=1,那么,程序执行到此处,就“死”在这里了,死循环,直到你按下k3键,出现这条语句n=0;break;才能跳出来,才会有显示啊。
由于n=0了,所以,dingshi()子函数再也不执行了,所以,就没法看其它时间了。
秒表的按键,一定要用外部中断才行的,你的这个程序思路有点不对,所以我没有帮你改,改不了啊。
作者: wulin 时间: 2018-5-14 17:24
//上电待令,按键计时开始,再按计时停止,再按清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=0;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=1;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(); //显示程序
}
作者: HC6800-ES-V2.0 时间: 2018-5-15 08:25
程序没什么大问题。
不过我认为你的显示函数中,显示第5位与显示第7位应该对调一下吧。
不可能100ms显示在s之前,对不对
作者: wulin 时间: 2018-5-15 14:33
你没有看清楚,楼主的程序是在8位数码管的实验板上从左至右只使用第5、6、7三个数码管显示。
作者: 259171 时间: 2018-5-15 19:41
已解决问题,感谢各位大神的指导
作者: zl2168 时间: 2018-5-15 21:19
本帖最后由 zl2168 于 2018-5-15 21:21 编辑
实例93 99.9秒秒表
先Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。若需99.99秒,硬件电路增加一位595。软件程序增加0.01s(10ms)计数器,并修改相应计数显示程序。
作者: zl2168 时间: 2018-5-15 21:22
实例96 能预置初值的倒计时秒表
先Proteus仿真一下,确认有效。
以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |