关于#单片机#的问题:显示7秒后切换显示日期,日期显示3秒后切换回时间显示

数码管显示时间(时分秒)。显示7秒后切换显示日期,日期显示3秒后切换回时间显示。可调节时间日期。增加按键,设置闹钟。时间到后,同闹钟响5秒钟关闭。改为LED灯亮5秒然后灭

不太清楚您的需求是否是需要实现代码,望采纳,谢谢

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <reg52.h>

sbit DIG_1 = P2^0;
sbit DIG_2 = P2^1;
sbit DIG_3 = P2^2;
sbit DIG_4 = P2^3;

unsigned char num[10] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x98
};

sbit SCLK = P3^6;
sbit RCLK = P3^5;
sbit DIO = P3^4;

sbit ALARM_LED = P1^0;

unsigned char hour = 0, minute = 0, second = 0;
unsigned char month = 0, day = 0, year = 0;
unsigned char alarm_h = 0, alarm_m = 0, alarm_on = 0;

void display(unsigned char, unsigned char, unsigned char, unsigned char);
void shift(unsigned char);
void set_time(unsigned char, unsigned char, unsigned char);
void set_date(unsigned char, unsigned char, unsigned char);
void get_time(unsigned char *, unsigned char *, unsigned char *);
void get_date(unsigned char *, unsigned char *, unsigned char *);
void set_alarm(unsigned char, unsigned char);
void check_alarm(void);

void main()
{
    TMOD = 0x01;
    TH0 = 0xFC;
    TL0 = 0x18;
    TR0 = 1;
    ET0 = 1;
    EA = 1;

    while (1)
    {
        display(hour, minute, second, 1);
        delay_ms(1000 * 7);
        display(month, day, year, 0);
        delay_ms(1000 * 3);
    }
}

void display(unsigned char a, unsigned char b, unsigned char c, unsigned char is_time)
{
    unsigned char i = 0;

    DIG_1 = 1;
    DIG_2 = 0;
    DIG_3 = 0;
    DIG_4 = 0;
    shift(num[a / 10]);
    delay_ms(1);
    shift(num[a % 10]);
    delay_ms(1);

    DIG_1 = 0;
    DIG_2 = 1;
    DIG_3 = 0;
    DIG_4 = 0;
    shift(num[b / 10]);
    delay_ms(1);
    shift(num[b % 10]);
    delay_ms(1);

    if (is_time == 1) {
        DIG_1 = 0;
        DIG_2 = 0;
        DIG_3 = 1;
        DIG_4 = 0;
        shift(num[c / 10]);
        delay_ms(1);
        shift(num[c % 10]);
        delay_ms(1);
    } else {
        DIG_1 = 0;
        DIG_2 = 0;
        DIG_3 = 1;
        DIG_4 = 0;
        shift(num[a / 10]);
        delay_ms(1);
        shift(num[a % 10]);
        delay_ms(1);

        DIG_1 = 0;
        DIG_2 = 0;
        DIG_3 = 0;
        DIG_4 = 1;
        shift(num[b / 10]);
        delay_ms(1);
        shift(num[b % 10]);
        delay_ms(1);

        DIG_1 = 0;
        DIG_2 = 0;
        DIG_3 = 0;
        DIG_4 = 0;
        shift(num[c / 10]);
        delay_ms(1);
        shift(num[c % 10]);
        delay_ms(1);
    }
}

