找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3831|回复: 2
收起左侧

51单片机LCD1602可调万年历程序Proteus仿真原理图设计

  [复制链接]
ID:465013 发表于 2022-4-13 05:48 | 显示全部楼层 |阅读模式
实现功能:1、以AT89C51/52为设计核心,采用LCD屏幕显示。
2、可以显示公历日期、时间、星期(可调)
3、平年和润年区分
4、闹钟设置
5、包含原理图、源码、仿真

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif 仿真1.png

Altium Designer画的原理图如下:(51hei附件中可下载工程文件) 51hei.png

调试及性能分析
6.1 软件测试
软件测试为利用Keil4软件的编译功能,讲程序导入keil编译运行,无错误显示,故通过软件测试,如图6-1所示:

6.2 proteus电路仿真
为了测试电路在下载程序后是否能够按设计运行,有两种测试方法,最初为制作硬件电路板测试,这种测试方法在有错误后常常需要重新制作电路板故后来渐渐被其它方法取代,另一种方法为在计算机上进行模拟电路仿真,这种方法简便并易差错,在此次设计电路初次测试即为利用proteus进行仿真测试,如图6-2所示:
仿真.png
图6-2 proteus电路仿真

DS1302模块的电路图如图4-3所示,第1脚和第4脚分别接到了电路的VCC和GND,这2个脚是芯片工作的电源输入脚。第8脚接了一个3V的纽扣电池作为时钟芯片的后备电池,可以保证断掉主电源后时钟继续行走。第2和第3脚接了一个32.768K的晶振给芯片提供时钟脉冲,最后,第5、6、7依次连接到单片机的IO口,进行数据的传输。

本设计中由于采用的按键数量较少,只有4个按键,分别是“时钟设置”、“闹钟设置”、“减”、“加”,故采用了独立键盘的方式。按键的连接图4-4所示:
程序设计
5.1 液晶程序算法

(1)1602液晶写数据函数,dat就是要写入的命令
void LcdWriteData(uchar dat)
{
     LcdRs_P = 1;
     LcdRw_P = 0;
     LcdEn_P = 0;
     P0=dat;                  
     DelayMs(2);
     LcdEn_P = 1;   
     DelayMs(2);
     LcdEn_P = 0;
}

   (2)1602液晶初始化函数
void LcdInit()
{
    LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
    LcdWriteCmd(0x0C);        // 开显示,不显示光标
    LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
    LcdWriteCmd(0x01);        // 清屏
}

(3)液晶光标定位函数
void LcdGotoXY(uchar line,uchar column)
{
    // 第一行
    if(line==0)        
        LcdWriteCmd(0x80+column);
    // 第二行
    if(line==1)        
        LcdWriteCmd(0x80+0x40+column);
}

(4)液晶显示内容的初始化
void LcdShowInit()
{
    LcdGotoXY(0,0);
    LcdPrintStr("20  -  -        ");
    LcdGotoXY(1,0);
    LcdPrintStr("  :  :      ");
}


(5)液晶输出数字
void LcdPrintNum(uchar num)
{
    LcdWriteData(num/10+48);        // 十位
    LcdWriteData(num%10+48);         // 个位
}

(6)液晶显示星期
void LcdPrintWeek(uchar week)
{
    switch(week)
    {
        case 1: LcdPrintStr(" Sun");    break;
        case 2: LcdPrintStr(" Mon");    break;
        case 3: LcdPrintStr("Tues");    break;
        case 4: LcdPrintStr(" Wed");    break;
        case 5: LcdPrintStr("Thur");    break;
        case 6: LcdPrintStr(" Fri");    break;
        case 7: LcdPrintStr(" Sat");    break;
        default:                            break;
    }
}

