51单片机倒计时程序

这篇文章是为了昨天一位博主准备的,因为我结题了,十分抱歉,今天重发以下

img


这是代码要求,附上原理图

img

img

img

img


以下是我写的代码,功能没有完全实现:


#include<reg52.h>

#define KeyPort P3
typedef  unsigned char u8;
typedef  unsigned int  u16;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;

u8 minute,second;                                                                     //定义分秒
u8 count = 0;

bit UpdateTimeFlag;                                                                                                                                        //定义读时间标志

u8 code smg[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};                            // 显示段码值0~9

unsigned char TempData[8],Key_Num;

void delay(u8 i);
void display();                                                                                                                                        //数码管显示函数
void KeyScan();                                                                                                                                                //按键扫描
void Init_Timer0(void);//定时器初始化

void main (void)
{

    Init_Timer0();

    while (1) {
        KeyScan();
        if(count==1) {
            switch(Key_Num) {
            case 2:
                minute++;
                if(minute==60)minute=0;
                Key_Num=0;
                break;
            case 3:
                minute--;
                if(minute==255)minute=59;
                Key_Num=0;
                break;
            default:
                break;
            }
        }
        if(count==2) {
            switch(Key_Num) {
            case 2:
                second++;
                if(second==60)second=0;
                Key_Num=0;
                break;
            case 3:
                second--;
                if(second==255)second=59;
                Key_Num=0;
                break;
            default:
                break;
            }
        }

        TempData[0]=smg[minute/10];//分
        TempData[1]=smg[minute%10];
        TempData[2]=smg[second/10];//秒
        TempData[3]=smg[second%10];
        display();
    }
}

void delay(u8 i) {
    while(i--);
}


void display()
{
    u8 i=0;
    for(i=0; i<8; i++)
    {
        switch(i)     //位选,选择点亮的数码管,
        {
        case(7):
            LSA=0;
            LSB=0;
            LSC=0;
            break;//显示第0位
        case(6):
            LSA=1;
            LSB=0;
            LSC=0;
            break;//显示第1位
        case(5):
            LSA=0;
            LSB=1;
            LSC=0;
            break;//显示第2位
        case(4):
            LSA=1;
            LSB=1;
            LSC=0;
            break;//显示第3位
        case(3):
            LSA=0;
            LSB=0;
            LSC=1;
            break;//显示第4位
        case(2):
            LSA=1;
            LSB=0;
            LSC=1;
            break;//显示第5位
        case(1):
            LSA=0;
            LSB=1;
            LSC=1;
            break;//显示第6位
        case(0):
            LSA=1;
            LSB=1;
            LSC=1;
            break;//显示第7位
        }
        P0=TempData[i];                                                //发送段码
        delay(100);                                                     //间隔一段时间扫描
        P0=0x00;                                                            //消隐
        ///delay(1000);
    }
}

void Init_Timer0(void)
{
    TMOD |= 0x01;                                                          //使用模式1,16位定时器
    EA=1;                                                                //总中断打开
    ET0=1;                                                               //定时器中断打开
    TR0=1;                                                               //定时器开关打开
}

void Timer0_isr(void) interrupt 1
{
    static unsigned int num,i;
    u8 j;
    TH0=(65536-2000)/256;                            //赋值 2ms
    TL0=(65536-2000)%256;


    i++;
    if(i==10)                                             //20ms更新一次
    {
        i=0;
        UpdateTimeFlag=1;                            //更新时间志位置1
    }
    num++;
    if(num==500)                                        //1s
    {
        num=0;
        if(count==0) {
            if(minute!=0||second!=0) {
                if(minute!=0&&second==0) {
                                        second--;
                                    if(second==255){
                                        second=59;
                    minute--;
                                    }                    
                    second--;
                    j++;
                    if(j==60) {
                        j=0;
                        if(minute > 0) {
                            minute--;
                        }
                    }
                }
                if(minute==0&&second!=0) {
                    second--;
                }
                if(minute!=0&&second!=0) {
                    second--;
                    if(second==255) {
                        minute--;
                        second=59;
                    }
                                        second--;
                    j++;
                    if(j==60) {
                        if(minute > 0) {
                            minute--;
                        }
                    }

                }
            }

        }
    }
}