void shift(unsigned char dat)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        DIO = dat >> 7;
        dat <<= 1;
        SCLK = 0;
  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7776926
  • 你也可以参考下这篇文章:实现定时器定时 1 秒钟,LED 亮灭显示
  • 除此之外, 这篇博客: 单片机汇编语言:我的第一个汇编语言程序(汇编语言实现按键控制LED灯)中的 源码注释 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • MAIN1的功能是:将LED置一,就是熄灭发光二极管,然后跳转到MAIN
    MAIN的功能是:JB判断KEY是否为1。若KEY = 1(按键没有按下),跳转到MAIN1将发光二极管熄灭。若KEY ≠ 1(按键按下),CLR LED 将LED清零,点亮发光二极管。

  • 以下回答由chatgpt基于相关博客总结生成:

    针对该问题,可以使用51单片机进行控制,具体步骤如下:

    1.接线: 将数码管和单片机进行引脚连接,可以参考以下接线图:

    接线图

    2.编写程序: 使用 C 语言编写程序,通过计时器实现时分秒的计数,并通过数码管显示出来,同时设置一个定时器来控制在时间和日期之间的自动切换,并将日期显示 3 秒钟,然后再切换回时间。同时,按键可以被用来设置闹钟,并在响铃时点亮 LED 灯,持续 5 秒后自动熄灭。具体可以参考以下代码:

    #include<reg52.h>
    
    #define uchar unsigned char
    #define uint unsigned int
    
    uchar code table[] = {
        0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f
    };    //显示段码表
    
    uchar second, minute, hour, date, month, year, day=0, k;    //时间日期变量
    uchar i, j, num, s, dly, set_hour, set_minute, alarm_hour, alarm_minute, alarm_flg;
                                        //其它变量
    uchar code week[] = {'U', 'M', 'T', 'W', 'T', 'F', 'S'};
    sbit DSH=P1^4;    //数码管公共端接 P1^4
    sbit D8N=P2^0;    //驱动蜂鸣器声音的管脚
    sbit D6N=P2^1;    //控制LED灯亮的管脚
    
    void Delay1ms(uint cnt); //1ms 延时
    
    void Wheek(void)         //显示星期 
    {
        num = day % 7;
        P1 = 0x01;    // DSH=0 显示第1位数据:U M T W T F S
        P0 = table[week[num]];
        Delay1ms(1);
    }
    
    void ShowTime(void)    //显示时间  
    {
        P1 = 0x00;    // DSH=1 显示时
        P0 = table[hour/10];
        Delay1ms(1);
        P1 = 0x01;
        P0 = table[hour%10];
        Delay1ms(1);
        P1 = 0x02;    // DSH=2 显示分
        P0 = table[minute/10]+0x80;    //加上“点”
        Delay1ms(1);
        P1 = 0x03;
        P0 = table[minute%10];
        Delay1ms(1);
        P1 = 0x04;    // DSH=3 显示秒
        P0 = table[second/10]+0x80;    //加上“点”
        Delay1ms(1);
        P1 = 0x05;
        P0 = table[second%10];
        Delay1ms(1);
    }
    
    void ShowDate(void)    //显示日期
    {
        P1 = 0x02;    // DSH=2 显示月
        P0 = table[month/10]+0x80;    //加上“点”
        Delay1ms(1);
        P1 = 0x03;
        P0 = table[month%10];
        Delay1ms(1);
        P1 = 0x04;    // DSH=3 显示日
        P0 = table[date/10]+0x80;    //加上“点”
        Delay1ms(1);
        P1 = 0x05;
        P0 = table[date%10];
        Delay1ms(1);
    }
    
    void main(void)
    {
        EA=1;             //使能总中断
        ET0=1;            //使能定时器0中断
        TMOD=0X01;        //定时器0 16位定时器模式
        TH0=0XFC;         //1000000/12/500=1000,1ms 中断一次
        TL0=0X18;
        TR0=1;            //启动定时器0
        hour=0, minute=0, second=0, date=1, month=2, year=20, day=3;   //初始化时间
        dly=0;
        alarm_hour=0, alarm_minute=0, alarm_flg=0;   //初始化闹钟
        while(1)
        {
            if(dly)    //dly=1,显示日期
            {
                ShowDate();
                Wheek();
                Delay1ms(3000);    //日期显示3秒,同时dly 置为 0
                dly=0;
            }
            else    //dly=0,显示时间
            {
                ShowTime();
            }
            if(alarm_flg)    //存在闹铃设定
            {
                if(hour==alarm_hour && minute==alarm_minute && second<2)    //时分相同时,闹铃响起
                {
                    D6N=1;     //点亮LED 灯
                    D8N=0;    //打开蜂鸣器
                }
                if(hour==alarm_hour && minute==alarm_minute && second>=5)    //5 秒后关闭闹铃
                {
                    D8N=1;    //关闭蜂鸣器
                    D6N=0;    //关闭LED 灯
                    alarm_flg=0;    //取消闹铃设定
                }
            }
        }
    }
    
    void InterruptTimer0() interrupt 1 using 0    //定时器0 中断服务程序,1 ms 进入一次
    {
        TH0=0XFC;         //1000000/12/500=1000,1ms 中断一次
        TL0=0X18;
        s++;             //s 记录执行次数到 1000,即为 1s
        if(s>=1000)
        {
            s=0;
            second++;
            if (second>=60)
            {
                second=0;
                minute++;
                if (minute>=60)
                {
                    minute=0;
                    hour++;
                    if(hour>=24)
                    {
                        hour=0;
                        day++;
                        if(day>=7)
                        {
                            day=0;
                        }
                    }
                }
            }
        }
        k++;          //控制 dly 的变化,1s 后 dly 变为 1
        if(k>=1000)
        {
            k=0;
            dly=1;
        }
    }
    
    void Delay1ms(uint cnt)    //1ms 延时
    {
        uchar i;
        while(cnt--)
        {
            i=11;
            while (i--)
            {
                ;
            }
        }
    }
    

    3.增加按键控制功能: 要添加按键设置闹钟的功能,需要在程序中增加接受按键事件的代码,可以通过定时扫描按键来实现。当正确按下按键后,将记录的时间设置为闹钟时间,并将闹钟设定标志置位。具体可以参考以下代码:

    void ScanKey()    //扫描三个按键 
    {
        uchar flag1 = 0, flag2 = 0, flag3 = 0;    //falg1~flag3 记录三个按键的状态
        if(P3^0)
        {
            Delay1ms(10);                     //延迟去抖
            if(P3^0)
            {
                flag1 = 1;                     //记录按键状态为按下
            }
        }
        if(P3^1)
        {
            Delay1ms(10);                     //延迟去抖
            if(P3^1)
            {
                flag2 = 1;                     //记录按键状态为按下
            }
        }
        if(P3^2)
        {
            Delay1ms(10);                     //延迟去抖
            if(P3^2)
            {
                flag3 = 1;                     //记录按键状态为按下
            }
        }
        if(flag1)                              //按键S1 按下
        {
            alarm_hour=set_hour;             //记录闹钟设置时间
            alarm_minute=set_minute;
            alarm_flg=1;                     //置位闹钟设定标志
        }
        if(flag2)                              //按键S2 按下
        {
            hour=set_hour;                   //记录设置时间
            minute=set_minute;
        }
        if(flag3)                              //按键S3 按下
        {
            if(!dly)                         //只有在时间显示时才能设定时间
            {
                s=0;                         //清零 s,使显示实时更新
                k=500;                       //快速更新时间日期
                if(++set_minute>=60)         //设置当前时间加 1 分钟
                {
                    set_minute=0;
                    if(++set_hour>=24)
                    {
                        set_hour=0;
                    }
                }
            }
        }
    }
    

    4.增加 LED 灯控制功能: 要在闹铃响起时点亮 LED 灯并持续 5 秒,需要在程序中增加 LED 灯控制的代码。具体可以参考以下代码:

    if(alarm_flg)                               //存在闹铃设定
    {
        if(hour==alarm_hour && minute==alarm_minute && second<2)    //时分相同时,闹铃响起
        {
            D6N=1;                                 //LED 灯亮
            D8N=0;                                //蜂鸣器响
        }
        if(hour==alarm_hour && minute==alarm_minute && second>=5)    //5 秒后关闭闹铃
        {
            D8N=1;                                //蜂鸣器关闭
            D6N=0;                                //LED 灯熄灭
            alarm_flg=0;                         //取消闹铃设定
        }
    }
    

    综上所述,以上步骤即可实现单片机控制数码管显示时间并能自动切换显示日期的功能,同时可以加入按键设置闹钟和 LED 灯控制的功能。