(7)液晶显示平润年
void LcdPrintYearType(uchar type)
{
    switch(type)
    {
        case 0: LcdPrintStr(" RUN");    break;
        case 1: LcdPrintStr(" PING");    break;
        default:                            break;
    }
}
(8)刷新时间显示
void FlashTime()
{
    LcdGotoXY(0,2);                                        // 年份
    LcdPrintNum(TimeBuff[0]);
    LcdGotoXY(0,5);                                        // 月份
    LcdPrintNum(TimeBuff[1]);
    LcdGotoXY(0,8);                                        // 日期
    LcdPrintNum(TimeBuff[2]);
    LcdGotoXY(1,0);                                        // 小时
    LcdPrintNum(TimeBuff[4]);
    LcdGotoXY(1,3);                                        // 分钟
    LcdPrintNum(TimeBuff[5]);
    LcdGotoXY(1,6);                                       // 秒钟
    LcdPrintNum(TimeBuff[6]);
    LcdGotoXY(0,11);                                       // 星期   
    LcdPrintWeek(TimeBuff[3]);
    LcdGotoXY(1,11);                                       // 平润年
    LcdPrintYearType(nian_type);                              
}
5.2 时钟程序算法
(1)初始化DS1302
void DS1302_Init(void)
{
    RST_P=0;            // RST脚置低
    SCK_P=0;            // SCK脚置低
    SDA_P=0;            // SDA脚置低               
}

    (2)从DS1302读出一字节数据
  uchar DS1302_Read_Byte(uchar addr)
{
    uchar i;
    uchar temp;
    RST_P=1;                                
    for(i=0;i<8;i++)
    {     
        if(addr&0x01)
            SDA_P=1;
        else
            SDA_P=0;        
        SCK_P=1;
        _nop_();
        SCK_P=0;
        _nop_();        
        addr=addr>> 1;
    }
    for(i=0;i<8;i++)
    {
        temp=temp>>1;   
        if(SDA_P)
            temp|= 0x80;
        else
            temp&=0x7F;        
        SCK_P=1;
        _nop_();
        SCK_P=0;
        _nop_();
    }   
    RST_P=0;   
    return temp;
}
      
(3)向DS1302写入时间数据
void DS1302_Write_Time()
{
  uchar i;
uchar temp1;
    uchar temp2;
    for(i=0;i<7;i++)            // 十进制转BCD码
    {
        temp1=(TimeBuff[ i]/10)<<4;
        temp2=TimeBuff[ i]%10;
        TimeBuff[ i]=temp1+temp2;
    }
   
    DS1302_Write_Byte(0x8E,0x00);                       // 关闭写保护
    DS1302_Write_Byte(0x80,0x80);                        // 暂停时钟
    DS1302_Write_Byte(0x8C,TimeBuff[0]);                // 年
    DS1302_Write_Byte(0x88,TimeBuff[1]);                // 月
    DS1302_Write_Byte(0x86,TimeBuff[2]);                // 日
    DS1302_Write_Byte(0x8A,TimeBuff[3]);                // 星期
    DS1302_Write_Byte(0x84,TimeBuff[4]);                // 时
    DS1302_Write_Byte(0x82,TimeBuff[5]);                // 分
    DS1302_Write_Byte(0x80,TimeBuff[6]);                // 秒
    DS1302_Write_Byte(0x80,TimeBuff[6]&0x7F);           // 运行时钟
    DS1302_Write_Byte(0x8E,0x80);                       // 打开写保护  
}
(4)从DS1302读出时间数据
void DS1302_Read_Time()  
{
    uchar i;
    uint nian_temp;

    TimeBuff[0]=DS1302_Read_Byte(0x8D);                        // 年
    TimeBuff[1]=DS1302_Read_Byte(0x89);                        // 月
    TimeBuff[2]=DS1302_Read_Byte(0x87);                        // 日
    TimeBuff[3]=DS1302_Read_Byte(0x8B);                        //星期
    TimeBuff[4]=DS1302_Read_Byte(0x85);                        // 时
    TimeBuff[5]=DS1302_Read_Byte(0x83);                        // 分
    TimeBuff[6]=(DS1302_Read_Byte(0x81))&0x7F;               // 秒

    for(i=0;i<7;i++)        // BCD转十进制
    {           
        TimeBuff[ i]=(TimeBuff[ i]/16)*10+TimeBuff[ i]%16;
    }
   
    nian_temp=2000+TimeBuff[0];
    //计算平润年
    if((nian_temp%4==0&&nian_temp%100!=0)||(nian_temp%400==0))
    {
        nian_type=0;
    }
    else
    {
        nian_type=1;
    }
}

51hei.png

下载: 基于51单片机LCD万年历.7z (359.96 KB, 下载次数: 211)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1042619 发表于 2022-12-14 11:43 | 显示全部楼层

STC单片机] 一箭双雕之USB转双串口: USB-CDC1串口仿真,USB-CDC2串口通信

     感谢楼主精彩分享,可以试试 STC8H8K64TLCD-45MHz-LQFP64, STC8H8K64TLCD-45MHz-LQFP48, 16个触摸按键,4COM*40Segment,段码LCD驱动,内置RTC万年历。

STC8H4K64TLCD-LCD-RTC-Demo-20220810.zip

131.77 KB, 下载次数: 10, 下载积分: 黑币 -5

STC8H4K64TLCD主要功能演示板-PCB.PDF

503.7 KB, 下载次数: 5, 下载积分: 黑币 -5

STC8H4K64TLCD主要功能演示板-SCH.PDF

276.3 KB, 下载次数: 5, 下载积分: 黑币 -5

回复

使用道具 举报

ID:1055701 发表于 2022-12-21 12:30 | 显示全部楼层
老师这个在开发板上怎么显示不了啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表