51单片机时钟万历年闹钟

在万历年数字时钟设计中,当proteus仿真过程中,无法进行闹钟的设置,呈现出的结果是,仅能将闹钟时间设置为01:01;02:02;等等,时位和分位同增同减,不知道什么原因,能帮忙看下吗,可有偿。

img

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,需要确定原因。检查代码和电路设计是否有问题。如果代码和电路设计都没有问题,那么问题可能是Proteus仿真器的Bug。

以下是51单片机时钟万历年闹钟的示例代码(仅供参考):

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

sbit SPEAKER = P1^0;
sbit LED = P2^7;
sbit DSIO = P1^1;
sbit DSCLK = P1^2;
sbit RST = P1^3;

unsigned char second,minute,hour,day,month,year,week;   //时间变量
unsigned char BeepState = 0; //报警标志位
unsigned char AlarmHour=0,AlarmMin=0;//用于存放闹钟时间

//DS1302需要的IO口操作函数
void Write_Ds1302(unsigned char dat,unsigned char address)
{
    unsigned char i;

    RST = 0;                                 //拉低RST
    DSIO = 0;                                //确保先发送起始位
    DSCLK = 0;
    RST = 1;                                 //拉高RST
    for(i=0;i<8;i++)                         //循环发送字节
    {
        DSIO=dat&0x01;dat>>=1;                //先发送LSB
        DSCLK=1;
        DSCLK=0;
    }
    DSIO = address;                          //发送地址
    for(i=0;i<8;i++)                        //循环发送字节
    {
        DSIO=dat&0x01;dat>>=1;               //先发送LSB
        DSCLK=1;
        DSCLK=0;
    }
}

unsigned char Read_Ds1302(unsigned char address)
{
    unsigned char i,dat;

    RST=0;DSIO=0;DSCLK=0;
    RST=1;DSIO=1;DSCLK=1;
    for(i=0;i<8;i++)
    {
        DSIO=address&(0x01<<i);DSCLK=1;DSCLK=0;
    }
    for(i=0;i<8;i++)
    {
        dat>>=1;
        if(DSIO)
            dat|=0x80;
        DSCLK=1;DSCLK=0;
    }
    return dat;
}

//DS1302 RTC初始化函数
void Init_Ds1302()
{
    Write_Ds1302(0x8e,0x80); //控制字节,写保护禁止,允许写数据
    Write_Ds1302(0x00,0x84); //关闭写保护,使用24小时制

    Write_Ds1302(0x80,0x80); //秒归零
    Write_Ds1302(0x00,0x82);  //不使能外部晶振

    Write_Ds1302(0x90,0x80); //启用写保护
}

//DS1302 RTC读取时间函数
void Read_Time()
{
    year = Read_Ds1302(0x8d);     //年
    month = Read_Ds1302(0x89);   //月
    day = Read_Ds1302(0x87);      //日
    week = Read_Ds1302(0x8b);      //星期
    hour = Read_Ds1302(0x85);     //时
    minute = Read_Ds1302(0x83);  //分
    second = Read_Ds1302(0x81);  //秒

    Write_Ds1302(0x80,0x80);     //秒归零
}

//DS1302 RTC设置时间函数
void Set_Time()
{
    Write_Ds1302(0x8e,0x80);     //使用24小时制,打开写保护
    Write_Ds1302(year,0x8c);
    Write_Ds1302(month,0x88);
    Write_Ds1302(day,0x86);
    Write_Ds1302(hour,0x84);
    Write_Ds1302(minute,0x82);
    Write_Ds1302(week,0x8a);
    Write_Ds1302(0x90,0x80);     //使能写保护,关闭写保护功能
}

//闹钟函数
void Alarm()
{
    if(AlarmHour == hour && AlarmMin == minute)
    {
        BeepState = 1;
    }
}

//延时函数
void Delay(int ms)
{
    int i, j;
    for (i=0; i<ms; i++)
        for (j=0; j<1275; j++);
}

//数码管表
unsigned char code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//动态扫描数码管函数
void Display(unsigned char *str)
{
    unsigned char i,len;
    len = strlen(str);

    for (i=0; i<len; i++)
    {
        switch(i)
        {
            case 0:
                P2 = 0xfe;
                break;
            case 1:
                P2 = 0xfd;
                break;
            case 2:
                P2 = 0xfb;
                break;
            case 3:
                P2 = 0xf7;
                break;
            case 4:
                P2 = 0xef;
                break;
            case 5:
                P2 = 0xdf;
                break;
            default:
                break;
        }

        P0 = num[str[i] - 48];
        Delay(2);
        P0 = 0x00;
    }
}

//主函数
int main()
{
    Init_Ds1302();                  //RTC初始化
    Set_Time();                      //设置时间
    while(1)
    {
        Read_Time();                //读取时间
        Alarm();                         //闹钟判断
        if(BeepState == 1)           //声音报警
        {
            SPEAKER = ~SPEAKER;
            LED = ~LED;
            Delay(1000);
        }else
        {
            SPEAKER = 0;
            LED = 0;
        }

        sprintf(temp,"%02d%02d%02d",hour,minute,second);  //依次为时、分、秒
        Display(temp);                                                   //动态扫描数码管显示当前时间
    }
    return 0;
}

如果以上代码没有问题,请检查电路设计是否符合要求。另外,您可以在开发板上测试此代码,如果在开发板上也不能正常工作,则问题可能是代码本身的问题。
如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,根据你的描述,似乎闹钟无法设置到任意时间,而是只能设置到类似01:01、02:02这样的时间。这可能是因为在程序中存在一些限制,或者存在一些错误导致程序无法正确设置闹钟时间。

以下是一些可能的原因和解决方法:

1.检查程序是否正确。请仔细检查程序代码,确保它能够正确地处理闹钟时间。请注意检查是否存在语法错误、逻辑错误或其他错误。你可以尝试从头开始检查代码,或者使用调试工具来帮助识别问题。

2.检查仿真器设置。请检查仿真器的设置是否正确。有时候,仿真器的设置可能会影响程序的正常运行。你可以尝试更改仿真器的设置,例如时钟频率、输入电压等等,看看是否有任何改善。

3.检查电路图。请确保电路图的连接和布局正确。有时候,电路连接不正确可能会导致程序无法正确运行。你可以检查电路图,确保所有元件都被正确连接,并且没有短路或断路等问题。

4.检查数据手册。请参考51单片机的数据手册,确保你正确地使用了相关的寄存器和功能。如果你不确定如何正确配置51单片机来设置闹钟,请参考数据手册。

希望这些建议能够帮助你解决问题。

您好,我可以尝试为您提供帮助。 根据您提供的信息,可能是在进行仿真时,程序没有正确理解时序关系,导致无法进行闹钟设置。 在单片机时钟万历年数字时钟设计中,时序关系非常重要,包括时钟周期、计数周期、时针和分针的移动顺序等等。如果程序没有正确理解这些时序关系,可能会导致仿真结果与实际不符。 您可以尝试查看Proteus仿真的时序描述文件,查看时序是否正确,包括时钟周期、计数周期、时针和分针的移动顺序等等。也可以尝试修改时序文件,以使仿真结果与实际相符。 如果以上方法无法解决问题,您可以尝试使用其他仿真软件或查看相关文献,以获取更多知识。如果仍然无法解决问题,您可以考虑寻求专业的技术支持。 希望我的回答能够帮助您解决问题。如果还需要进一步的帮助,请随时联系我。

参考:https://download.csdn.net/download/qq_41951164/11259118