找回密码
 注册会员
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

求各路大侠批评指导 DS1302 错哪里了呢?

[复制链接]
xiong57785 发表于 2011-7-25 17:36:36 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
[attachimg]1303
QQ截图未命名.png
include <regx52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit RS=P2^4;
sbit RW=P2^5;
sbit E=P2^6;

sbit io=P3^4;
sbit rst=P3^5;
sbit sclk=P3^6;


uchar bdata ds,dt;
sbit ds0=ds^0;
sbit dt7=dt^7;

uchar idata lcddate[]={" 2011-07-25 1"};
uchar idata lcdtime[]={" 00:00:00"};
uchar table[]={"0123456789"};

uchar m,ms,mg;                  // 秒
uchar f,fs,fg;                 //分
uchar s,ss,sg;                 //时
uchar r,rs,rg;                  //日
uchar x,xs,xg;                 //星期
uchar y,ys,yg;                 //月
uchar n,ns,ng;                 //年

uchar temp;

void delay(uint z);
void w1602_data(uchar dt1602);
void w1602_com(uchar com);
void dis_lcd(uchar adr,uchar *temp,uint length)        ;
void init_1602();          //初始化1602
void busy();
void lcd_reset();
void w1302_data(uchar adr,uchar dt1302)        ;
uchar  r1302_data(uchar adr);
void init_1302();
void read_1302();

void main()
{       

        init_1602();        //1602初始化
        lcd_reset();        //1602复位
        init_1302();        //1302初始化

        dis_lcd(0x80+0x01,lcddate,13);
        dis_lcd(0x80+0x43,lcdtime,9);
        while(1);

        while(1)
        {
                read_1302();
                dis_lcd(0x80+0x02,lcddate,13);
                dis_lcd(0x80+0x41,lcdtime,9);
                                       
        }          
                       
}

void delay(uint z)
{
        uint x;
        for(;z>2;z--)
                for(x=175;x>0;x--);
               
}
/************************************************************************

                                                1602

*************************************************************************/


void w1602_data(uchar dt1602)                //向1602中写数据
{
        RS=1;
        RW=0;
        P0=dt1602;
        E=1;
        E=0;                                                
}

void w1602_com(uchar com)           //向1602中写命令
{
        RS=0;
        RW=0;
        P0=com;
        E=1;
        E=0;

}

void dis_lcd(uchar adr,uchar *temp,uint length)                   //1602显示
{
        uint i;

        w1602_com(adr);
        delay(10);
        for(i=0;i<length;i++)
        {
                w1602_data(temp);
                delay(10);       
        }
}


void init_1602()          //初始化1602
{
        uint num;

        delay(15);
        for(num=0;num<2;num++)
        {
                w1602_com(0x38);
                delay(5);
        }
        busy();
        w1602_com(0x38);
        busy();
        w1602_com(0x08);
        busy();
        w1602_com(0x01);
        busy();
        w1602_com(0x06);
        busy();
        w1602_com(0x0c);


       
}

void busy()                                //1602忙检测
{
        {

                temp=0xff;
                RS=0;
                RW=1;
                E=1;
                E=0;
                temp=P0;
                       
        }while((temp&0x80)==0x80);
}



void lcd_reset()
{
        w1602_com(0x01);
        delay(5);
        w1602_com(0x06);
        delay(5);
        w1602_com(0x0c);
        delay(5);       
}
/****************************************************************

                                        DS1302

*****************************************************************/
void w1302_data(uchar adr,uchar dt1302)                                         //向DS1302中写入数据
{
        uint i;

        ds=adr;
        sclk=0;
        rst=0;
        rst=1;
        for(i=0;i<8;i++)          //写入控制字节
        {
                sclk=0;
                io=ds0;
                sclk=1;
                ds>>=1;
        }


        ds=dt1302;
        for(i=0;i<8;i++)    //写入数据
        {
                ds>>=1;       
                sclk=0;
                io=ds0;
                sclk=1;
        }
        sclk=0;
        rst=0;
}

uchar  r1302_data(uchar adr)         //读取DS1302中的数据
{
        uint i;

        ds=adr;
        rst=0;
        sclk=0;
        rst=1;
       
        for(i=0;i<8;i++)          //写入控制字节
        {
         
                ds>>=1;       
                sclk=0;       
                io=ds0;
                sclk=1;
        }
       
        for(i=0;i<8;i++)         //读取数据
        {
                sclk=1;
                dt>>=1;
                sclk=0;
                dt7=io;       
        }
        sclk=0;
        rst=0;
        return dt;       
}

