[求助] 大家能给我分析一下怎么回事吗?近期再做一个ds1302的万年历,一直读不出数来

18811707971   2015-11-5 15:16 楼主
/*2015_11-02*/
#include
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
       
#define lcd_date P0
#define delay5us(){_nop_();_nop_();_nop_();_nop_();_nop_();}

uchar a,miao,shi,fen,ri,yue,nian,week,keynum,temp,count;
uchar code set_time[7]={0x00,0x46,0x11,0x26,0x10,0x06,0x14};

uchar time_buf[]="date:00-00-00";
uchar time_buf1[]="time:00:00:00";

bit c_moon;
data uchar year_moon,month_moon,day_moon;

//??1602????
sbit lcdrs=P0^0;
sbit lcden=P0^2;
sbit lcdrw=P0^1;

//DS1302???????

sbit DS_reset=P1^3;
sbit DS_io=P1^2;
sbit DS_sclk=P1^1;

sbit ACC0=ACC^0;//?????
sbit ACC7=ACC^7;

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

void delayms(uchar x)
{
        uchar t;
        while(x--)
    for(t=0;t<120;t++);
}

void lcd_busy_wait()
{
uchar Hi,Lo;
        do
        {
                lcd_date |=0xf0;//4?????????????
                lcdrs=0;
                lcdrw=1;//??????? ?
                lcden=1;
                delay5us();
                Hi=lcd_date;
                delay5us();
                lcden=0;
                delay5us();
                lcden=1;
                delay5us();
                Lo=lcd_date;
                delay5us();
                lcden=0;
                delay5us();
        }
        while(Hi&0x80);
}

void lcd_1602_write_com(uchar com)   
{
        lcd_busy_wait();//?????
        lcd_date=com&0xf0|0x04;//?????,?????rs,rw,en?????
        delay5us();
        lcden=0;
        delay5us();
        lcd_date=com<<4|0x04;//?????
        delay5us();
        lcden=0;
        delay5us();
}       

void lcd_1602_write_dat(uchar dat)
{
        lcd_busy_wait();//?????
        lcd_date=dat&0xf0|0x05;//?????
        delay5us();
        lcden=0;
        delay5us();
        lcd_date=dat<<4|0x05;//?????
        delay5us();
        lcden=0;
        delay5us();
}


void lcd_string(uchar r,uchar c,char *str)
{
        uchar i=0;
        code uchar ddram[]={0x80,0xc0};//???????????
         lcd_1602_write_com(ddram[r]|c);//????????
        //?????
        for(i=0;i<16&&str[i]!= '\0';i++)
                {
                        lcd_1602_write_dat(str[i]);
                }
}

void Lcd_1602_init()
{
        lcd_date=0xff;//?????????????
        lcd_date=0x24;//4???,?lcden,lcdrw,lcdrs=100(4),?????????
        lcden=0;//?????????

        lcd_1602_write_com(0x28); //4?,2?,5x7??          
          delayms(15);                          
          lcd_1602_write_com(0x0c); //???
        delayms(15);
        lcd_1602_write_com(0x06);  //?????,????
        delayms(15);          
          lcd_1602_write_com(0x01);//??
        delayms(15);
        lcd_1602_write_com(0x02);//????????
        delayms(15);
        //        lcd_string(0,0,time_buf);
        //lcd_string(1,0,time_buf1);
}       


/*?DS1302?????????*/

void DS1302_write_byte(uchar inbyte)
{
   uchar i;
   for(i=0;i<8;i++)
   {
    DS_sclk=0;             //?????????
    if(inbyte&0x01) {DS_io=1;}
        else {DS_io=0;}
    DS_sclk=1;            //????????DS1302
    inbyte=inbyte>>1;
   }
}

uchar DS1302_read_byte()  //???DS1302????????
{
   uchar i,tp=0;

   for(i=0;i<8;i++)
   {
    if(DS_io==1) tp=tp|0x80;
      else tp=tp&0x7f;
    DS_sclk=1;             //?????
        _nop_();
    DS_sclk=0;       
    tp=tp>>1;
   }
   return (tp);
}

void DS1302_write(uchar cmd,uchar indata) //?DS1302??, ?DS1302?????????
{
   DS_sclk=0;
   DS_reset=1;
   DS1302_write_byte(cmd);
   DS1302_write_byte(indata);
   _nop_();
   DS_sclk=0;
   DS_reset=0;
}

uchar DS1302_read(uchar addr)        //?DS1302??,?DS1302???????
{
   uchar backdata;
   DS_reset=0;
   DS_sclk=0;
   DS_reset=1;
   DS1302_write_byte(addr);                      //????
   backdata=DS1302_read_byte();                  //?????
   DS_sclk=0;
   DS_reset=0;
   return (backdata);
}

