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

 我来答
MIW2011
2014-05-29 · TA获得超过1506个赞
知道小有建树答主
回答量:1188
采纳率:50%
帮助的人:693万
展开全部

直接百度 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--);
};
}
 
 

CHQIC
2014-05-18 · TA获得超过781个赞
知道小有建树答主
回答量:1362
采纳率:50%
帮助的人:447万
展开全部
这个我做过哦.就是51+DS1302+1602芯片的.
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式