void KeyScan()
{

    if(k1==0)                                                                              //检测按键K1是否按下
    {
        delay(1000);                                                               //消除抖动 一般大约10ms
        if(k1==0)                                                                         //再次判断按键是否按下
        {
            Key_Num=1;
        }
        while(!k1);                                                                     //检测按键是否松开
        count++;
    }
    if(count==3)count=0;                                                        //复位操作数字
    if(k2==0)
    {
        delay(1000);
        if(k2==0)
        {
            Key_Num=2;
        }
        while(!k2);
    }

    if(k3==0)
    {
        delay(1000);
        if(k3==0)
        {
            Key_Num=3;
        }
        while(!k3);
    }

    if(k4==0)
    {
        delay(1000);
        if(k4==0)
        {
            Key_Num=4;
        }
        while(!k4);
    }
}


对应电路图245/138修改了程序,数码管选-CC不是-CA的仿真这点要注意,电路图左边是CC右边是CA。
#include "REG52.h"
unsigned char code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0,64,15,56}; //共阴0~F消隐减号
unsigned char Js=0, miao=34, fen=12;//中断计时 秒 分 时 毫秒
bit Mb=0;//12/24切换 秒表
sbit k0=P1^0;
sbit k1=P1^1;
sbit k2=P1^2;
sbit da=P2^2;
sbit db=P2^3;
sbit dc=P2^4;
void smxs(unsigned char mz, unsigned char w)
{
    unsigned char Xd=0;
    P0=0;
    P0=smgduan[mz];
    P2=w;
    while(++Xd);
}
void ZhongDuanSheZhi()
{
    TH0+=(65536-9216*5)/256;/*定时器赋初值,定时50ms触发中断,自动补偿方式*/
    TL0+=(65536-9216*5)%256; 
    TMOD=0X01;//16位定时器/计数器
    TR0=0; //启动定时器T0。
    ET0=1; //开启定时器
    EA=1; //全局中断开关
}
void main()
{
    unsigned char Xd=0,qh=0,ss=0;
    unsigned int shu=0;
    ZhongDuanSheZhi();
    while(1)
    {
        if(k0==0&&++Xd==0){if(++qh>2)qh=0;while(k0==0);}//
        if(qh==1)
        {
            if(++ss>100){smxs(fen/10,2);smxs(fen%10,6);}else{smxs(16,2);smxs(16,6);}
            if(k1==0&&++Xd==0){if(++fen>60)fen=0;while(k1==0);}//
            if(k2==0&&++Xd==0){if(--fen>60)fen=60;while(k2==0);}//
        }
        else if(qh==2)
        {
            if(++ss>100){smxs(miao/10,10);smxs(miao%10,14);}else{smxs(16,10);smxs(16,14);}
            if(k1==0&&++Xd==0){if(++miao>60)miao=0;while(k1==0);}//
            if(k2==0&&++Xd==0){if(--miao>60)miao=60;while(k2==0);}//
        }
        else
        {
            smxs(fen/10,2);smxs(fen%10,6);smxs(miao/10,10);smxs(miao%10,14);
            if(k1==0&&++Xd==0){TR0=~TR0;while(k1==0);}//
            if(k2==0&&++Xd==0){TR0=0;while(k2==0);}//
        }
        if(Js>=20)
        {
            Js=0;
            if(--miao>60&&fen>0)
            {
                miao=59;
                --fen;
            }
        }
    }
}
void ZhongDuan() interrupt 1
{
    ++Js;
    TH0+=0X4c;
    TL0+=0X00;        
}

img

你应该把位选display(),放到发送段码前边
display();
P0=TempData[i]; //发送段码
delay(100); //间隔一段时间扫描
P0=0x00;