高手来帮我看下ds1302断电后没有保存为什么不能断...

求助关于万年历1602显示乱码问题|我爱单片机 - 数码之家
查看完整版本: [--
赞助商链接
自己尝试做一个万年历,但是程序下载好后,然后1602上运行显示不正确,具体情况是都是乱码,而且快速的从右到左,然后在从右到左不停,还有刚开始的时候只是第一行显示一行黑块,然后我摁下硬件复位才开始滚动显示乱码~~~具体就是这样,请各位高手帮忙分析分析原因图片如下:[attachment=2253591]摁下复位之后[attachment=2253590]代码如下:#include®52.h&#include&intrins.h&#define uchar unsigned char #define uint unsigned int#define     LCDIO      P0sbit DQ=P1^3;//ds18b20与单片机连接口sbit rs=P1^0;  sbit rd=P1^1;sbit lcden=P1^2;sbit acc0=ACC^0;             //移位时的第0位sbit acc7=ACC^7;             //移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0;    uchar ReadValue,num,    //温度值uchar code    table[]={&
MON&};uchar code table1[]={& 15:45:00 000.0C&};uchar code table2[]={&THUFRISATSUNMONTUEWES&};uchar data disdata[5];sbit DATA=P3^4;   //时钟数据接口sbit RST=P3^5;    sbit SCLK=P3^3;   sbit menu=P2^0;              //菜单sbit add=P2^1;               //加一sbit dec=P2^2;               //减一void delay(uint z){    uint x,y;    for(x=z;x&0;x--)        for(y=110;y&0;y--);}void delay1(uint z){    for(;z&0;z--);}void write_com(uchar com){    rs=0;    rd=0;    lcden=0;    P0=    delay(5);    lcden=1;    delay(5);    lcden=0;    } void write_date(uchar date){    rs=1;    rd=0;    lcden=0;    P0=    delay(5);    lcden=1;    delay(5);    lcden=0;    } void init(){        lcden=0;     write_com(0x38);    write_com(0x0c);    write_com(0x06);    write_com(0x01);    write_com(0x80);    delay(5);    write_com(0x80);    for(num=0;num&15;num++)        {            write_date(table[num]);            delay(5);        }    write_com(0x80+0x40);    for(num=0;num&15;num++)        {            write_date(table1[num]);            delay(5);        }      
} void Write1302(uchar dat){     SCLK=0;           //拉低SCLK,为脉冲上升沿写入数据做好准备  delay1(2);       //稍微等待,使硬件做好准备  for(i=0;i&8;i++)      //连续写8个二进制位数据    {     DATA=dat&0x01;    //取出dat的第0位数据写入1302  delay(2);       //稍微等待,使硬件做好准备   SCLK=1;           //上升沿写入数据   delay1(2);      //稍微等待,使硬件做好准备   SCLK=0;           //重新拉低SCLK,形成脉冲   dat&&=1;          //将dat的各数据位右移1位,准备写入下一个数据位   } }
void WriteSet1302(uchar Cmd,uchar dat) {   RST=0;           //禁止数据传递   SCLK=0;          //确保写数居前SCLK被拉低   RST=1;           //启动数据传输   delay1(2);     //稍微等待,使硬件做好准备   Write1302(Cmd);  //写入命令字   Write1302(dat);  //写数据   SCLK=1;          //将时钟电平置于已知状态   RST=0;           //禁止数据传递 } uchar Read1302(void) {   uchar i,   delay(2);       //稍微等待,使硬件做好准备   for(i=0;i&8;i++)   //连续读8个二进制位数据   {    dat&&=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位    if(DATA==1)    //如果读出的数据是1    dat|=0x80;    //将1取出,写在dat的最高位    SCLK=1;       //将SCLK置于高电平,为下降沿读出    delay1(2);  //稍微等待    SCLK=0;       //拉低SCLK,形成脉冲下降沿    delay1(2);  //稍微等待    }            //将读出的数据返回  } uchar  ReadSet1302(uchar Cmd) {    RST=0;                 //拉低RST  SCLK=0;                //确保写数居前SCLK被拉低  RST=1;                 //启动数据传输  Write1302(Cmd);       //写入命令字  dat=Read1302();       //读出数据  SCLK=1;              //将时钟电平置于已知状态  RST=0;               //禁止数据传递            //将读出的数据返回}void Init_DS1302(void){
WriteSetE,0x00);                 //根据写状态寄存器命令字,写入不保护指令
WriteSet,((0/10)&&4|(0%10)));   //根据写秒寄存器命令字,写入秒的初始值 WriteSet,((45/10)&&4|(45%10)));   //根据写分寄存器命令字,写入分的初始值 WriteSet,((15/10)&&4|(15%10))); //根据写小时寄存器命令字,写入小时的初始值 WriteSet,((29/10)&&4|(29%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet,((11/10)&&4|(11%10))); //根据写月寄存器命令字,写入月的初始值 WriteSetc,((10/10)&&4|(10%10)));   //nian WriteSeta,((4/10)&&4|(4%10)));} void DisplaySecond(uchar x){ uchar i,j;     i=x/10; j=x%10; write_com(0xc7);  
write_date(0x30+i);  
write_date(0x30+j);       }void DisplayMinute(uchar x){ uchar i,j;     i=x/10; j=x%10;
write_com(0xc4);     write_date(0x30+i);   write_date(0x30+j);         } void DisplayHour(uchar x){ uchar i,j;  
i=x/10; j=x%10; write_com(0xc1);     write_date(0x30+i);   write_date(0x30+j);         } void DisplayDay(uchar x){ uchar i,j;  
i=x/10; j=x%10;     write_com(0x89);     write_date(0x30+i);   write_date(0x30+j);       } void DisplayMonth(uchar x){ uchar i,j;    
i=x/10; j=x%10;   write_com(0x86);     write_date(0x30+i);   write_date(0x30+j);   } void DisplayYear(uchar x){ uchar i,j;    i=x/10; j=x%10;
write_com(0x83);     write_date(0x30+i); write_date(0x30+j);   }   void DisplayWeek(uchar x){   x=x*3; write_com(0x8c);     for(i=0;i&3;i++)   {       write_date(table2[x]);    x++;     } }  
void  read_date(void){     ReadValue = ReadSet);        second=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);     ReadValue = ReadSet);       minute=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);      ReadValue = ReadSet);       hour=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);      ReadValue = ReadSet);       day=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);      ReadValue = ReadSet);       month=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);      ReadValue = ReadSetd);       year=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F);      ReadValue=ReadSetb);                     //读星期     week=ReadValue&0x07;     DisplaySecond(second);                DisplayMinute(minute);             DisplayHour(hour);                  DisplayDay(day);                     DisplayMonth(month);                 DisplayYear(year);               DisplayWeek(week);  } void turn_val(char newval,uchar flag,uchar  newaddr,uchar s1num)    {                   newval=ReadSet1302(newaddr);                     //读取当前时间                   newval=((newval&0x70)&&4)*10+(newval&0x0f);    //将bcd码转换成十进制                   if(flag)                  //判断是加一还是减一                   {                      newval++;                     switch(s1num)                       { case 1: if(newval&99) newval=0;                                  DisplayYear(newval);                                                                 case 2: if(newval&12) newval=1;                                   DisplayMonth(newval);                                                            case 3: if(newval&31) newval=1;                                  DisplayDay(newval);                                                             case 4: if(newval&6) newval=0;                                  DisplayWeek(newval);                                                            case 5: if(newval&23) newval=0;                                  DisplayHour(newval);                                                            case 6: if(newval&59) newval=0;                                  DisplayMinute(newval);                                                            case 7: if(newval&59) newval=0;                                  DisplaySecond(newval);                                                            default:                       }                      }                   else                   {                    newval--;                    switch(s1num)                       { case 1: if(newval==0) newval=99;                                  DisplayYear(newval);                                                            case 2: if(newval==0) newval=12;                                   DisplayMonth(newval);                                                            case 3: if(newval==0) newval=31;                                   DisplayDay(newval);                                                            case 4: if(newval&0) newval=6;                                  DisplayWeek(newval);                                                            case 5: if(newval&0) newval=23;                                  DisplayHour(newval);                                                            case 6: if(newval&0) newval=59;                                  DisplayMinute(newval);                                                            case 7: if(newval&0) newval=59;                                  DisplaySecond(newval);                                                           default:                       }                     }                WriteSet1302((newaddr-1),((newval/10)&&4)|(newval%10));  //将新数据写入寄存器     }  
//键盘扫描程序//*******************************************void key_scan(void){    uchar miao,s1num=0;     if(menu==0)     {        delay(5);       if(menu==0)       {         while(!menu);                s1num++;        while(1)        {             if(menu==0)             {                 delay(5);                if(menu==0)                  {                      while(!menu);                     s1num++;                  }             }             rd=0;            miao=ReadSet);            second=            WriteSet,miao|0x80);            write_com(0x0f);//光标闪射             if(s1num==1)            {    year=ReadSetd);                         write_com(0x80+4);    //年光标                 if(add==0)                 {                   delay(3);                   if(add==0)                     {     while(!add);                       turn_val(year,1,0x8d,1);                                  }                  }                if(dec==0)                 {                    delay(3);                    if(dec==0)                     {    while(!dec);                       turn_val(year,0,0x8d,1);                                           }                  }             }            if(s1num==2)            {              month=ReadSet);                write_com(0x80+7);    //月光标                 if(add==0)            {              delay(3);              if(add==0)               {  while(!add);                  turn_val(month,1,0x89,2);                }            }            if(dec==0)            {               delay(3);               if(dec==0)               {  while(!dec);                  turn_val(month,0,0x89,2);               }            }            }            if(s1num==3)            {    day=ReadSet);                write_com(0x80+10);//日光标                if(add==0)              {              delay(3);              if(add==0)               { while(!add);                 turn_val(day,1,0x87,3);                }            }            if(dec==0)            {               delay(3);               if(dec==0)               { while(!dec);                 turn_val(day,0,0x87,3);                //写入日寄存器               }            }            }            if(s1num==4)            {  week=ReadSetb);                write_com(0x80+14);    //星期光标                  if(add==0)                 {              delay(3);              if(add==0)               { while(!add);                 turn_val(week,1,0x8b,4);                }            }            if(dec==0)            {               delay(3);               if(dec==0)               { while(!dec);                 turn_val(week,0,0x8b,4);               }            }            }            if(s1num==5)            {    hour=ReadSet);                write_com(0x80+0x40+2);    //时光标                 if(add==0)            {              delay(3);              if(add==0)               { while(!add);                 turn_val(hour,1,0x85,5);                }            }            if(dec==0)            {               delay(3);               if(dec==0)               { while(!dec);                 turn_val(hour,0,0x85,5);               }            }            }            if(s1num==6)//调时间分            {  minute=ReadSet);                write_com(0x80+0x40+5);                if(add==0)            {              delay(5);              if(add==0)               { while(!add);                 turn_val(minute,1,0x83,6);                //写入分寄存器                   }            }            if(dec==0)            {               delay(3);               if(dec==0)               { while(!dec);                 turn_val(minute,0,0x83,6);                //写入分寄存器               }            }            }            if(s1num==7)//调时间秒            {    second=ReadSet);                write_com(0x80+0x40+8);//秒光标                if(add==0)            {              delay(3);              if(add==0)               { while(!add);                 if(second==0x60)                    second=0x00;                     turn_val(second,1,0x81,7);                    }            }            if(dec==0)            {               delay(3);               if(dec==0)               { while(!dec);                 turn_val(second,0,0x81,7);                               }            }            }
            if(s1num==8)            {    miao=ReadSet);                second=                WriteSet,second&0x7f);                s1num=0;//s1num清零//                write_com(0x0c);//光标不闪烁//                            }        }    }    }} void delay_18B20(unsigned int i)//延时1微秒{     while(i--);}void ds1820rst()/*ds1820复位*/ {  unsigned char x=0;     DQ = 1;          //DQ复位     delay_18B20(4);  //延时     DQ = 0;          //DQ拉低     delay_18B20(100); //精确延时大于480us     DQ = 1;          //拉高     delay_18B20(40);        }      uchar ds1820rd()/*读数据*/  { unsigned char i=0;     unsigned char dat = 0;     for (i=8;i&0;i--)     {   DQ = 0; //给脉冲信号          dat&&=1;          DQ = 1; //给脉冲信号          if(DQ)          dat|=0x80;          delay_18B20(10);     }     return(dat);  }   void ds1820wr(uchar wdata)/*写数据*/  {unsigned char i=0;    for (i=8; i&0; i--)   { DQ = 0;     DQ = wdata&0x01;     delay_18B20(10);     DQ = 1;     wdata&&=1;   } }read_temp()/*读取温度值并转换*/ {uchar a,b;  ds1820rst();      ds1820wr(0xcc);//*跳过读序列号*/  ds1820wr(0x44);//*启动温度转换*/  ds1820rst();      ds1820wr(0xcc);//*跳过读序列号*/   ds1820wr(0xbe);//*读取温度*/   a=ds1820rd();  b=ds1820rd();  tvalue=b;  tvalue&&=8;  tvalue=tvalue|a;    if(tvalue&0x0fff)   tflag=0;    else   {tvalue=~tvalue+1;     tflag=1;   }  tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数    return(tvalue);  }void ds1820disp()//温度值显示    {      disdata[0]=tvalue/;//百位数     disdata[1]=tvalue%x30;//十位数     disdata[2]=tvalue%100/10+0x30;//个位数     disdata[3]=tvalue%10+0x30;//小数位      if(tflag==0)        flagdat=0x20;//正温度不显示符号     else       flagdat=0x2d;//负温度显示负号:-      if(disdata[0]==0x30)       {disdata[0]=0x20;//如果百位为0,不显示         if(disdata[1]==0x30)          {disdata[1]=0x20;//如果百位为0,十位为0也不显示          }        }        write_com(0xc9);       write_date(flagdat);//显示符号位       write_com(0xca);       write_date(disdata[0]);//显示百位       write_com(0xcb);       write_date(disdata[1]);//显示十位            write_com(0xcc);       write_date(disdata[2]);//显示个位            write_com(0xcd);       write_date(0x2e);//显示小数点            write_com(0xce);       write_date(disdata[3]);//显示小数位       write_com(0xcf);       write_date('C');   }void main(){        init();    Init_DS1302();       //将1302初始化     read_temp();//读取温度    ds1820disp();//显示    while(1)    {      read_date();      key_scan();      read_temp();//读取温度     ds1820disp();//显示     } }