void init_1302()
{
        w1302_data(0x8e,0x00);
        w1302_data(0x90,0xaa);
        w1302_data(0x80,0x80);
        w1302_data(0x83,0x00);
        w1302_data(0x84,0x00);
        w1302_data(0x86,0x00);
        w1302_data(0x88,0x00);
        w1302_data(0x8a,0x00);
        w1302_data(0x8c,0x09);
               
}

void read_1302()
{
                m=r1302_data(0x81);
                ms=m>>4;
                mg=m&0x0f;
                f=r1302_data(0x83);
                fs=f>>4;
                fg=f&0x0f;
                s=r1302_data(0x85);
                ss=s>>4;       
                sg=s&0x0f;
                r=r1302_data(0x87);
                rs=r>>4;
                rg=r&0x0f;
                y=r1302_data(0x89);
                ys=y>>4;
                yg=y&0x0f;
                x=r1302_data(0x8b);
                n=r1302_data(0x8d);
                ns=n>>4;
                ng=n&0x0f;

                lcddate[3]=table[ns];
                lcddate[4]=table[ng];
                lcddate[6]=table[ys];
                lcddate[7]=table[yg];
                lcddate[9]=table[rs];
                lcddate[10]=table[rg];
                lcddate[12]=table[x];
                lcdtime[1]=table[ss];
                lcdtime[2]=table[sg];
                lcdtime[4]=table[fs];
                lcdtime[5]=table[fg];
                lcdtime[7]=table[ms];
                lcdtime[8]=table[mg];

}

1602部分程序没错 主要是DS1302的 还有一个疑问1602时序图上的RS为什么那么画 高电平就高电平 低就低 为什么要花到一个图上去
 楼主| xiong57785 发表于 2011-7-25 17:42:24 | 显示全部楼层
粘错了 把主程序中while(1);去掉
admin 发表于 2011-7-25 19:00:04 | 显示全部楼层
楼主描述详细点  如果是无法编译 请帖处错误代码  如果不是按你的思路工作请仔细描述下
 楼主| xiong57785 发表于 2011-7-25 19:38:29 | 显示全部楼层
#include <regx52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit RS=P2^4;
sbit RW=P2^5;
sbit E=P2^6;

sbit io=P3^4;
sbit rst=P3^5;
sbit sclk=P3^6;


uchar bdata ds,dt;
sbit ds0=ds^0;
sbit dt7=dt^7;

uchar idata lcddate[]={" 2011-07-25 1"};
uchar idata lcdtime[]={" 00:00:00"};
uchar table[]={"0123456789"};

uchar m,ms,mg;                  // 秒
uchar f,fs,fg;                 //分
uchar s,ss,sg;                 //时
uchar r,rs,rg;                  //日
uchar x,xs,xg;                 //星期
uchar y,ys,yg;                 //月
uchar n,ns,ng;                 //年

uchar temp;

void delay(uint z);
void w1602_data(uchar dt1602);
void w1602_com(uchar com);
void dis_lcd(uchar adr,uchar *temp,uint length)        ;
void init_1602();          //初始化1602
void busy();
void lcd_reset();
void w1302_data(uchar adr,uchar dt1302)        ;
uchar  r1302_data(uchar adr);
void init_1302();
void read_1302();

void main()
{       

        init_1602();        //1602初始化
        lcd_reset();        //1602复位
        init_1302();        //1302初始化

        dis_lcd(0x80+0x01,lcddate,13);
        dis_lcd(0x80+0x43,lcdtime,9);

        while(1)
        {
                read_1302();
                dis_lcd(0x80+0x01,lcddate,13);
                dis_lcd(0x80+0x43,lcdtime,9);
                                       
        }          
                       
}

void delay(uint z)
{
        uint x;
        for(;z>2;z--)
                for(x=175;x>0;x--);
               
}
/************************************************************************

                                                1602

*************************************************************************/


void w1602_data(uchar dt1602)                //向1602中写数据
{
        RS=1;
        RW=0;
        P0=dt1602;
        E=1;
        E=0;                                                
}

void w1602_com(uchar com)           //向1602中写命令
{
        RS=0;
        RW=0;
        P0=com;
        E=1;
        E=0;

}

void dis_lcd(uchar adr,uchar *temp,uint length)                   //1602显示
{
        uint i;

        w1602_com(adr);
        delay(10);
        for(i=0;i<length;i++)
        {
                w1602_data(temp[i]);
                delay(10);       
        }
}


void init_1602()          //初始化1602
{
        uint num;

        delay(15);
        for(num=0;num<2;num++)
        {
                w1602_com(0x38);
                delay(5);
        }
        busy();
        w1602_com(0x38);
        busy();
        w1602_com(0x08);
        busy();
        w1602_com(0x01);
        busy();
        w1602_com(0x06);
        busy();
        w1602_com(0x0c);


       
}

