遇到一个奇怪的事情,开发板上的读取DS1302的时序与datasheet上的不一致,却能正常读写;我按照我的理解改写后,确不能读写。具体如下:
1. 该图是DS1302的读时序,可以看到数据是下降沿后输出。也就是在SCLK下降沿后,I/O上输出串行数据,该数据需要单片机对其接收。对于这种方式,用一种不太恰当的说法就是“10D10D10D......”,其中1、0表示SCLK的输出,D表示单片机接收数据
2. 开发板上的程序如下:
Write_Ds1302_Byte(address); //写入“读”控制命令
for (i=0;i<8;i++) //循环8次 读取数据
{
if(SDA)
temp|=0x80; //每次传输低字节
SCK=0;
temp>>=1; //右移一位
SCK=1;
_nop_();
}
同样用上述表达方式,这个程序的流程是“D01D01D01......”,这显然是与datasheet上的说法不同。
3. 用2的程序,可以正常读写;若把它的流程改为与datasheet一致,即“10D10D......”,显示却不能正常读写。
改程序只需改for循环内部,改后如下:
SCK=0; //上一个函数已将SCK给1,故给0即产生下降沿
if(SDA)
temp|=0x80; //每次传输低字节
temp>>=1; //右移一位
SCK=1;
_nop_();
是我理解错了,还是datasheet上的图有误?求指教!
此帖出自
小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2的程序能正确?除非Write_Ds1302_Byte(address);结尾有sck=0
3的程序,会多移一位。
Write_Ds1302_Byte(address); //写入“读”控制命令
for (i=0;i<8;i++) //循环8次 读取数据
{
temp>>=1; //右移一位
SCK=0;
if(SDA)
temp|=0x80; //每次传输低字节
SCK=1;
_nop_();
}
还是这么写的好吧
[ 本帖最后由 孤獨の快樂 于 2011-11-22 18:13 编辑 ]void Write_Ds1302_Byte(unsigned char temp1)
{
unsigned char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCK=0;
SDA=temp1&0x01; //每次传输低字节
temp1>>=1; //右移一位
SCK=1;
}
}
对于你的写法,产生的时序与2是一样的,只是SCK高点平维持的时间长一点而已。下载到板子上验证与2的效果一样。
很奇怪,if(SDA) temp|=0x80; 是在SCK=0;之后,那第一次的循环的数据就没取吧?
要传输低字节不是应该 temp&=0x01么
不知道是不是定义的不一样还是怎么
既然是右移,比较的应该是最低位啊。。。
能力有限。。越来越糊涂了。。。。
弄清楚了!非常感谢 孤獨の快樂的指教!具体如下:
1. 孤獨の快樂 的程序是对的,我上面说错了,他的程序与程序2的读写流程不同,与程序3的循环移位不同。
我在上面轻易断定他的程序无用,是大错特错, 孤獨の快樂,不好意思了,
2. 程序3的错误如孤獨の快樂所说,移位丢失了一位。
程序2不仅循环移位错了,而且读写时序也错了。但为什么下载到板子上现象正常呢?请往下看
为方便说明,挂了张图如下,画得很丑,见谅!
先说读写时序错误
正常的读数据时机应该是I/O线上的后面的那8个六边形,如图中“1、2、。。8”
程序2读数据的时机在SCLK的高电平期间,并且比正常的时机提前大约半个SCLK脉冲周期,
如图中SCLK后8个高电平上的长方形所示。
在图中可以看到,第1个长方形出现时,SCLK还没有下降沿,故I/O上也还没有正常输出,此时读取的数据无效,用“?”表示。
在第2个长方形到第8个长方形间,如果I/O的输出数据在两个下降沿间均有效,那么这期间就能读到数据,
但是,读到的数据是前一个下降沿触发输出的。
这样,第1个长方形被浪费,后面7个依次读取数据“1、2、3、。。。7”,第8位数据没有长方形来读,被丢弃。
在这种时序下,“87654321”会被读成“7654321?”。(?表示无效数据)
由于程序2又犯了移位错误,“7654321?”又变成了“07654321”
这就是个很大的漏洞了。如果正确的数据最高位为0,那么将会一切正常;否则,才会出现错误!
比如:设定09年04月15日,读出来显示的是正常的;
设定99年04月15日,读出来显示的是19年04月15日,此时错误才显现。
3. 我用程序2下载,现象正常,原因即如上所述。同时也反证了上面红 {MOD}字体的假设是成立的,
那么,datasheet上的I/O数据六边形应该拉长,即图中比特1的维持长度应是所画两条直竖线之间。
一周热门 更多>