当前位置: 首页 > news >正文

【51单片机-B030】【protues仿真】基于51单片机万年历系统

目录

一、主要功能

二、使用步骤

三、硬件资源

四、软件设计

五、实验现象

一、主要功能

1、LCD1602液晶显示时间,温度
2、按键设置时间和闹钟,查看农历​
3、整点报时,闹钟功能
4、调整闹钟时间:将显示调至闹钟显示界面进行调整
5、整点报时,闹钟开启与关闭:同时按下设置+加键,
可开启或关闭整点报时,蜂鸣器会有提示,如响一声表示开,
响两声表示关闭;同时按下设置+减键,可开启或关闭闹钟功能,
同时蜂鸣器会有提示,响一声表示开,响两声表示关闭。

二、使用步骤

基于51单片机的万年历系统通常采用STC89C52/AT89C51作为主控芯片,结合时钟模块、显示模块和温度传感器实现多功能时间管理。

三、硬件资源

1、51单片机核心模块
2、按键模块
3、温度传感器模块,时钟芯片模块
4、蜂鸣器模块
5、继电器模块
6、LCD1602显示模块

四、软件设计

#include<reg52.h>
#include <string.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define wd 1                //定义是否有温度功能  =0时无温度,=1时有温度


#define yh 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)
#define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)

//液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)
sbit en=P2^7;
sbit rw=P2^6;   //如果硬件上rw接地,就不用写这句和后面的rw=0了
sbit rs=P2^5;


//校时按键与C51的引脚连接定义

sbit set=P3^0;      //设置键
sbit add=P3^1;      //加键
sbit dec=P3^2;      //减键
sbit seeNL_NZ=P3^3;    //查看农历/闹钟

sbit DQ=P3^7;        //
sbit buzzer=P2^0;    //蜂鸣器,通过三极管8550驱动,端口低电平响

sbit led=P2^4;         //LCD背光开关
bit  led1=1;
bit  ZDK=1,NZK=1;    //整点报时,闹钟开关控制位  =0时,关闭,=1时,开启
bit zdkg=0,nzkg=0;
unsigned char temp_miao;
unsigned char bltime;  //背光亮的时间

//DS1302时钟芯片与C51之间的引脚连接定义
sbit IO=P1^4;
sbit SCLK=P1^3;
sbit RST=P1^5;


uchar a,miao,shi,fen,ri,yue,nian,week,setn,temp;
uint flag;
//flag用于读取头文件中的温度值,和显示温度值
bit c_moon;

uchar nz_shi=12,nz_fen=0,nz_miao=0,setNZn;        //定义闹钟变量
uchar shangyimiao,bsn,temp_hour;            //记录上一秒时间
uchar T_NL_NZ;                            //计数器
bit timeron=0;                            //闹钟启用标志位
bit baoshi=0;                            //整点报时标志位
bit  p_r=0;                                 //平年/润年  =0表示平年,=1表示润年
data uchar year_moon,month_moon,day_moon,week;

sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
/************************************************************
ACC累加器=A
ACC.0=E0H

ACC.0就是ACC的第0位。Acc可以位寻址。

累加器ACC是一个8位的存储单元,是用来放数据的。但是,这个存储单元有其特殊的地位,
是单片机中一个非常关键的单元,很多运算都要通过ACC来进行。以后在学习指令时,
常用A来表示累加器。但有一些地方例外,比如在PUSH指令中,就必须用ACC这样的名字。
一般的说法,A代表了累加器中的内容、而ACC代表的是累加器的地址。
***************************************************************/

