本帖最后由 cjunrong 于 2012-11-20 16:14 编辑
各位,我用
单片机驱动DS1302的时候遇到了一点问题,在读取数据的时候,使用下面的程序时读取的数值总是错误的,
for(i=0;i<8;i++)
{
ds1302_SCLK=1;
ds1302_SCLK=0;
if(ds1302_IO==1)
date=date|0x80;
date>>=1;
}
而使用下面的程序的时候就是正确的
for(i=0;i<8;i++)
{
if(ds1302_IO)
date|=0x80; //每次传输低字节
ds1302_SCLK=0;
date>>=1; //右移一位
ds1302_SCLK=1;
}
看资料说是在下降沿读走数据,而这对于这两个函数断,为啥第一个不行,而第二个行,小弟实在是搞不明白,还望哪位大侠指点一下...!
非常感谢...!
还是有一点不明白,说是在下降沿送出数据,可为什么写程序是先写下降沿再写读数据就不行,而先写读数据再写下降沿就行...!这点老是想读懂,以下是修改后的程序,/**/注释掉的是可以正常工作的,没有注释掉的读出的数据有误...!
已定义过#define uchar unsigned char
uchar ds1302_read_byte(uchar address)
{
uchar date,i,temp;
temp=address;
ds1302_CE=0;
ds1302_SCLK=0;
ds1302_IO=0;
ds1302_CE=1;
//写地址
for(i=0;i<8;i++)
{
ds1302_SCLK=0;
ds1302_IO=temp&0x01;
temp>>=1;
ds1302_SCLK=1;
}
//读数据
for(i=0;i<8;i++)
{
ds1302_SCLK=0;
if(ds1302_IO==1)
date=date|0x80;
date>>=1;
ds1302_SCLK=1;
/*if(ds1302_IO)
date|=0x80; //每次传输低字节
ds1302_SCLK=0;
date>>=1; //右移一位
ds1302_SCLK=1; */
}
ds1302_CE=0;
return date;
}
非常感谢,祝生活愉快...!
时序 是没有问题。。。。
很奇怪,你修改了上面写数据那段代码之后,然后再采用 原来 注释掉的内容可以运行成功么,,,感觉不可以才对啊 。。。。。
仔细分析下,两端代码的异同,现在我怀疑是 ds1302芯片的 反应速度不够,所以现在每次下降沿后给一个小的延时,,你再试试。。。当然延时我只是大概给的,可能会影响速度,你可以试一下减少延时的时间,测一下极限
- void delay(unsigned char i)
- {
- unsigned char j;
- for( ; i > 0; i--)
- {
- for(j = 50; j > 0; j--)
- ;
- }
- }
- uchar ds1302_read_byte(uchar address)
- {
- unsigned char date,i,temp;
- temp=address;
- ds1302_CE=0;
- ds1302_SCLK=0;
- ds1302_IO=0;
- ds1302_CE=1;
- //写地址
- for(i=0;i<8;i++)
- {
- ds1302_SCLK=0;
- ds1302_IO=temp&0x01;
- temp>>=1;
- ds1302_SCLK=1;
- }
-
- ds1302_IO=1;//拉高数据信号,避免影响芯片输出
- //读数据
- for(i=0;i<8;i++)
- {
- ds1302_SCLK=0;
- delay(2);//小延时,留给芯片足够的时间
- if(ds1302_IO==1)
- date=date|0x80;
- date>>=1;
- ds1302_SCLK=1;
- delay(2);//小延时,留给芯片足够的时间
- /*if(ds1302_IO)
- date|=0x80; //每次传输低字节
- ds1302_SCLK=0;
- date>>=1; //右移一位
- ds1302_SCLK=1; */
- }
- ds1302_CE=0;
- return date;
- }
复制代码你好,非常谢谢...!
试了你的方法,加了延时,还是和之前一样,可以读出数据,只是读出的数据是错误的...!
程序中那个被注释掉的是可以正常工作的...!
我复制上来一下
#define uchar unsigned char
uchar ds1302_read_byte(uchar address)
{
uchar date,i,temp;
temp=address;
ds1302_CE=0;
ds1302_SCLK=0;
ds1302_IO=0;
ds1302_CE=1;
//写地址
for(i=0;i<8;i++)
{
ds1302_SCLK=0;
ds1302_IO=temp&0x01;
temp>>=1;
ds1302_SCLK=1;
}
//读数据
for(i=0;i<8;i++)
{
if(ds1302_IO)
date|=0x80; //每次传输低字节
ds1302_SCLK=0;
date>>=1; //右移一位
ds1302_SCLK=1;
}
ds1302_CE=0;
return date;
}
一周热门 更多>