void DS1302_timeset()
{
   uchar i;
   DS1302_write(0x8e,0x00);          //????,?????
   for (i=0;i<7;i++)
    {
         DS1302_write(0x80+2*i,set_time[i]);
        }
   DS1302_write(0x8e,0x80);          //???,????
}

void DS1302_init() //???DS1302??
{  
   DS_reset=0;
   DS_sclk=0;
   DS1302_timeset();
  }

void DS1302_get_time()
{
        uchar i,tp,add=0x81;

  DS1302_write(0x8e,0x80);
  for (i=0;i<7;i++)
   {
    tp=DS1302_read(add);
        add+=2;
        delay(1);
    time_buf[15-2*i]=tp%16;
        time_buf[14-2*i]=tp/16;
        time_buf1[i]=(tp/16)*10+tp%16;
   }
}

void main()
{
         lcd_1602_init();
delayms(15);        
        DS1302_init();
                while(1)
        {
                        //DS1302_init();
                DS1302_timeset();
                DS1302_get_time();
                lcd_string(0,0,time_buf);
                delayms(15);
                lcd_string(1,0,time_buf1);
        }
}


回复评论 (11)

1446707904373.jpg
点赞  2015-11-5 15:21

写了几个程序都是这种情况,不知道怎么回事了,还请大家多多帮忙
点赞  2015-11-5 15:22
引用: 18811707971 发表于 2015-11-5 15:22
写了几个程序都是这种情况,不知道怎么回事了,还请大家多多帮忙

有一个不是很懂得地方,ds1302读出的数据给1602来显示??
点赞  2015-11-5 15:23
引用: 18811707971 发表于 2015-11-5 15:23
有一个不是很懂得地方,ds1302读出的数据给1602来显示??

已经捣鼓啦很长一段时间了,本来觉得很简单,但一直没有攻克
点赞  2015-11-5 15:28
如果你自信自己了代码逻辑,时序都没问题,就检查一下你的硬件吧,DS1302电源电压是地否都正常
点赞  2015-11-5 16:24
还有,你的时间设置函数为什么在while循环中呢?
点赞  2015-11-5 16:31
看着头疼,我觉得你首先把几个问题解决

1.硬件方面的,至少 供电电压 是没问题的,这个都不对,就别说了;

ds1302读出来的是 时间值,从你显示的内容来看,确实,就是用来显示那个的。
但我个人觉得你最好先不要一下子就把读出来的数值写上去,鬼知道中间有没别的错误。
先在程序里,debug一下也好,串口打印也好,先看看(ds1302)读出来的内容是啥

当然,在此之前,先确认1302的读写对不对,1302不是标准spi,这一点一定要切记。
最好的办法确保你的基本读写是对的,比如找一个比较无害的寄存器,,写进去读出来,看对不对,当然最好试过几个不同的数值,以免误导了自己。

如果最后确认是 时序问题,还是好好调吧。
最好有个 逻辑分析仪 什么的看看,不然瞎猫死耗子没意思。

总之,事情要一步一步做。你这么一上来就代码,谁见了都会崩溃的。

最后,特别要说一点:
不要老是换不同的,写不同的程序,没必要,找一个差不多的,慢慢调才是正路。

相信我,你这种想法这种路数,我以前干多了,实在没啥卵用的说~~

好了祝你好运,如果你不太理解我说的,先把思路慢慢理顺,欢迎回帖~~
强者为尊,弱者,死无葬身之地
点赞  2015-11-5 19:53
引用: 辛昕 发表于 2015-11-5 19:53
看着头疼,我觉得你首先把几个问题解决

1.硬件方面的,至少 供电电压 是没问题的,这个都不对,就别说了 ...

好的,版主说的很有道理,硬件方面应该没问题,电压是对的,然后下载程序液晶上显示的都是全零,我想既然能够读出0来,初始化应该是没问题吧?但是时钟不走就不是很清楚怎么回事,继续加油吧,还是谢谢您的指导
点赞  2015-11-5 22:36
引用: dong2213dong 发表于 2015-11-5 16:31
还有,你的时间设置函数为什么在while循环中呢?

这个不对吗?
点赞  2015-11-5 22:38
引用: 18811707971 发表于 2015-11-5 22:36
好的,版主说的很有道理,硬件方面应该没问题,电压是对的,然后下载程序液晶上显示的都是全零,我想既然 ...

读出来是0,就没问题?
这个结论下的太苍白。
请用更加确切的方式确保读写正确。
强者为尊,弱者,死无葬身之地
点赞  2015-11-6 00:11
引用: 18811707971 发表于 2015-11-5 22:38
这个不对吗?

我没特别仔细的看你的程序,不过你设置时间无非是向芯片的寄存器写入数据,你不断的向里面写入相同的东西,假如你的读写成功了的话,读出的时间值会按正常时间发生变化吗,好比你隔一分钟把钟调回到8点,那什么时候钟才能显示9点呢,可能我没完全理解你的思路,仅供参考
点赞  2015-11-6 08:35
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复