void busy()                                //1602忙检测
{
        {

                temp=0xff;
                RS=0;
                RW=1;
                E=1;
                E=0;
                temp=P0;
                       
        }while((temp&0x80)==0x80);
}



void lcd_reset()
{
        w1602_com(0x01);
        delay(5);
        w1602_com(0x06);
        delay(5);
        w1602_com(0x0c);
        delay(5);       
}
/****************************************************************

                                        DS1302

*****************************************************************/
void w1302_data(uchar adr,uchar dt1302)                                         //向DS1302中写入数据
{
               
       
        uint i;
        ds=adr;
        sclk=0;
        rst=0;
        rst=1;
        for(i=0;i<8;i++)          //写入控制字节
        {
                io=ds0;
                sclk=1;
                ds>>=1;
                sclk=0;
               
        }


        ds=dt1302;
        for(i=0;i<8;i++)    //写入数据
        {
                io=ds0;
                sclk=1;
                ds>>=1;
                sclk=0;
               
        }
        sclk=0;
        rst=0;
}

uchar  r1302_data(uchar adr)         //读取DS1302中的数据
{
        uint i;

        ds=adr;
        rst=0;
        sclk=0;
        rst=1;
        for(i=0;i<8;i++)          //写入控制字节
        {
                io=ds0;
                sclk=1;
                ds>>=1;
                sclk=0;
               
        }
       
        for(i=0;i<8;i++)         //读取数据
        {       
                dt>>=1;
                dt7=io;
                sclk=1;       
                sclk=0;
               
               
        }
        sclk=0;
        rst=0;
        return dt;       
}

void init_1302()
{
        w1302_data(0x8e,0x00); //关闭写保护
        w1302_data(0x90,0xaa); //供电方式
        w1302_data(0x80,0x00); //时钟运行 秒
        w1302_data(0x83,0x00);//分
        w1302_data(0x84,0x00);//   24小时
        w1302_data(0x86,0x25);//   日
        w1302_data(0x88,0x07);//        月
        w1302_data(0x8a,0x01);// 星期
        w1302_data(0x8c,0x11); // 年
               
}

void read_1302()
{
                m=r1302_data(0x81);
                ms=(m>>4);
                mg=m&0x0f;
                f=r1302_data(0x83);
                fs=(f>>4);
                fg=f&0x0f;
                s=r1302_data(0x85);
                ss=(s>>4);       
                sg=s&0x0f;
                r=r1302_data(0x87);
                rs=(r>>4);
                rg=r&0x0f;
                y=r1302_data(0x89);
                ys=(y>>4);
                yg=y&0x0f;
                x=r1302_data(0x8b);
                n=r1302_data(0x8d);
                ns=(n>>4);
                ng=n&0x0f;

                lcddate[3]=table[ns];
                lcddate[4]=table[ng];
                lcddate[6]=table[ys];
                lcddate[7]=table[yg];
                lcddate[9]=table[rs];
                lcddate[10]=table[rg];
                lcddate[12]=table[x];
                lcdtime[1]=table[ss];
                lcdtime[2]=table[sg];
                lcdtime[4]=table[fs];
                lcdtime[5]=table[fg];
                lcdtime[7]=table[ms];
                lcdtime[8]=table[mg];         


}
程序调好了 是向DS1302中初始化和LCDtime/date矛盾了 粗心了

 楼主| xiong57785 发表于 2011-7-25 19:49:14 | 显示全部楼层
QQ截图未命名.png
不过还有一点疑问 在DS1302的读程序中这段代码   
for(i=0;i<8;i++)         //读取数据
        {        
                dt>>=1;
                dt7=io;
                sclk=1;        
                sclk=0;
               
               
        }
为什么把          dt7=io;
放到               sclk=1;  sclk=0;前面就显示 而放后面就乱码 时序图上写的是在下降沿处DS1302输出第一位数据 如果先写dt7=io的话岂不是第一次读的数据没有意义吗? 望大虾指点一下
 楼主| xiong57785 发表于 2011-7-25 20:03:09 | 显示全部楼层
[还有个疑问就是1602中 QQ截图未命名3.png 读时序是RS为高电平    写数据时时序时RS为高电平 而时序图中却要画RS为如下 QQ截图未命名2.png
QQ截图未命名1.png
这是为什么呢 望大虾指点 感激不尽啊.......................................
 楼主| xiong57785 发表于 2011-7-26 11:41:16 | 显示全部楼层
大虾们帮忙看看啊
yanzh007 发表于 2011-7-29 16:00:00 | 显示全部楼层

RS的高低电平 分别对应读取的 数据与命令
*滑块验证:
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2024-11-23 10:49 , Processed in 0.059365 second(s), 12 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表