下一站是上岸 2022-06-25 08:11 采纳率: 66.7%
浏览 238
已结题

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);
    }
}


  • 写回答

2条回答 默认 最新

  • 智者知已应修善业 2022-06-25 11:17
    关注
    对应电路图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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月3日
  • 已采纳回答 6月25日
  • 创建了问题 6月25日

悬赏问题

  • ¥30 matlab appdesigner私有函数嵌套整合
  • ¥15 给我一个openharmony跑通webrtc实现视频会议的简单demo项目,sdk为12
  • ¥15 vb6.0使用jmail接收smtp邮件并另存附件到D盘
  • ¥30 vb net 使用 sendMessage 如何输入鼠标坐标
  • ¥15 关于freesurfer使用freeview可视化的问题
  • ¥100 谁能在荣耀自带系统MagicOS版本下,隐藏手机桌面图标?
  • ¥15 求SC-LIWC词典!
  • ¥20 有关esp8266连接阿里云
  • ¥15 C# 调用Bartender打印机打印
  • ¥15 我这个代码哪里有问题 acm 平台上显示错误 90%,我自己运行好像没什么问题