找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机设计秒表出现问题!

[复制链接]
跳转到指定楼层
楼主

这个问题怎么解决啊?
还有蜂鸣器不响
原定功能时,第三个按键按下时,蜂鸣器会每到一秒钟,响一下。
求解决
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:862128 发表于 2020-12-17 14:28 | 只看该作者
可看一下你的代码吗?
回复

使用道具 举报

板凳
ID:861592 发表于 2020-12-18 16:32 | 只看该作者
#include <reg51.h>

#define false 0
#define true 1
#define uchar unsigned char         //0——255
#define uint unsigned int                         //0——65535
#define ulong unsigned long        //0——4294967295

sbit start_key = P3^0;        //启动按钮
sbit pause_key = P3^1;        //暂停按钮
sbit reset_key = P3^2;        //重置按钮
sbit beep_key = P3^3;        //声音按钮

sbit start_led = P3^4;                //启动指示灯
sbit pause_led = P3^5;                //暂停指示灯
sbit beep_led = P3^6;                //喇叭指示灯
sbit beep = P3^7;                                //喇叭

uchar disCode[10] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //数码管段码 0~9
uchar locCode[8] = {0x01,0x02,0x04,0x08,0x10,0x20};                                        //位码

void displayTime(void);         //刷新时间显示
void disPlay(uchar num, uchar loc);         //数码管、led显示函数

void Delay1ms(unsigned int n);        //延时1ms

uchar state;        //状态:0-停止,1-启动,2-暂停
ulong ms = 0;        //存储毫秒值
uchar fen = 0;        //分钟数
uchar miao;        //秒数
uchar ms2;        //毫秒数的10位

bit isBeep = false;        //是否开启蜂鸣器

/*******************************************************************************
* 函 数 名          : T0_INT
* 函数功能         : T0定时器中断函数10ms
* 输      入         : 无
* 输      出         : 无
*******************************************************************************/
void T0_INT(void)  interrupt 1
{
        //这里不是减去10000是因为在C51单片机中,每执行一条语句需要花费 1ms 时间。减去的是误差值。
        //经过测试,大概每一分钟还是会有 0.8 s的误差……
        //实际的秒表还是得专业的时钟芯片
        TL0= (65536-9000)/256;       
        TH0= (65536-9000)%256;
        ms ++;
}

/*******************************************************************************
* 函 数 名          : main
* 函数功能         : 主函数
* 输      入         : 无
* 输      出         : 无
*******************************************************************************/  
void main(void)
{
        TMOD=0x61; //0110 0001        //方式一
       
        TL0= (65536-10000)/256;                // 10ms
        TH0= (65536-10000)%256;
        TR0=1;                //开启T0
        //ET0=1;                //T0中断允许(要在点击了启动按钮在开启,所以这里不需要开启)
       
        EA=1;        //总中断开启
       
        //以下指示灯一开始都应该是灭的
        start_led = 0;                //启动指示灯
        pause_led = 0;                //暂停指示灯
        beep_led = 0;                //喇叭指示灯
       
        while(1)
        {
                displayTime();         //刷新时间显示
                       
                //检测启动、停止按钮
                if(start_key == 0)         //按下了启动、停止按钮
                {
                        Delay1ms(10);        //延时消抖
                        if(start_key == 0)
                        {
                                if(state == 0)//之前是未启动,按了按钮要变成已启动
                                {
                                        state = 1;        //更新状态为已启动
                                        ms = 0;                //毫秒数归零
                                        fen = 0;        //分钟数归零
                                        ET0 = 1;                //T0中断允许打开,开始计时
                                        start_led = 1;        //启动led指示灯亮
                                }else{
                                        state = 0;                //更新状态为未启动
                                        ET0 = 0;                //关闭T0中断,停止计时
                                        start_led = 0;        //启动led指示灯灭
                                        pause_led = 0;        //暂停指示灯灭
                                }
                                   while(start_key == 0) displayTime();        //防止按键重复检测
                        }
                }
               
                //检测暂停按钮
                if(state != 0 && pause_key == 0)        //已启动计时,并且暂停按钮按下
                {
                        Delay1ms(10);        //延时消抖
                        if(pause_key == 0)
                        {
                                if(state == 2)        //之前是暂停,现在要启动
                                {
                                        state = 1;                //更新状态为已启动
                                        pause_led = 0;        //暂停指示灯灭
                                        ET0 = 1;                //打开T0中断允许,恢复计时
                                }else{
                                        state = 2;
                                        pause_led = 1;        //暂停指示灯亮起
                                        ET0 = 0;                //关闭T0定时器,暂停计时
                                }
                                   while(pause_key == 0) displayTime();        //防止按键重复检测
                        }
                }

                //检测归零按钮
                if(state == 0 && reset_key == 0)        //已停止计时,并且归零按钮按下
                {
                        Delay1ms(10);        //延时消抖
                        if(reset_key == 0)
                        {
                                ms = 0;                //毫秒数归零
                                fen = 0;        //分钟数归零
                                   while(reset_key == 0) displayTime();        //防止按键重复检测
                        }
                }
               
                //检测声音按钮
                if(beep_key == 0)        //归零按钮按下
                {
                        Delay1ms(10);        //延时消抖
                        if(beep_key == 0)
                        {
                                isBeep = ~isBeep;        //取反,原来是开启的,变为关闭。原来是关闭的则变为开启
                                beep_led = isBeep;        //更新声音指示灯
                                   while(beep_key == 0) displayTime();        //防止按键重复检测
                        }
                }
        }
}

void displayTime(void)         //刷新时间显示
{
        miao = ms/100 - fen*60;        //秒数
        ms2 = ms/10%10;        //毫秒数的10位
       
        //已启动计时,并且开启了声音     并且处于一秒刚开始的0.1秒内(即新的一秒刚刚开始)
        if(state == 1 && isBeep == true && ms2 < 1)
        {
                beep = 0;                //蜂鸣器发出响声
        }else{
                beep = 1;                //关闭蜂鸣器
        }
       
        if(miao >= 60)        //秒数大于60
        {
                miao = 0;
                fen++;                //分钟数加一
        }
       
        disPlay(fen/10, 0);                 //显示分钟数的十位
        disPlay(fen%10, 1);         //显示分钟数的个位
        disPlay(miao/10, 2);         //显示秒数的十位
        disPlay(miao%10, 3);         //显示秒数的个位
        disPlay(ms2, 4);                         //0.1s
        disPlay(ms%10, 5);         //0.01s
}

void disPlay(uchar num, uchar loc)         //数码管、led显示函数
{
        P0 = 0xff;        //消除重影
        P2 = locCode[loc];        //位码输出
        P0 = disCode[num];        //段码输出
        Delay1ms(1);        //增加显示时间,防止显示过暗
}

/*******************************************************************************
* 函 数 名          : Delay1ms (多个)
* 函数功能         : 延时函数,延时n*1ms
* 输      入         : n-延时次数
* 输      出         : 无
*******************************************************************************/  
void Delay1ms(unsigned int n)
{
        unsigned char i, j;       
        for (; n>0; n--)
                for(i=0;i<10;i++)
                        for(j=0;j<33;j++);       
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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