//********阳历转换阴历表************************************
code uchar year_code[597]=
{
    0x04,0xAe,0x53,    //1901 0
    0x0A,0x57,0x48,    //1902 3
    0x55,0x26,0xBd,    //1903 6
    0x0d,0x26,0x50,    //1904 9
    0x0d,0x95,0x44,    //1905 12
    0x46,0xAA,0xB9,    //1906 15
    0x05,0x6A,0x4d,    //1907 18
    0x09,0xAd,0x42,    //1908 21
    0x24,0xAe,0xB6,    //1909
    0x04,0xAe,0x4A,    //1910
    0x6A,0x4d,0xBe,    //1911
    0x0A,0x4d,0x52,    //1912
    0x0d,0x25,0x46,    //1913
    0x5d,0x52,0xBA,    //1914
    0x0B,0x54,0x4e,    //1915
    0x0d,0x6A,0x43,    //1916
    0x29,0x6d,0x37,    //1917
    0x09,0x5B,0x4B,    //1918
    0x74,0x9B,0xC1,    //1919
    0x04,0x97,0x54,    //1920
    0x0A,0x4B,0x48,    //1921
    0x5B,0x25,0xBC,    //1922
    0x06,0xA5,0x50,    //1923
    0x06,0xd4,0x45,    //1924
    0x4A,0xdA,0xB8,    //1925
    0x02,0xB6,0x4d,    //1926
    0x09,0x57,0x42,    //1927
    0x24,0x97,0xB7,    //1928
    0x04,0x97,0x4A,    //1929
    0x66,0x4B,0x3e,    //1930
    0x0d,0x4A,0x51,    //1931
    0x0e,0xA5,0x46,    //1932
    0x56,0xd4,0xBA,    //1933
    0x05,0xAd,0x4e,    //1934
    0x02,0xB6,0x44,    //1935
    0x39,0x37,0x38,    //1936
    0x09,0x2e,0x4B,    //1937
    0x7C,0x96,0xBf,    //1938
    0x0C,0x95,0x53,    //1939
    0x0d,0x4A,0x48,    //1940
    0x6d,0xA5,0x3B,    //1941
    0x0B,0x55,0x4f,    //1942
    0x05,0x6A,0x45,    //1943
    0x4A,0xAd,0xB9,    //1944
    0x02,0x5d,0x4d,    //1945
    0x09,0x2d,0x42,    //1946
    0x2C,0x95,0xB6,    //1947
    0x0A,0x95,0x4A,    //1948
    0x7B,0x4A,0xBd,    //1949
    0x06,0xCA,0x51,    //1950
    0x0B,0x55,0x46,    //1951
    0x55,0x5A,0xBB,    //1952
    0x04,0xdA,0x4e,    //1953
    0x0A,0x5B,0x43,    //1954
    0x35,0x2B,0xB8,    //1955
    0x05,0x2B,0x4C,    //1956
    0x8A,0x95,0x3f,    //1957
    0x0e,0x95,0x52,    //1958
    0x06,0xAA,0x48,    //1959
    0x7A,0xd5,0x3C,    //1960
    0x0A,0xB5,0x4f,    //1961
    0x04,0xB6,0x45,    //1962
    0x4A,0x57,0x39,    //1963
    0x0A,0x57,0x4d,    //1964
    0x05,0x26,0x42,    //1965
    0x3e,0x93,0x35,    //1966
    0x0d,0x95,0x49,    //1967
    0x75,0xAA,0xBe,    //1968
    0x05,0x6A,0x51,    //1969
    0x09,0x6d,0x46,    //1970
    0x54,0xAe,0xBB,    //1971
    0x04,0xAd,0x4f,    //1972
    0x0A,0x4d,0x43,    //1973
    0x4d,0x26,0xB7,    //1974
    0x0d,0x25,0x4B,    //1975
    0x8d,0x52,0xBf,    //1976
    0x0B,0x54,0x52,    //1977
    0x0B,0x6A,0x47,    //1978
    0x69,0x6d,0x3C,    //1979
    0x09,0x5B,0x50,    //1980
    0x04,0x9B,0x45,    //1981
    0x4A,0x4B,0xB9,    //1982
    0x0A,0x4B,0x4d,    //1983
    0xAB,0x25,0xC2,    //1984
    0x06,0xA5,0x54,    //1985
    0x06,0xd4,0x49,    //1986
    0x6A,0xdA,0x3d,    //1987
    0x0A,0xB6,0x51,    //1988
    0x09,0x37,0x46,    //1989
    0x54,0x97,0xBB,    //1990
    0x04,0x97,0x4f,    //1991
    0x06,0x4B,0x44,    //1992
    0x36,0xA5,0x37,    //1993
    0x0e,0xA5,0x4A,    //1994
    0x86,0xB2,0xBf,    //1995
    0x05,0xAC,0x53,    //1996
    0x0A,0xB6,0x47,    //1997
    0x59,0x36,0xBC,    //1998
    0x09,0x2e,0x50,    //1999 294
    0x0C,0x96,0x45,    //2000 297
    0x4d,0x4A,0xB8,    //2001
    0x0d,0x4A,0x4C,    //2002
    0x0d,0xA5,0x41,    //2003
    0x25,0xAA,0xB6,    //2004
    0x05,0x6A,0x49,    //2005
    0x7A,0xAd,0xBd,    //2006
    0x02,0x5d,0x52,    //2007
    0x09,0x2d,0x47,    //2008
    0x5C,0x95,0xBA,    //2009
    0x0A,0x95,0x4e,    //2010
    0x0B,0x4A,0x43,    //2011
    0x4B,0x55,0x37,    //2012
    0x0A,0xd5,0x4A,    //2013
    0x95,0x5A,0xBf,    //2014
    0x04,0xBA,0x53,    //2015
    0x0A,0x5B,0x48,    //2016
    0x65,0x2B,0xBC,    //2017
    0x05,0x2B,0x50,    //2018
    0x0A,0x93,0x45,    //2019
    0x47,0x4A,0xB9,    //2020
    0x06,0xAA,0x4C,    //2021
    0x0A,0xd5,0x41,    //2022
    0x24,0xdA,0xB6,    //2023
    0x04,0xB6,0x4A,    //2024
    0x69,0x57,0x3d,    //2025
    0x0A,0x4e,0x51,    //2026
    0x0d,0x26,0x46,    //2027
    0x5e,0x93,0x3A,    //2028
    0x0d,0x53,0x4d,    //2029
    0x05,0xAA,0x43,    //2030
    0x36,0xB5,0x37,    //2031
    0x09,0x6d,0x4B,    //2032
    0xB4,0xAe,0xBf,    //2033
    0x04,0xAd,0x53,    //2034
    0x0A,0x4d,0x48,    //2035
    0x6d,0x25,0xBC,    //2036
    0x0d,0x25,0x4f,    //2037
    0x0d,0x52,0x44,    //2038
    0x5d,0xAA,0x38,    //2039
    0x0B,0x5A,0x4C,    //2040
    0x05,0x6d,0x41,    //2041
    0x24,0xAd,0xB6,    //2042
    0x04,0x9B,0x4A,    //2043
    0x7A,0x4B,0xBe,    //2044
    0x0A,0x4B,0x51,    //2045
    0x0A,0xA5,0x46,    //2046
    0x5B,0x52,0xBA,    //2047
    0x06,0xd2,0x4e,    //2048
    0x0A,0xdA,0x42,    //2049
    0x35,0x5B,0x37,    //2050
    0x09,0x37,0x4B,    //2051
    0x84,0x97,0xC1,    //2052
    0x04,0x97,0x53,    //2053
    0x06,0x4B,0x48,    //2054
    0x66,0xA5,0x3C,    //2055
    0x0e,0xA5,0x4f,    //2056
    0x06,0xB2,0x44,    //2057
    0x4A,0xB6,0x38,    //2058
    0x0A,0xAe,0x4C,    //2059
    0x09,0x2e,0x42,    //2060
    0x3C,0x97,0x35,    //2061
    0x0C,0x96,0x49,    //2062
    0x7d,0x4A,0xBd,    //2063
    0x0d,0x4A,0x51,    //2064
    0x0d,0xA5,0x45,    //2065
    0x55,0xAA,0xBA,    //2066
    0x05,0x6A,0x4e,    //2067
    0x0A,0x6d,0x43,    //2068
    0x45,0x2e,0xB7,    //2069
    0x05,0x2d,0x4B,    //2070
    0x8A,0x95,0xBf,    //2071
    0x0A,0x95,0x53,    //2072
    0x0B,0x4A,0x47,    //2073
    0x6B,0x55,0x3B,    //2074
    0x0A,0xd5,0x4f,    //2075
    0x05,0x5A,0x45,    //2076
    0x4A,0x5d,0x38,    //2077
    0x0A,0x5B,0x4C,    //2078
    0x05,0x2B,0x42,    //2079
    0x3A,0x93,0xB6,    //2080
    0x06,0x93,0x49,    //2081
    0x77,0x29,0xBd,    //2082
    0x06,0xAA,0x51,    //2083
    0x0A,0xd5,0x46,    //2084
    0x54,0xdA,0xBA,    //2085
    0x04,0xB6,0x4e,    //2086
    0x0A,0x57,0x43,    //2087
    0x45,0x27,0x38,    //2088
    0x0d,0x26,0x4A,    //2089
    0x8e,0x93,0x3e,    //2090
    0x0d,0x52,0x52,    //2091
    0x0d,0xAA,0x47,    //2092
    0x66,0xB5,0x3B,    //2093
    0x05,0x6d,0x4f,    //2094
    0x04,0xAe,0x45,    //2095
    0x4A,0x4e,0xB9,    //2096
    0x0A,0x4d,0x4C,    //2097
    0x0d,0x15,0x41,    //2098
    0x2d,0x92,0xB5,    //2099
};

