找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

定时器怎么不走了

[复制链接]
gaibian2017 发表于 2017-3-13 09:25:45 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define GPIO_DIG P0        //用P0口段选

sbit K1=P2^6;                //按键位声明
sbit K2=P2^7;

sbit LSA=P2^2;        //138译码器位声明
sbit LSB=P2^3;
sbit LSC=P2^4;

uchar code DIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};        //0、1、2、3、4、5、6、7、8、9的显示码

void xianshi();//声明时钟函数
void DigDisplay();//声明译码器动态函数
void dinshipeizhi(); //声明定时器配置函数
void Delay10ms(uint c);   //声明延时函数
uchar Key_Scan();        //声明按键检测函数
uchar DisplayData[8]; //存放要显示的8个值
uint time,ss,sg,fs,fg,ms,mg,i,j,k;       

void main()
{
        dinshipeizhi();//启动定时器
        while(1)
        {
                xianshi();//时钟显示               
        }
}

void xianshi()
{
        Key_Scan();        //检测按键是否按下
        if(time==20)        //定时中断一次为50ms,20次就是1s
        {
                ++mg;        //秒  个位自增一                                          
                time=0;
        }
        else
        {
                mg=mg;
        }
        if(mg>9)        //秒 个位大于9
        {
                mg=0;        //秒 个位归零
                ++ms;        //秒 十位自增1
        }
        else
        {
                ms=ms;
        }
        if(ms==6)        //秒十位等于6
        {
                ms=0;        //秒 十位归零
                ++fg;        //分 个位自增1
        }
        else
        {
                fg=fg+k;        //按键1按下,分 个位加1
                k=0;
        }
        if(fg>9)        //分 个位大于9
        {
                fg=0;        //分 个位归零
                ++fs;        //分 十位自增1
        }
        else
        {
                fs=fs;
        }
        if(fs==6)        //分 十位等于6
        {
                fs=0;        //分 十位归零
                ++sg;        //时 个位自增1
                ++i;                //计数,当记到12时,时十位归零
        }
        else
        {
                sg=sg+j;        //检测到按键2按下,时 个位加1
                i=i+j;        //时 个位加1,i也要加1
                j=0;
        }
        if(sg>9)        //时 个位大于9
        {
                sg=0;        //时 个位归零
                ++ss;        //时 十位自增1
        }
        else
        {
                ss=ss;
        }
        if(i>=12&&ss<2)        //i等于12,时 十位小于2
        {
                ss=0;        //时 十位归零
                sg=1;        //时 个位为一
                i=0;        //i归零
        }

        DisplayData[0] = DIG_CODE[ss];        //时
        DisplayData[1] = DIG_CODE[sg];                                 
        DisplayData[2] = 0x40;
        DisplayData[3] = DIG_CODE[fs];        //分
        DisplayData[4] = DIG_CODE[fg];       
        DisplayData[5] = 0x40;
        DisplayData[6] = DIG_CODE[ms];        //秒
        DisplayData[7] = DIG_CODE[mg];               
        DigDisplay();       
}

void DigDisplay()
{
        uchar a;
        uint b;
        for(a=0;a<8;a++)
        {
                switch(a)         //位选,选择点亮的数码管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//显示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//显示第1位
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;//显示第2位
                        case(3):
                                LSA=81;LSB=1;LSC=0; break;//显示第3位
                        case(4):
                                LSA=0;LSB=0;LSC=1; break;//显示第4位
                        case(5):
                                LSA=1;LSB=0;LSC=1; break;//显示第5位
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;//显示第6位
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;//显示第7位       
                }
                GPIO_DIG=DisplayData[a];//发送段码
                b=50;                                                 //扫描间隔时间设定
                while(b--);       
                GPIO_DIG=0x00;//消隐
                TR0=1;
        }
}

uchar Key_Scan()
{
        if (K1==0)                //检测按键K1是否按下
        {
                Delay10ms(4);        //消除抖动
                if (K1==0)        //再次检测按键是否按下
                {
                        j = 1;
                        if (K1==0)         //检测按键是否松开       
                        Delay10ms(4);        //消除抖动                               
                }
        }
       
                //--检测按键2--//
        if (K2==0)                //检测按键K1是否按下
        {
                Delay10ms(4);        //消除抖动
       
                if (K2==0)        //再次检测按键是否按下
                {
                        k = 1;
                        if (K2==0);         //检测按键是否松开
                                Delay10ms(4);        //消除抖动
                }
        }
        return j,k;   //将读取到键值的值返回
}
void dinshipeizhi()
{
        i=0;
        j=0;
        k=0;
        time=0;
        ss=0;
        sg=0;
        fs=0;
        fg=0;
        ms=0;
        mg=0;
        TMOD=0x01;//选择定时器0,工作方式为1
        TH0=0x3c;//高位设置初始值  50ms
        TL0=0xb0;//低位设置初始值
        EA=1;//        开总中断
        ET0=1;//开定时器0中断
        TR0=1;//启动定时器0
}

void Timer0() interrupt 1        //设置初始值为50ms,故中断执行一次就为50ms
{
        TH0=0x3c;//高位设置初始值  50ms
        TL0=0xb0;//低位设置初始值
        time++;        //执行一次中断自增1
}

void Delay10ms(uint c)   //误差 0us
{
    uchar a, b;

        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
        {
                for (b=38;b>0;b--)
                {
                        for (a=130;a>0;a--);
                }
           
        }      
}

        这是我自己编的时钟程序,最笨的方法,还可以用三个/10,%10,来做。
        现在有一个问题,我长按键后,秒那里不动了,是什么原因?是程序死在按键检测那里了吗?如果是这样数码管不应该灭掉吗?
我知道是按键松手消抖那里的问题,但我怎么改都没用,要么就达不到按一下记一次的效果,要么就是秒不跑了,求解!!!!!!
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-12-23 10:09 , Processed in 0.061678 second(s), 12 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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