赞助商链接
代码发上来给你看看啊,
赞助商链接
发个代码、照片上来吧,这样大家判断问题也容易些~~~
建议先用万用表检查所有连接1602的线是否有虚焊或接触不良, 下一步才检查源程序是否有问题, 所以先处理好硬件才检测软件.
我的1602屏显示字符也是这样的,最后换了个片子 就正常了
代码已经在一楼放出,麻烦帮忙看看,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,实在没辙了,请大神帮帮忙~~~
代码已经在一楼放出,麻烦帮忙看看,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,实在没辙了,请大神帮帮忙~~~
代码已在一楼放出,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,请大神帮帮忙~~~
估计是DS1302时钟芯片未能读取数据, 检查相关数据线是否接触不良, 如可以上传制作实物和显示问题相片给大家一起研究解决.
你意思是换块板子重新焊接~~~好坑爹的方法~~~这个方法等到实在没办法的时候再用~~~
好吧,我尽量吧,因为乱码滚动比较快,手机有压力,我拍个视频然后截个动态图片
还有忘说了,程序里面有些语句貌似是没用到的,因为是从网上down的一个功能比较少,仿真没问题,实物就是问题多多呀,
问题已解决,换了块单片机就好了,貌似是我单片机某个引脚有问题,乱码消失了,至于第一幅图片里面第一行黑块需要复位下,是因为1602覆盖在单片机上影响接电,我只好先拿掉1602接好电后才插上1602就导致了需要复位才正常显示,后来又出现新问题,最终也解决了,下面把我后来遇到的问题,就是显示部分显示不正常,不走动,然后调节时间也是错乱的,因为我用的stc89c52(说实话我只熟悉这一款)P0/P1/P2/P3 是准双向口/弱上拉,那么就需要在ds1302 I/O加一个上拉(网上也有说io、sclk、rst都加上拉,我没试过,大家可以先试试给io加个上拉,不行再给另外两个也加上),具体就是这样,作为一个菜鸟,我也不知道分析的对不对,不过怎么说问题还是解决了,就给各位做个参考,让大家少走弯路~~~
好吧,此贴终结!
DS1302的3条数据线和DS18B20的DQ线一般都加上拉电阻传送数据时较为稳定, 楼主吸收了宝贵的实践经验, 继续加油.
引用第9楼zichuanliufe于 19:35发表的 回 4楼(ccfx) 的帖子 :你意思是换块板子重新焊接~~~好坑爹的方法~~~这个方法等到实在没办法的时候再用~~~ 一点都不坑爹,我曾经一块做下载板,之前正常,放一段时间后怎么弄都不行,最后气的重新做一个,好了
其实,有个逻辑分析仪的话,问题瞬间解决。
感觉像时序的问题&&你用的什么片子来着?&&网上下的程序 仿真没问题&&实际有时候要自己改延时呀什么的
学习!字数补丁,嘿嘿!
查看完整版本: [--
Powered by
Gzip enabled

参考资料

 

随机推荐