求教 关于DS1302时钟芯片时序程序(有尝的求救)
这几天在弄个1602液晶显示时钟,用DS1302时钟芯片提供时间;但在中途出现了点小问题,对着DS1302时序图写完这部分程序,想试试程序是否对,就用一个8个LED灯P0接收DS1302的数据,
如果8个LED灯发生变化说明没有对着时序图写的这部分驱动没问题,但发现并不这么理想,8个LED全亮(LED共阳),
没有发生变化,说明DS1302驱动程序那部分有问题;可调试了很久也不知道哪里出错了.望好心人大神们帮助下。
(很想知道哪里错了,有尝的求救,如果有意愿帮助指导下的,可以加我QQ1097957773,,谢谢)
以下是时序图:
以下是DS1302驱动部分程序:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
void DS1302_COMMAND_WRITE(uchar adr);
void DS1302_DATA_WRITE(uchar date);
void switch_10_16(uchar transition);
void delay(uint z);
void delaynop();
uchar receive_io,shift_date;
void delaynop()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************************/
/* */
/* DS1302时钟位定义 */
/* */
/***************************/
sbit RST=P2^0;
sbit io=P2^2;
sbit SCLK=P2^1;
/***************************************/
/* */
/* 延时函数 */
/* */
/***************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/***************************************/
/* */
/* DS1302时钟写保护函数 */
/* */
/***************************************/
void WRITE_PROTECT(uchar protect)
{
DS1302_COMMAND_WRITE(0x8E);//DS1302 CONTROL地址位
DS1302_DATA_WRITE(protect);//DS1302 CONTROL数据位
}
/*****************************************/
/* */
/* DS1302时钟地址写操作函数 */
/* */
/*****************************************/
void DS1302_COMMAND_WRITE(uchar adr)
{
uchar i;
RST=0;
SCLK=0;
RST=1; //高电平开始
delaynop();
for(i=0;i<8;i++)
{
adr=adr>>1;
io=adr&0x80;//1位送入DS1302芯片中
SCLK=1;//高脉冲送出数据
delaynop();
SCLK=0;
delaynop();
}
} //地址写完 SCLK为低电平
/***************************************/
/* */
/* DS1302时钟数据写操作函数 */
/* */
/***************************************/
void DS1302_DATA_WRITE(uchar date)
{
uchar i;
switch_10_16(date); //数值转换
for(i=0;i<8;i++)
{
io=shift_date&0x01; //低位与运算判断0和1
shift_date=shift_date>>1;//转换后的数据进行移位传输
SCLK=1;//高脉冲送出数据
delaynop();
SCLK=0;
delaynop();
}
SCLK=1;//写完后按时序图SCLK先置高
RST=0;//RST在置低
}
/***************************************/
/* */
/* DS1302时钟数据读操作函数 */
/* */
/***************************************/
void DS1302_READ(uchar adre)
{
uchar i;
receive_io=0;
DS1302_COMMAND_WRITE(adre);//写完地址后SCLK为低电平,需要一个高电平过度在开始读操作
SCLK=1;
delaynop();
for(i=0;i<8;i++)
{
SCLK=0;//低脉冲读走数据
delaynop();
receive_io=receive_io>>1;
if(io==1)
{
receive_io=receive_io|0x80;//高位补1
}
else
{
receive_io=receive_io|0x00;//高位补0
}
}
SCLK=1;
delaynop();
RST=0;
}
/*****************************************/
/* */
/* DS1302时钟总体写操作函数 */
/* */
/*****************************************/
void DS1302_WRITE(uchar adress,uchar dat)
{
DS1302_COMMAND_WRITE(adress);
DS1302_DATA_WRITE(dat);
}
/***************************************/
/* */
/* 发送_数值转换函数 */
/* */
/***************************************/
void switch_10_16(uchar transition)
{
uchar ge,shi;
shi=transition/10;
ge=transition%10;
shift_date=shi*16+ge;
}
void main()
{
WRITE_PROTECT(0x00);//去除写保护
delaynop();
DS1302_WRITE(0x80,13);
delaynop();
while(1)
{
DS1302_READ(0x81);
delaynop();
P0=receive_io;
}
}
玩DS1302最难的地方在于读完后紧接着写,
建议你再好好研究一下这段,
实在弄不出来,我给你一份调试通过的。 horalxi 发表于 2012-9-8 13:50 static/image/common/back.gif
玩DS1302最难的地方在于读完后紧接着写,
建议你再好好研究一下这段,
实在弄不出来,我给你一份调试通过的 ...
我已经调试了1天多了,从头到尾都看了,可也弄不出来,你能留个QQ吗? physics 发表于 2012-9-8 17:27 static/image/common/back.gif
网上很多,找找看吧
你帮我看看我程序 时序那里有错好吗?网上的都看过. 很想知道哪里错了
basically, very poor structuring of your code. you should try to use 1 routine to send a byte to the chip and another routine to read a byte from the chip, and build the rest of the routines from that.
try this one#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
void DS1302_COMMAND_WRITE(uchar adr);
void DS1302_DATA_WRITE(uchar date);
void switch_10_16(uchar transition);
void delay(uint z);
void delaynop();
uchar receive_io,shift_date;
void delaynop()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/***************************/
/* */
/* DS1302????? */
/* */
/***************************/
sbit RST=P2^0;
sbit io=P2^2;
sbit SCLK=P2^1;
/***************************************/
/* */
/* ???? */
/* */
/***************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//reset the bus
void DS1302_INIT(void) {
RST=0;
SCLK=0;
}
/*****************************************/
/* */
/* DS1302????????? */
/* */
/*****************************************/
void DS1302_BYTE_WRITE(uchar adr)
{
uchar i;
//RST=0;
//SCLK=0;
//RST=1; //?????
//delaynop();
for(i=0;i<8;i++)
{
SCLK = 0; //reset sclk to idle
//adr=adr>>1;
io=(adr&0x01)?1:0;//1???DS1302???
//delaynop();
SCLK=1;//???????
adr = adr >> 1;
//SCLK=0;
//delaynop();
}
} //???? SCLK????
uchar DS1302_BYTE_READ(void)
{
uchar adr=0; //temp variable
uchar i;
//RST=0;
//SCLK=0;
//RST=1; //?????
//delaynop();
io = 1; //wait to read io
for(i=0;i<8;i++)
{
SCLK = 0; //reset sclk to idle
adr=adr>>1;
//delaynop();
adr |= (io)? 0x80: 0x00; //=(adr&0x01)?1:0;//1???DS1302???
SCLK=1;//???????
//SCLK=0;
//delaynop();
}
return adr; //return the value
} //???? SCLK????
/***************************************/
/* */
/* DS1302??????? */
/* */
/***************************************/
void xWRITE_PROTECT(uchar protect)
{
DS1302_BYTE_WRITE(0x8E);//DS1302 CONTROL???
DS1302_BYTE_WRITE(protect);//DS1302 CONTROL???
}
/***************************************/
/* */
/* DS1302????????? */
/* */
/***************************************/
void xDS1302_DATA_WRITE(uchar date)
{
uchar i;
switch_10_16(date); //????
for(i=0;i<8;i++)
{
io=shift_date&0x01; //???????0?1
shift_date=shift_date>>1;//????????????
SCLK=1;//???????
delaynop();
SCLK=0;
delaynop();
}
SCLK=1;//???????SCLK???
RST=0;//RST???
}
/***************************************/
/* */
/* DS1302????????? */
/* */
/***************************************/
uchar DS1302_READ(uchar adre)
{
uchar i;
//receive_io=0;
//reset the bus
RST=0;
SCLK=0;
RST=1; //?????
DS1302_BYTE_WRITE(adre);//?????SCLK????,???????????????
i=DS1302_BYTE_READ();
//return the bus to idle
SCLK=0;
RST=0;
return i; //return the value
/* SCLK=1;
delaynop();
for(i=0;i<8;i++)
{
SCLK=0;//???????
delaynop();
receive_io=receive_io>>1;
if(io==1)
{
receive_io=receive_io|0x80;//???1
}
else
{
receive_io=receive_io|0x00;//???0
}
}
SCLK=1;
delaynop();
RST=0;
*/
}
/*****************************************/
/* */
/* DS1302????????? */
/* */
/*****************************************/
void DS1302_WRITE(uchar adress,uchar dat)
{
//reset the bus
RST=0;
SCLK=0;
RST=1; //?????
DS1302_BYTE_WRITE(adress);
DS1302_BYTE_WRITE(dat);
//return the bus to idle
SCLK=0;
RST=0;
}
/***************************************/
/* */
/* ??_?????? */
/* */
/***************************************/
uchar dec2bcd(uchar dec)
{
/* uchar ge,shi;
shi=transition/10;
ge=transition%10;
shift_date=shi*16+ge;
*/
return ((dec / 10) << 4) | (dec % 10);
}
void main()
{
DS1302_INIT(); //reset the bus
//WRITE_PROTECT(0x00);//?????
DS1302_WRITE(0x8e, 0x00);
delaynop();
DS1302_WRITE(0x80,13);
delaynop();
while(1)
{
receive_io= DS1302_READ(0x81);
delaynop();
P0=receive_io;
}
}
it is largely based on yours, but not fully cleaned up. millwood0 发表于 2012-9-8 22:27 static/image/common/back.gif
basically, very poor structuring of your code. you should try to use 1 routine to send a byte to t ...
I try your program that you give me ,Althoughprogram can't work normally, but thank you all the same.
/*****************************************/
/* */
/* DS1302时钟地址写操作函数 */
/* */
/*****************************************/
void DS1302_COMMAND_WRITE(uchar adr)
{
uchar i;
RST=0;
SCLK=0;
RST=1; //高电平开始
delaynop();
for(i=0;i<8;i++)
{
adr=adr>>1; //这句应该往下面移
io=adr&0x80;//1位送入DS1302芯片中 //这句改为 io=adr&0x01;
SCLK=1;//高脉冲送出数据
delaynop();
SCLK=0;
delaynop();
}
} //地址写完 SCLK为低电平 here is the code I posted, outputting receive_io on p3.
the rtc was reset to 13 (0x13 in bcd format) initially.
so from 1s - 2s, the second should be 13 (0x14 in bcd format). that corresponds to P3.4 = 1, P3.2 = 1, and P3.x cleared -> P3 = 0x14, as you can see on the chart.
from 6 - 7s, the second should be 19 (0x19 in bcd format). P3 reads 0x19, correctly.
from 7s - 8s, the second will advance to 20, which causes the bcd reading to go from 0x19 to 0x20. You can see that there.
If the code I posted doesn't work on your hardware, you have other problems.
xtl2012 发表于 2012-9-8 17:18 static/image/common/back.gif
我已经调试了1天多了,从头到尾都看了,可也弄不出来,你能留个QQ吗?
别着急,以前我调试的时候,弄了一个星期,后来发现了问题点,茅塞顿开,以后再调试DS1302就如鱼得水了。
qq:157185173 zyyn123 发表于 2012-9-8 23:45 static/image/common/back.gif
/*****************************************/
/* */
/* ...
嗯,发现了.谢谢你! DS1302驱动弄好了.花了两天时间调试,谢谢热心的网友们!谢谢!!!{:smile:} horalxi 发表于 2012-9-9 12:11 static/image/common/back.gif
别着急,以前我调试的时候,弄了一个星期,后来发现了问题点,茅塞顿开,以后再调试DS1302就如鱼得水了。 ...
大侠,你好,我现在DS1302出现一个问题,就是大多情况下,我读出DS1302大多数次都能读出正确值,但是偶尔就会读出错误的一次日期值,我在读DS1302都有禁止中断。我用了纽扣电池,设置了下寄存器!也起作用了,但是就是偶尔会给我读出一个错误的日期值,请问,这种问题是什么情况哇?
页:
[1]