LCD1602和DS1302做的数字钟的显示问题 不能正确显示 板子的LC...

2019-07-15 23:24发布

在没用DS1302的时候,自己编的程序能正常显示,按键也可以随意调整,后来加了点DS1302的程序后就出现问题,LCD显示不正常,感觉秒钟是在走的,以下是程序,自己不太懂,想请各位帮帮忙,谢谢!!

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit LCD_RS = P2^6;              
sbit LCD_RW = P2^5;  
sbit LCD_EP = P2^7;
sbit SCLK=P3^6; //时钟
sbit IO=P3^4; //数据
sbit RST = P3^5;// DS1302复位
uchar s1num,temp,day,year,mon,a,week,flag;
char miao,shi,fen;
uchar code table[]="  20  -  -      ";
uchar code table1[]="      :  :  ";
uchar code ping[]={31,28,31,30,31,30,31,31,30,31,30,31};
uchar code run[]={31,29,31,30,31,30,31,31,30,31,30,31};

void delay(uchar z)
{
  uint x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

bit lcd_bz()
{                        
  bit result;
  LCD_RS = 0;
  LCD_RW = 1;
  LCD_EP = 1;
  delay(5);
  result = (bit)(P0 & 0x80);  //检测P0最高位是否为1
  LCD_EP = 0;
  return result;//返回侧忙结果
}

void write_com_8bit(uint com)   
{                          // 写入指令数据到LCD
  while(lcd_bz());
  LCD_RS = 0;
  LCD_RW = 0;
  LCD_EP = 0;
  delay(1);
  P0 = com; //将高4位位指令通过P0口传给1602
  delay(5);
  LCD_EP = 1;
  delay(5);
  LCD_EP = 0;  
}
void write_com(uint com)     //写命令函数
{                          
while(lcd_bz());
LCD_RS = 0;
LCD_RW = 0;
LCD_EP = 0;
delay(5);
P0 = com;
delay(5);
LCD_EP = 1;
delay(5);
LCD_EP = 0;
delay(5);
P0 = (com&0x0f)<<4;
delay(5);
LCD_EP = 1;
delay(5);
LCD_EP = 0;  
}

void write_data(uint date)  //写数据函数
{                          
while(lcd_bz());
LCD_RS = 1;
LCD_RW = 0;
LCD_EP = 0;
delay(5);
P0 =date;
delay(5);
LCD_EP = 1;
delay(5);
LCD_EP = 0;

LCD_RS = 1;
LCD_RW = 0;
LCD_EP = 0;
delay(5);  
P0 = (date&0x0f)<<4;
delay(5);
LCD_EP = 1;
delay(5);
LCD_EP = 0;  
}

void write_byte(uchar date)//写一个字节
{
SCLK=0;
delay(1);
  for (a=0;a<8;a++)      //循环8次 写入数据
   {
     
      IO=date&0x01;
  delay(1);
   SCLK=1;
   delay(1);
   SCLK=0;   
      date>>=1;    //右移一位
      
   }
}

void write_1302(uchar add,uchar date)//向1302芯片写函数,指定写入地址,数据
{
RST=0;
delay(1);
SCLK=0;
delay(1);
RST=1;
delay(1);
write_byte(add);
write_byte(date);
SCLK=1;
delay(1);
RST=0;
}
uchar read_byte( )
{
  uchar date;
  delay(1);;
   for(a=0;a<8;a++)
    {
          date>>=1;
          if(IO==1)
            date|=0x80;
           SCLK=1;
           delay(1);
           SCLK=0;
           delay(1);
        }
        return date;
}
uchar read_1302(uchar add)//从1302读数据函数,指定读取数据来源地址
{
uchar date;
RST=0;
delay(1);
SCLK=0;
delay(1);
RST=1;
delay(1);
write_byte(add);
date=read_byte();
SCLK=1;
RST=0;
return(date);
}
uchar BCD(uchar bcd)//BCD码转十进制函数,输入BCD,返回十进制
{
  return(((bcd&0xf0)>>4)*10+(bcd&0x0f));
}
void init()  //初始化函数
{
//LCD1602初始化部分
uchar num,flag0;
write_com_8bit(0x38);
delay(1);
write_com_8bit(0x38);
delay(1);
write_com_8bit(0x28);
delay(1);
  write_com(0x28);
delay(1);
write_com(0x06);
delay(1);
write_com(0x0c);
delay(1);
  write_com(0x01);
delay(1);
write_com(0x80);
for(num=0;num<16;num++)
  {
   write_data(table[num]);
   delay(5);
  }
write_com(0x80+0x40);
for(num=0;num<12;num++)
  {
   write_data(table1[num]);
   delay(5);
  }
  
  //DS1302初始化部分
RST=0;
SCLK=0;
flag0=read_1302(0x81);
if(flag0&0x80) //判断时钟芯片是否关闭
{
  write_1302(0x8e,0x00); //允许写,禁止写保护
  write_1302(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据
  write_1302(0x82,0x37);//向DS1302内写分寄存器82H写入初始分数据
  write_1302(0x84,0x16);//向DS1302内写小时寄存器84H写入初始小时数据
  write_1302(0x8a,0x01);//向DS1302内写周寄存器8aH写入初始周数据4
  write_1302(0x86,0x29);//向DS1302内写日期寄存器86H写入初始日期数据
  write_1302(0x88,0x07);//向DS1302内写月份寄存器88H写入初始月份数据
  write_1302(0x8c,0x13);//向DS1302内写年份寄存器8cH写入初始年份数据
  write_1302(0x90,0xa5); //充电
  write_1302(0x8e,0x80); //打开写保护
}
//定时器初始化
EA=1;
EX0=1;
IT0=1;   
}
void write_sfm(uchar add,uchar shu)
{
uchar shi,ge;
shi=shu/10;   //分离操作
ge=shu%10;
write_com(0x80+0x40+add);  //地址指向
write_data(0x30+shi);
write_data(0x30+ge);
}

void write_ymd(uchar add3,uchar shu3)
{
uchar shi,ge;
shi=shu3/10;   //分离操作
ge=shu3%10;
write_com(0x80+add3);  //地址指向
write_data(0x30+shi);
write_data(0x30+ge);
}


void pingrun()
{
if((year%4==0&&year%100!=0)||(year%400==0))
   flag=1;
else flag=0;
}
void display_week(uchar week)
{
switch(week)
{
  case 1:write_com(0x80+13);write_data('M');write_data('O');write_data('N');break;
  case 2:write_com(0x80+13);write_data('T');write_data('U');write_data('S');break;
  case 3:write_com(0x80+13);write_data('W');write_data('E');write_data('N');break;
  case 4:write_com(0x80+13);write_data('T');write_data('H');write_data('U');break;
  case 5:write_com(0x80+13);write_data('F');write_data('R');write_data('I');break;
  case 6:write_com(0x80+13);write_data('S');write_data('A');write_data('T');break;
  case 7:write_com(0x80+13);write_data('S');write_data('U');write_data('N');break;
   
}
}
void DS_set_time()
{
write_1302(0x8e,0x00);
write_1302(0x80,miao);
write_1302(0x82,fen);
write_1302(0x84,shi);
write_1302(0x86,day);
write_1302(0x88,mon);
write_1302(0x8c,year);
write_1302(0x8a,week);
write_1302(0x8e,0x80);
}
void DS_gettime()
{
miao=BCD(read_1302(0x81));
fen=BCD(read_1302(0x83));
shi=BCD(read_1302(0x85));
year=BCD(read_1302(0x8d));
mon=BCD(read_1302(0x89));
day=BCD(read_1302(0x87));
week=BCD(read_1302(0x8b));
}
void keyscan()
{
   P1=0xfe;
   temp=P1;
   temp=temp&0xf0;
   while(temp!=0xf0)
    {
     delay(5);
     temp=P1;
     temp=temp&0xf0;
     while(temp!=0xf0)
     {
      temp=P1;
      if(temp==0xee)
      {
       delay(5);
       if(temp==0xee)
       {
        s1num++;
        while(temp!=0xf0)
        {
         temp=P1;
         temp=temp&0xf0;
        }
       }
      }
         if(s1num==1)
        {
         
         write_com(0x80+2);
         write_com(0x0f);
        }
        if(s1num==2)
        {
         write_com(0x80+7);
        }
        if(s1num==3)
        {
         write_com(0x80+10);
        }
        if(s1num==4)
        {
         write_com(0x80+0x40+10);
        }
        if(s1num==5)
        {
         write_com(0x80+0x40+7);
        }
        if(s1num==6)
        {
         write_com(0x80+0x40+4);
        }
        if(s1num==7)
        {
         s1num=0;
         write_com(0x0c);
         
        }  
       if(s1num!=0)
       {
        if(temp==0xde)
        {
         delay(5);
         if(temp==0xde)
         {
          while(temp!=0xf0)
           {
            temp=P1;
            temp=temp&0xf0;
           }
          if(s1num==1)
          {
           year++;         
           write_ymd(2,year);
           write_com(0x80+2);
          }
          if(s1num==2)
          {
           mon++;
           if(mon==13)
            mon=1;
           write_ymd(7,mon);
           write_com(0x80+7);
          }
         
          if(s1num==3)
          {
           day++;
           pingrun();
           if(flag==1 && day>=(run[mon-1]+1))
            day=1;
           if(flag==0 && day>=(ping[mon-1]+1))
            day=1;
           write_ymd(10,day);
           write_com(0x80+10);
           display_week(week);
          }
          if(s1num==4)
          {
           miao++;
           if(miao==60)
            miao=0;
           write_sfm(10,miao);
           write_com(0x80+0x40+10);
           
           
          }
          if(s1num==5)
          {
           fen++;
           if(fen==60)
            fen=0;
           write_sfm(7,fen);
           write_com(0x80+0x40+7);
          }
          if(s1num==6)
          {
           shi++;
           if(shi==24)
            shi=0;      
           write_sfm(4,shi);
           write_com(0x80+0x40+4);
          }
         }
        }
      
        if(temp==0xbe)
        {
         delay(5);
         if(temp==0xbe)
         {
          while(temp!=0xf0)
           {
            temp=P1;
            temp=temp&0xf0;
           }
           if(s1num==1)
          {
           year--;
           write_ymd(2,year);
           write_com(0x80+2);
          }
          if(s1num==2)
          {
           mon--;
           if(mon==0)
            mon=12;
           write_ymd(7,mon);
           write_com(0x80+7);
          }
           if(s1num==3)
          {
           day--;
           if(day==0 && flag==1)
            day=run[mon-1];
           if(day==0 && flag==0)
            day=ping[mon-1];
           write_ymd(10,day);
           write_com(0x80+10);
           display_week(week);
          }
          if(s1num==4)
          {
           miao--;
           if(miao==-1)
            miao=59;
           write_sfm(10,miao);
           write_com(0x80+0x40+10);
          }
          if(s1num==5)
          {
           fen--;
           if(fen==-1)
            fen=59;
           write_sfm(7,fen);
           write_com(0x80+0x40+7);
          }
          if(s1num==6)
          {
           shi--;
           if(shi==-1)
            shi=23;
           write_sfm(4,shi);
           write_com(0x80+0x40+4);
          }
         }
        }
       }
      }
     }
}   

void main()
{
  init();
  DS_set_time();
while(1)
{
  DS_gettime();
  write_ymd(4,year);
  write_ymd(7,mon);
  write_ymd(10,day);
  display_week(week);
  write_sfm(4,shi);
  write_sfm(7,fen);
  write_sfm(10,miao);
  delay(5);
  keyscan();
  
}
}

void timer0() interrupt 1
{


}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
冰葑世纪
1楼-- · 2019-07-16 04:21
我给你上传你个我开发板上的例程、你可以按照原理图所示电路接一下,也可以改一下程序接口。测试下,因为程序太多检测起来有点麻烦。你首先得测试排除是硬件问题,再从程序下手,有时候虚焊等现象也会引起。一些问题。
1602LCD DS1302时钟实验.rar (95.22 KB, 下载次数: 104)
cjh5750
2楼-- · 2019-07-16 08:35
 精彩回答 2  元偷偷看……
●﹍↙残泪
3楼-- · 2019-07-16 11:15
谢谢!  受教了
说不出的味道
4楼-- · 2019-07-16 16:03
{:1:}{:1:}{:1:}{:1:}{:1:}{:1:}{:1:}{:1:}{:1:}
冯磊123雷锋
5楼-- · 2019-07-16 21:01
感谢一楼资源{:12:}{:12:}
zxf_love2
6楼-- · 2019-07-17 01:12
一般需要先排除硬件问题   然后在保证你驱动1302的协议没有逻辑错误   按照你所说的情况 有可能是1302驱动程序的逻辑错误   不过硬件问题 你要先排除 这是最根本的

一周热门 更多>