找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2264|回复: 9
打印 上一主题 下一主题
收起左侧

秒表程序有问题了,求大神帮助

[复制链接]
跳转到指定楼层
楼主
设计了一个三位数的秒表,通过按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, 下载次数: 60)

1.PNG

2.PNG (65.87 KB, 下载次数: 54)

2.PNG

评分

参与人数 2黑币 +15 收起 理由
ssvv + 5 共享资料的黑币奖励!
cciejs12345 + 10 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:319019 发表于 2018-5-14 15:02 | 只看该作者
改大delay(i);,时间太短频率高,显示不出
回复

使用道具 举报

板凳
ID:19715 发表于 2018-5-14 15:28 | 只看该作者
改大delay(i);,不能及时响应按键,建议按键采用外中断
回复

使用道具 举报

地板
ID:164602 发表于 2018-5-14 16:47 | 只看该作者
你的程序我简单看了一下,楼上的几位都没说到点子上。
问题在你的dingshi()子函数中。
你这个子函数中,有一个while(n),而n=1,那么,程序执行到此处,就“死”在这里了,死循环,直到你按下k3键,出现这条语句n=0;break;才能跳出来,才会有显示啊。
由于n=0了,所以,dingshi()子函数再也不执行了,所以,就没法看其它时间了。

秒表的按键,一定要用外部中断才行的,你的这个程序思路有点不对,所以我没有帮你改,改不了啊。
回复

使用道具 举报

5#
ID:213173 发表于 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();                                        //显示程序
}
回复

使用道具 举报

6#
ID:164602 发表于 2018-5-15 08:25 | 只看该作者
wulin 发表于 2018-5-14 17:24
//上电待令,按键计时开始,再按计时停止,再按清0,周而复始。
#include
#define uint unsigned int

程序没什么大问题。
不过我认为你的显示函数中,显示第5位与显示第7位应该对调一下吧。
不可能100ms显示在s之前,对不对
回复

使用道具 举报

7#
ID:213173 发表于 2018-5-15 14:33 | 只看该作者
HC6800-ES-V2.0 发表于 2018-5-15 08:25
程序没什么大问题。
不过我认为你的显示函数中,显示第5位与显示第7位应该对调一下吧。
不可能100ms显 ...

你没有看清楚,楼主的程序是在8位数码管的实验板上从左至右只使用第5、6、7三个数码管显示。
回复

使用道具 举报

8#
ID:328743 发表于 2018-5-15 19:41 | 只看该作者
已解决问题,感谢各位大神的指导
回复

使用道具 举报

9#
ID:111634 发表于 2018-5-15 21:19 | 只看该作者
本帖最后由 zl2168 于 2018-5-15 21:21 编辑

实例93  99.9秒秒表
Proteus仿真一下,确认有效。
实例95 99.9秒秒表.rar (38.86 KB, 下载次数: 4)

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。若需99.99秒,硬件电路增加一位595。软件程序增加0.01s10ms计数器,并修改相应计数显示程序。
回复

使用道具 举报

10#
ID:111634 发表于 2018-5-15 21:22 | 只看该作者
实例96  能预置初值的倒计时秒表
Proteus仿真一下,确认有效。
实例96 能设置初值的倒计时秒表.rar (40 KB, 下载次数: 2)

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,书中电路和程序设计有详细说明,电路与程序真实可靠可信可行,程序语句条条有注解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表