单片机/MCUwilliam hill官网
直播中

laichiweng

10年用户 6经验值
擅长:连接器 存储技术 控制/MCU
私信 关注
[问答]

51单片机DS1302有问题 ,求大神解答

只显示时间,时间不动,而且不是初始化的时间。
求解救。

#include
#include
#define  uchar unsigned char
#define  uint unsigned int

//lcd1602
void delay10ms(uint c);   
void lcdwritecom(uchar com);
void lcdwritedata(uchar dat);
void lcdinit(void);
#define LCD P0
***it RS=P2^6;
***it RW=P2^5;
***it LCDE=P2^7;       
////////////////////////
//ds1302
***it SCLK=P3^6;
***it DSIO=P3^4;
***it RST=P3^5;
uchar ds1302read(uchar addr);
void ds1302write(uchar addr,uchar dat);
void ds1302init(void);
void ds1302readtime(void);
void lcddisplay(void);
uchar readaddr[7]={0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar writeaddr[7]={0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
uchar time[7]={0, 0, 0x12, 0x30, 0x03, 0x07, 0x14};
////////////////////////////////////////////////////

void main()
{
        lcdinit();
        ds1302init();
        while(1)
        {
                ds1302readtime();
                lcddisplay();
        }
}





void lcddisplay(void)
{
        lcdwritecom(0x80+0x40);
        lcdwritedata('0'+time[2]/16);
        lcdwritedata('0'+(time[2]&0x0f));
        lcdwritedata('-');
        lcdwritedata('0'+time[1]/16);
        lcdwritedata('0'+(time[1]&0x0f));
        lcdwritedata('-');
        lcdwritedata('0'+time[0]/16);
        lcdwritedata('0'+(time[0]&0x0f));
        lcdwritecom(0x80);
        lcdwritedata('2');
        lcdwritedata('0');
        lcdwritedata('0'+time[6]/16);
        lcdwritedata('0'+(time[6]&0x0f));
        lcdwritedata('-');
        lcdwritedata('0'+time[4]/16);
        lcdwritedata('0'+(time[4]&0x0f));
        lcdwritedata('-');
        lcdwritedata('0'+time[3]/16);
        lcdwritedata('0'+(time[3]&0x0f));
        lcdwritecom(0x8D);
        lcdwritedata('0'+(time[5]&0x07));       
}


/*******************************************************************************
* 函 数 名         : ds1302readtime
* 函数功能                   : 读取ds1032时间
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void ds1302readtime(void)
{
        uchar n;
        for(n=0;n<7;n++)
        {
                time[n]= ds1302read(readaddr[n]);
        }
}
/*******************************************************************************
* 函 数 名         : ds1302init
* 函数功能                   :  ds1032初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void ds1302init(void)
{
        uchar n,tmp;
        for (n=0; n<7; n++)  
        {
                tmp = time[n] / 10;
                time[n] = time[n] % 10;
                time[n] = time[n] + tmp*16;
        }
        ds1302write(0x8E,0x00);
        for(n=0;n<7;n++)
        {
                 ds1302write(writeaddr[n],time[n]);
        }
        ds1302write(0x8E,0x80);
}
/*******************************************************************************
* 函 数 名         : ds1302read
* 函数功能                   :  ds1032读操作
* 输    入         : uchar addr
* 输    出         : 无
*******************************************************************************/
uchar ds1302read(uchar addr)
{
        uchar n,dat,dat1;
        RST=0;
        _nop_();
        SCLK=0;
        _nop_();_nop_();_nop_();
        RST=1;
        _nop_();
        for(n=0;n<8;n++)
        {
                DSIO=addr&0x01;
                addr>>=1;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        _nop_();
        for(n=0;n<8;n++)
        {
                dat1=DSIO;
                dat=dat>>1;
                dat1=dat1<<7;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        RST=0;
        _nop_();
        SCLK=1;
        _nop_();
        DSIO=0;
        _nop_();
        DSIO=1;
        _nop_();
        return dat;
}
/*******************************************************************************
* 函 数 名         : ds1302write
* 函数功能                   :  ds1032写操作
* 输    入         : uchar addr ,dat
* 输    出         : 无
*******************************************************************************/
void ds1302write(uchar addr,uchar dat)
{
        uchar n;
        RST=0;
        _nop_();
        SCLK=0;
        _nop_();_nop_();_nop_();
        RST=1;
        _nop_();
        for(n=0;n<8;n++)
        {
                DSIO=addr&0x01;
                addr>>=1;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        for(n=0;n<8;n++)
        {
                DSIO=dat&0x01;
                dat>>=1;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        RST=0;
        _nop_();
}


/*******************************************************************************
* 函 数 名         : lcdwritecom
* 函数功能                   :   LCD写指令
* 输    入         : uchar com
* 输    出         : 无
*******************************************************************************/
void lcdwritecom(uchar com)
{
        LCDE=0;
        RS=0;
        RW=0;
        LCD=com;
        delay10ms(1);
        LCDE=1;
        delay10ms(1);
        LCDE=0;
}
/*******************************************************************************
* 函 数 名         : lcdwritedata
* 函数功能                   : LCD写数据
* 输    入         : uchar dat
* 输    出         : 无
*******************************************************************************/

void lcdwritedata(uchar dat)
{
        LCDE=0;
        RS=1;
        RW=0;
        LCD=dat;
        delay10ms(1);
        LCDE=1;
        delay10ms(1);
        LCDE=0;
}

/*******************************************************************************
* 函 数 名         : delay10ms
* 函数功能                   : 延时 10ms
* 输    入         : uint c
* 输    出         : 无
*******************************************************************************/
void delay10ms(unsigned int c)   
{
    unsigned char a, b;
    for (;c>0;c--)
        {
                for (b=38;b>0;b--)
                {
                        for (a=130;a>0;a--) ;
                }         
        }      
}

/*******************************************************************************
* 函 数 名         : lcdinit
* 函数功能                   : 初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void lcdinit(void)
{
        lcdwritecom(0x38);
        lcdwritecom(0x0c);
        lcdwritecom(0x01);
        lcdwritecom(0x06);
        lcdwritecom(0x80);
}

回帖(4)

军少

2014-3-31 16:38:56
可能是你液晶和DS1302初始化没有加延时   
  lcdinit();
delay_ms(100);
        ds1302init();  
delay_ms(100);
举报

陈锐文

2014-3-31 20:09:12
又经过本人亲身测试,发现你的程序有一些问题。第一:DS1302初始化有问题,
  1. void ds1302init(void)
  2. {
  3.         uchar n,tmp;
  4.         for (n=0; n<7; n++)  
  5.         {
  6.                 tmp = time[n] / 10;
  7.                 time[n] = time[n] % 10;
  8.                 time[n] = time[n] + tmp*16;
  9.         }
  10.         ds1302write(0x8E,0x00);
  11.         for(n=0;n<7;n++)
  12.         {
  13.                  ds1302write(writeaddr[n],time[n]);
  14.         }
  15.         ds1302write(0x8E,0x80);
  16. }

第一个for循环可以去掉,根本不用什么转换了,比如time[7]={0, 0, 0x12, 0x30, 0x03, 0x07, 0x14};
直接保存进去就是2014-03-30 12-00-00了。
第二:你程序不能正常显示是因为你的读取有问题,以此总是显示0.我发我改过后的程序给你,不懂再来问。
  1. void ds1302init(void)
  2. {
  3.         uchar n;                   //temp也不要了
  4. /*        for (n=0; n<7; n++)  
  5.         {
  6.                tmp = time[n] / 10;
  7.                time[n] = time[n] % 10;
  8.                time[n] = time[n] + tmp*16;
  9.         }    */           //这部分可以去掉
  10.         ds1302write(0x8E,0x00);
  11.         for(n=0;n<7;n++)
  12.         {
  13.                  ds1302write(writeaddr[n],time[n]);
  14.         }
  15.         ds1302write(0x8E,0x80);
  16. }
  1. uchar ds1302read(uchar addr)
  2. {
  3.         uchar n,dat;                                         //dat1去掉
  4.         RST=0;
  5.         _nop_();
  6.         SCLK=0;
  7.         _nop_();_nop_();_nop_();
  8.         RST=1;
  9.         _nop_();
  10.         for(n=0;n<8;n++)
  11.         {
  12.                 DSIO=addr&0x01;
  13.                 addr>>=1;
  14.                 SCLK=1;
  15.                 _nop_();
  16.                 SCLK=0;
  17.                 _nop_();
  18.         }
  19.         _nop_();
  20.         for(n=0;n<8;n++)
  21.         {
  22. //               dat1=DSIO;                           // 这句不要
  23.                 dat=dat>>1;
  24. //               dat=dat1<<7;                   // 这句也不要

  25.                                 if(DSIO)                                  //我换一个方法,DSIO为1的时候最高位为1,否则为0
  26.                                 {
  27.                                          dat|=0x80;                        //每次传输低字节
  28.                                 }
  29.                 SCLK=1;
  30.                 _nop_();
  31.                 SCLK=0;
  32.                 _nop_();
  33.         }
  34.         RST=0;
  35.         _nop_();
  36.         SCLK=1;
  37.         _nop_();
  38.         DSIO=0;
  39.         _nop_();
  40.         DSIO=1;
  41.         _nop_();
  42.         return dat;
  43. }
举报

MR Wang

2014-4-1 10:13:25
直接对时间数据进行赋值,调试一下看看是DS1302的问题还是液晶的问题。
举报

z00

2014-4-1 22:40:42
主程序死循环中应该加较长时间的延时才好
举报

更多回帖

发帖
×
20
完善资料,
赚取积分