///月份数据表
code uchar day_code1[9]= {0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
code uint day_code2[3]= {0x111,0x130,0x14e};

/*
函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
*/

bit c_moon;
data uchar year_moon,month_moon,day_moon,week;
//子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0
bit get_moon_day(uchar month_p,uint table_addr)
{
    uchar temp;
    switch (month_p)
    {
    case 1:
    {
        temp=year_code[table_addr]&0x08;
        if (temp==0)return(0);
        else return(1);
    }
    case 2:
    {
        temp=year_code[table_addr]&0x04;
        if (temp==0)return(0);
        else return(1);
    }
    case 3:
    {
        temp=year_code[table_addr]&0x02;
        if (temp==0)return(0);
        else return(1);
    }
    case 4:
    {
        temp=year_code[table_addr]&0x01;
        if (temp==0)return(0);
        else return(1);
    }
    case 5:
    {
        temp=year_code[table_addr+1]&0x80;
        if (temp==0) return(0);
        else return(1);
    }
    case 6:
    {
        temp=year_code[table_addr+1]&0x40;
        if (temp==0)return(0);
        else return(1);
    }
    case 7:
    {
        temp=year_code[table_addr+1]&0x20;
        if (temp==0)return(0);
        else return(1);
    }
    case 8:
    {
        temp=year_code[table_addr+1]&0x10;
        if (temp==0)return(0);
        else return(1);
    }
    case 9:
    {
        temp=year_code[table_addr+1]&0x08;
        if (temp==0)return(0);
        else return(1);
    }
    case 10:
    {
        temp=year_code[table_addr+1]&0x04;
        if (temp==0)return(0);
        else return(1);
    }
    case 11:
    {
        temp=year_code[table_addr+1]&0x02;
        if (temp==0)return(0);
        else return(1);
    }
    case 12:
    {
        temp=year_code[table_addr+1]&0x01;
        if (temp==0)return(0);
        else return(1);
    }
    case 13:
    {
        temp=year_code[table_addr+2]&0x80;
        if (temp==0)return(0);
        else return(1);
    }
    }
}

void Conversion(bit c,uchar year,uchar month,uchar day)
{
    //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
    uchar temp1,temp2,temp3,month_p;
    uint temp4,table_addr;
    bit flag2,flag_y;
    temp1=year/16;   //BCD->hex 先把数据转换为十六进制
    temp2=year%16;
    // year=temp1*10+temp2;
    year=temp1*16+temp2;
    temp1=month/16;
    temp2=month%16;
    //month=temp1*10+temp2;
    month=temp1*16+temp2;
    temp1=day/16;
    temp2=day%16;
    //day=temp1*10+temp2;
    day=temp1*16+temp2;
    //定位数据表地址
    if(c==0)
    {
        table_addr=(year+0x64-1)*0x3;
    }
    else
    {
        table_addr=(year-1)*0x3;
    }
    //定位数据表地址完成
    //取当年春节所在的公历月份
    temp1=year_code[table_addr+2]&0x60;
    temp1=_cror_(temp1,5);
    //取当年春节所在的公历月份完成
    //取当年春节所在的公历日
    temp2=year_code[table_addr+2]&0x1f;
    //取当年春节所在的公历日完成
    // 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
    if(temp1==0x1)
    {
        temp3=temp2-1;
    }
    else
    {
        temp3=temp2+0x1f-1;
    }

    if (month<10)
    {
        temp4=day_code1[month-1]+day-1;
    }
    else
    {
        temp4=day_code2[month-10]+day-1;
    }
    if ((month>0x2)&&(year%0x4==0))   //如果公历月大于2月并且该年的2月为闰月,天数加1
    {
        temp4+=1;
    }

    if (temp4>=temp3)  //公历日在春节后或就是春节当日使用下面代码进行运算
    {
        temp4-=temp3;
        month=0x1;
        month_p=0x1;  //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
        flag2=get_moon_day(month_p,table_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0
        flag_y=0;
        if(flag2==0)temp1=0x1d; //小月29天
        else temp1=0x1e; //大小30天
        temp2=year_code[table_addr]&0xf0;
        temp2=_cror_(temp2,4);  //从数据表中取该年的闰月月份,如为0则该年无闰月
        while(temp4>=temp1)
        {
            temp4-=temp1;
            month_p+=1;
            if(month==temp2)
            {
                flag_y=~flag_y;
                if(flag_y==0)month+=1;
            }
            else month+=1;
            flag2=get_moon_day(month_p,table_addr);
            if(flag2==0)temp1=0x1d;
            else temp1=0x1e;
        }
        day=temp4+1;
    }
    else   //公历日在春节前使用下面代码进行运算
    {
        temp3-=temp4;
        if (year==0x0)
        {
            year=0x63;
            c=1;
        }
        else year-=1;
        table_addr-=0x3;
        month=0xc;
        temp2=year_code[table_addr]&0xf0;
        temp2=_cror_(temp2,4);
        if (temp2==0)
            month_p=0xc;
        else
            month_p=0xd; //

        //month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12

        flag_y=0;
        flag2=get_moon_day(month_p,table_addr);
        if(flag2==0)temp1=0x1d;
        else temp1=0x1e;
        while(temp3>temp1)
        {
            temp3-=temp1;
            month_p-=1;
            if(flag_y==0)month-=1;
            if(month==temp2)flag_y=~flag_y;
            flag2=get_moon_day(month_p,table_addr);
            if(flag2==0)temp1=0x1d;
            else temp1=0x1e;
        }
        day=temp1-temp3+1;
    }
    c_moon=c;                 //HEX->BCD ,运算结束后,把数据转换为BCD数据
    temp1=year/10;
    temp1=_crol_(temp1,4);
    temp2=year%10;
    year_moon=temp1|temp2;
    temp1=month/10;
    temp1=_crol_(temp1,4);
    temp2=month%10;
    month_moon=temp1|temp2;
    temp1=day/10;
    temp1=_crol_(temp1,4);
    temp2=day%10;
    day_moon=temp1|temp2;
}
 

//*******************主函数**************************
//***************************************************
void main()
{
    ds1302_init();   //调用DS1302时钟的初始化子函数
    init();          //调用定时计数器的设置子函数
    lcd_init();      //调用液晶屏初始化子函数
    InitialTimer2();
    led=1;           //关闭LCD的背光电源

    while(1)  //无限循环下面的语句:
    {
        keyscan();      //调用键盘扫描子函数
        led=led1;
    }
}
 

五、实验现象

演示视频:

http://www.xdnf.cn/news/1477477.html

相关文章:

  • 心路历程-passwdusermod命令补充
  • 嵌入式学习——ARM 体系架构1
  • [光学原理与应用-422]:非线性光学 - 计算机中的线性与非线性运算
  • PHP - pack/unpack「字符串/二进制字符串」- 学习/实践
  • Week 15: 深度学习补遗:集成学习初步
  • C++算法学习——链表
  • 基于Scikit-learn集成学习模型的情感分析研究与实现
  • Day12--HOT100--23. 合并 K 个升序链表,146. LRU 缓存,94. 二叉树的中序遍历
  • 腾讯混元翻译模型Hunyuan-MT-7B开源,先前拿了30个冠军
  • Go基础(③Cobra)
  • STM32——Flash闪存
  • 自动化运维,ansible综合测试练习题
  • Ceph分布式存储全解析:从了解到使用
  • 新能源研发,用新型实验记录本:ELN
  • 006-Dephi 表达式 选择语句 循环语句其他语句
  • k8s网络原理
  • Qt自定义列表项与QListWidget学习
  • PID控制技术深度剖析:从基础原理到高级应用(六)
  • LeetCode 刷题【66. 加一、67. 二进制求和】
  • Linux bzip2 命令使用说明
  • 大数据毕业设计选题推荐-基于大数据的宫颈癌风险因素分析与可视化系统-Spark-Hadoop-Bigdata
  • Day22_【机器学习—集成学习(2)—Bagging—随机森林算法】
  • 学习nginx location ~ .*.(js|css)?$语法规则
  • Error metrics for skewed datasets|倾斜数据集的误差指标
  • 区块链论坛社区
  • 在 ES6 中如何提取深度嵌套的对象中的指定属性
  • 【111】基于51单片机停车场车位管理系统【Proteus仿真+Keil程序+报告+原理图】
  • 从RAW到BMP:工业视觉系统图像格式的转换与优化
  • 数据结构之二叉树(1)
  • STM32-----SPI