利用AT89C51单片机,LM016L液晶显示、时钟芯片DS1302芯片制作电子钟,需要一个程序,帮帮我吧

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-07
利用AT89C51单片机,LM016L液晶显示、时钟芯片DS1302芯片制作电子钟,需要一个程序,帮帮我吧

lm016l没有卖的,跟1602一样,proteus仿真时用它来代替1602,告诉你如果你是作业,连写这么简单程序的耐心都没有,你还不如不去交作业,电路图放了,程序只给一部分,供参考,头文件自己去写
#include
#include"lcd1602.h"
#include"ds1302.h"
uchar readaddress[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
uchar readvalue[21];
uchar readdate[7];

void delay()
{
uchar i,j;
for(i=5;i>0;i--)
for(j=115;j>0;j--);
}

void init()
{
EN=0;
writecom(0x38);
writecom(0x0c);
writecom(0x06);
writecom(0x01);
writecom(0x80+0x01);// 2014-02-22-06
writedate('2');
delay();
writedate('0');
delay();
writecom(0x80+0x05);
delay();
writedate('-');
delay();
writecom(0x80+0x08);
delay();
writedate('-');
delay();
writecom(0x80+0x0b);
delay();
writedate('-');
delay();
writecom(0x80+0x40+0x06);
delay();//" 00:00:00
writedate(':');
delay();
writecom(0x80+0x40+0x09);
delay();
writedate(':');
}
void read()
{
uchar i;
for(i=0;i<7;i++)
{
readdate[i]=ds1302read(readaddress[i]);//读取数据
}
}
void nyrz(uchar add,uchar date)//年月日周
{
uchar shi,ge;//任一数据的2位
shi=date/16;
ge=date%16;
writecom(0x80+add);
delay();
writedate(0x30+shi);
delay();
writedate(0x30+ge);

}

void sfm(uchar add,uchar date)//时分秒" 00:00:00"
{
uchar shi,ge;//任一数据的2位
shi=date/16;
ge=date%16;
writecom(0x80+0x40+add);
delay();
writedate(0x30+shi);
delay();
writedate(0x30+ge);

}

void main()
{
init();
set();//数据写入ds1302中
while(1)
{
read();
nyrz(3,readdate[0]);
nyrz(6,readdate[2]);
nyrz(9,readdate[3]);
nyrz(12,readdate[1]);
sfm(4,readdate[4]);
sfm(7,readdate[5]);
sfm(10,readdate[6]);
}

}

你好!这是一个时钟显示,硬件里应该有时钟芯片

直接百度 1602 的时钟程序,lm016l好像就是1602。

晶振使用12m的。


#define LCM_RW   P2^4 //定义引脚
#define LCM_RS   P2^3
#define LCM_E    P2^5
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#include <reg52.h>
void WriteDataLCM    (unsigned char WDLCM);
void WriteCommandLCM (unsigned char WCLCM,BuysC);
void DisplayOneChar  (unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar (unsigned char X, unsigned char Y, unsigned char code *DData);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);

void pro_timedate(void);
bit leap_year(); //判断是否为闰年
unsigned char data year=11,month=5,date=22;//年、月、日、星期
unsigned char disbuf[16];
unsigned char data hour=23,min=59,sec=55,sec20=0; //时、分、秒、百分之一秒
unsigned char code email[] = {"YEA:MON:DAT:TIME"};
void updatetime (void);
void LCMInit    (void);
void pro_display(void);
void Delay400Ms (void);
void Delay5Ms   (void);
void main(void)
{
     Delay400Ms(); //启动等待,等LCM讲入工作状态
     LCMInit(); //LCM初始化
     DisplayListChar(0, 1, email);
     TMOD=0X01;
     TH0=0X4C;
     TL0=0X00;
     TR0=1;
     ET0=1;
     EA=1;
     while(1);
}

void pro_timedate()
     {
       sec++;
        if(sec > 59)
               {sec = 0;
                     min++;
                        if(min>59)
                              {min=0;
                                  hour++;
                                    if(hour>23)
                                         {hour=0;
                                             date++;
         if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
         if (date>31)
                  {date=1;month++;} //大月31 天
         if (month==4||month==6||month==9||month==11)
         if (date>30)
                  {date=1;month++;} //小月30 天
         if (month==2)
                   {if( leap_year()) //闰年的条件
                   {if (date>29) {date=1;month++;}} //闰年2 月为29 天
                     else
                   {if (date>28) {date=1;month++;}} //平年2 月为28 天
                   }
            if (month>12) {month=1;year++;}
            if (year>99) year=0;
                                        }
                             }
               }

     }

bit leap_year()
{
       bit leap;
       if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件
       leap=1;
       else
       leap=0;
       return leap;
}
//Timer0 中断处理程序,秒的产生
void timer0() interrupt 1
{
     TH0=0x4C; //Timer0 置10ms 定时初值dc00H(2^16=65536D,dc00H=56320D)
     TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)
     sec20++;      
     if(sec20 >= 20) //1 秒时间 (100*10ms=1000ms=1s)
          { sec20=0;
            updatetime  ();     
            pro_timedate();
            pro_display ();
            if(sec&0x01)
            disbuf[13]=' ';
            else disbuf[13]=':';
          }
}



void updatetime(void)
    {   disbuf[0] ='2';
        disbuf[1] ='0';
        disbuf[2] =year/10+48;
        disbuf[3] =year%10+48;
        disbuf[4] =' ';
        disbuf[5] =month/10+48;
        disbuf[6] =month%10+48;
        disbuf[7] ='.';
        disbuf[8] =date/10+48;
        disbuf[9] =date%10+48;
        disbuf[10] =' ';
        disbuf[11]=hour/10+48;
        disbuf[12]=hour%10+48;
        //disbuf[13]=' ';
        disbuf[14]=min/10+48;
        disbuf[15]=min%10+48;
    }
//显示处理程序
void pro_display()
{ unsigned char f;
   for (f=0;f<=15;f++)
   {DisplayOneChar( f,  0,  disbuf[f]);}
   
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
//WDLCM = ((WDLCM&0x01)<<7)|((WDLCM&0x02)<<5)|((WDLCM&0x04)<<3)|((WDLCM&0x08)<<1)|((WDLCM&0x10)>>1)|((WDLCM&0x20)>>3)|((WDLCM&0x40)>>5)|((WDLCM&0x80)>>7);
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0; //延时
LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
//WCLCM = ((WCLCM&0x01)<<7)|((WCLCM&0x02)<<5)|((WCLCM&0x04)<<3)|((WCLCM&0x08)<<1)|((WCLCM&0x10)>>1)|((WCLCM&0x20)>>3)|((WCLCM&0x40)>>5)|((WCLCM&0x80)>>7);
LCM_Data = WCLCM;

LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}

//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0);


//三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF;         //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
//50ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
 
 



这个我做过哦.就是51+DS1302+1602芯片的.