[讨论] 单片机控制电子时钟LCD显示C程序.现贴上来,和大家分享一下~~~

maker   2008-9-10 15:24 楼主
/*By wysh
*Date 2008.8.20
*/
#include

#define Lcd_Data P0                 //定义八位数据口
#define Busy 0x80                //用于检测LCM状态字中的Busy标识

#define uchar unsigned char  
#define uint unsigned int

sbit s1=P2^0;                 //定义三个按键
sbit s2=P2^1;
sbit s3=P2^2;

sbit Lcd_EN=P1^1;
sbit Lcd_RW=P1^2;
sbit Lcd_RS=P1^3;

char miao,shi,fen,nian,yue,ri,xq;   //定义变量
uchar count,s1num;
uchar code table[]="  2008-08-20 03";//年月日 星期
uchar code table1[]="    12:00:00";  //时分秒


//通用延时子程序
void delay(uint N)
{
  for(;N>0;N--);
}


//5ms延时
void Delay5Ms(void)
{
   uchar i=5552;
   while(i--);
}


//LCD检测忙子程序
uchar Lcd_WaitBusy(void)
{
     Lcd_Data = 0xFF;
     Lcd_RS = 0;
     Lcd_RW = 1;
     Lcd_EN = 0;
     Lcd_EN = 1;
     Lcd_EN = 1;
     while (Lcd_Data & Busy);    //检测忙信号
     Lcd_EN = 0;
     return(Lcd_Data);           //若不处于忙状态显示字符
}


//LCD写指令子程序
void Lcd_WriteCmd(uchar W_Cmd,BusyC) //BusyC为0时忽略忙检测
{
   if (BusyC) Lcd_WaitBusy();   //根据需要检测忙
   Lcd_Data = W_Cmd;
   Lcd_RS = 0;
   Lcd_RW = 0;
   Lcd_EN = 0;
   Lcd_EN = 1;                   //开始执行写指令
   Lcd_EN = 0;
}


//LCD写数据子程序
void Lcd_WriteData(uchar W_Data)
{
    Lcd_WaitBusy();            //检测忙
    Lcd_Data = W_Data;
    Lcd_RS = 1;
    Lcd_RW = 0;
    Lcd_EN = 0;                //若晶振速度太高可以在这后加小的延时
    Lcd_EN = 1;                  //开始执行写数据
    Lcd_EN = 0;
}


//LCD初始化子程序
void init()
{
    uchar num;
    delay(4000);
    Lcd_WriteCmd(0x38,0);  //显示模式设置,不检测忙信号
    Delay5Ms();              //指令码38H设置16*2显示  5*7点阵  8位数据接口
    Delay5Ms();

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

for(num=0;num<15;num++)
  {
   Lcd_WriteData(table[num]);
   delay(80);
  }
Lcd_WriteCmd(0x80+0x40);         //指令码0x80+0x40设置数据指针地址
for(num=0;num<12;num++)
  {
   Lcd_WriteData(table1[num]);
   delay(80);
  }
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}


//写时分秒数据子程序
void Write_Sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
Lcd_WriteCmd(0x80+0x40+add);
Lcd_WriteData(0x30+shi);
Lcd_WriteData(0x30+ge);
}


//写年月日星期数据子程序
void Write_Nyr(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
Lcd_WriteCmd(0x80+add);
Lcd_WriteData(0x30+shi);
Lcd_WriteData(0x30+ge);
}


//按键操作子程序
void keyscan()
{
if(s1==0)  
{
  delay(80);
  if(s1==0)
  {  
   s1num++;
   while(!s1);
   if(s1num==1)
   {
    TR0=0;
    Lcd_WriteCmd(0x80+0x40+10);                 //调节秒的数据指针设置在(1,10)坐标处  理解0x80+0x40+10这条指令
    Lcd_WriteCmd(0x0f);                 //即数据指针地址在第二行第11位处
   }
  }
   if(s1num==2)
   {
    Lcd_WriteCmd(0x80+0x40+7);                  //调节时的数据指针设置在(1,7)坐标处
   }
   if(s1num==3)
   {
    Lcd_WriteCmd(0x80+0x40+4);                 //调节时的数据指针设置在(1,4)坐标处
   }
     if(s1num==4)
   {
        Lcd_WriteCmd(0x80+13);
   }
  if(s1num==5)
   {
        Lcd_WriteCmd(0x80+10);
   }
   if(s1num==6)
   {
        Lcd_WriteCmd(0x80+7);
   }
     if(s1num==7)
   {
        Lcd_WriteCmd(0x80+4);
   }
   if(s1num==8)
   {
    s1num=0;
    Lcd_WriteCmd(0x0c);                                   //按键4次后 开显示  光标不开不闪烁
    TR0=1;                                                           //又开始计时
   }

     
  }
  if(s1num!=0)
  {
   if(s2==0)
   {
    delay(80);
    if(s2==0)
    {
     while(!s2);
     if(s1num==1)
     {
      miao++;
      if(miao==60)
       miao=0;
      Write_Sfm(10,miao);
      Lcd_WriteCmd(0x80+0x40+10);
      }
     if(s1num==2)
     {
      fen++;
      if(fen==60)
       fen=0;
      Write_Sfm(7,fen);
      Lcd_WriteCmd(0x80+0x40+7);
     }
     if(s1num==3)
     {
      shi++;
      if(shi==24)
       shi=0;
      Write_Sfm(4,shi);
      Lcd_WriteCmd(0x80+0x40+4);
     }
     if(s1num==4)
     {
      xq++;
      if(xq==8)
       xq=0;
      Write_Nyr(13,xq);
      Lcd_WriteCmd(0x80+13);
     }      
         if(s1num==5)
     {
      ri++;
          if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
      {
          if(ri==32)
         ri=0;
          }
          else if(yue==2)                                         //注意这里没有考虑闰年
          {
          if(ri==29)
             ri=0;
          }
          else  
          {
          if(ri==31)   
             ri=0;
          }
      Write_Nyr(10,ri);
      Lcd_WriteCmd(0x80+10);
     }
     if(s1num==6)
     {
      yue++;
      if(yue==13)
       yue=0;
      Write_Nyr(7,yue);
      Lcd_WriteCmd(0x80+7);
     }
     if(s1num==7)
     {
      nian++;
      if(nian==99)
       nian=0;
      Write_Nyr(4,nian);
      Lcd_WriteCmd(0x80+4);
     }
    }
   }
   if(s3==0)
   {
    delay(80);
    if(s3==0)
    {
     while(!s3);
     if(s1num==1)
     {
      miao--;
      if(miao==-1)
       miao=59;
      Write_Sfm(10,miao);
      Lcd_WriteCmd(0x80+0x40+10);
     }
     if(s1num==2)
     {
      fen--;
      if(fen==-1)
       fen=59;
      Write_Sfm(7,fen);
     Lcd_WriteCmd(0x80+0x40+7);
     }
     if(s1num==3)
     {
      shi--;
      if(shi==-1)
       shi=23;
      Write_Sfm(4,shi);
      Lcd_WriteCmd(0x80+0x40+4);
     }
     if(s1num==4)
     {
      xq--;
      if(xq==-1)
       xq=7;
      Write_Nyr(13,xq);
      Lcd_WriteCmd(0x80+13);
     }
     if(s1num==5)
     {
      ri--;
          if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
      {
          if(ri==-1)
         ri=31;
          }
          else if(yue==2)                                         //注意这里没有考虑闰年
          {
          if(ri==-1)
             ri=28;
          }
          else  
          {
          if(ri==-1)
             ri=30;
          }
      Write_Nyr(10,ri);
      Lcd_WriteCmd(0x80+10);
     }
     if(s1num==6)
     {
      yue--;
      if(yue==-1)
       yue=12;
      Write_Nyr(7,yue);
      Lcd_WriteCmd(0x80+7);
     }
     if(s1num==7)
     {
      nian--;
      if(nian==-1)
       nian=99;
      Write_Nyr(4,nian);
      Lcd_WriteCmd(0x80+4);
     }
    }
   }
  }
}


//主函数
void main()
{
init();
while(1)
{
  keyscan();  
}
}


//计时器
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
  {
   count=0;
   miao++;
   if(miao==60)
   {
    miao=0;
    fen++;
    if(fen==60)
    {
     fen=0;
     shi++;
     if(shi==24)
     {
      shi=0;
          ri++;
          if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
            {
                if(ri==31)
                  {
                  ri=0;
                  yue++;
                  xq++;
                  if(xq==8)
                    {
                        xq=1;
                        }
                  if(yue==12)
                    {
                         yue=0;
                         nian++;
                     Write_Nyr(4,nian);
                        }
                        Write_Nyr(7,yue);
                        Write_Nyr(13,xq);
                  }  
                }
          else if(yue==2)                                         //注意这里没有考虑闰年
           {
                if(ri==31)
                 {  
                  ri=0;
                  yue++;
                  xq++;
                  if(xq==8)
                    {
                        xq=1;
                        }
                  if(yue==12)
                    {
                         yue=0;
                         nian++;
                         Write_Nyr(4,nian);
                        }
                  Write_Nyr(7,yue);
                  Write_Nyr(13,xq);
                  }
                }
          else
           {
                if(ri==31)
                  {
                  ri=0;
                  yue++;
                  xq++;
                  if(xq==8)
                    {
                        xq=1;
                        }
                  if(yue==12)
                    {
                         yue=0;
                         nian++;
                         Write_Nyr(4,nian);
                        }
                  Write_Nyr(7,yue);
                  Write_Nyr(13,xq);
                  }
           }
           Write_Nyr(10,ri);
     }
     Write_Sfm(4,shi);
    }
    Write_Sfm(7,fen);
   }
   Write_Sfm(10,miao);
   
  }  
}
/*程序难点就在对LCD1602指令集的认识,这里有不错到资料http://cn.ic-on-line.cn/IOL/datasheet/LCD1602A_398763.pdf,共享一下...另外时期的显示也比较繁琐,其中很多是为了保证全面,因此看起来有很多重复*/

回复评论 (5)

Re: [分享] 单片机控制电子时钟LCD显示C程序.现贴上来,和大家分享一下~~~

不怎么详细,没图可看的!!!
点赞  2009-4-1 17:59
很好,谢谢楼主分享
点赞  2009-6-20 15:34
好的,谢谢!
点赞  2009-6-20 16:01

回复 楼主 maker 的帖子

有硬件图没有,楼主
点赞  2009-6-21 04:40
正好借鉴一下
点赞  2011-6-21 16:18
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复