• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

大家帮我看看这个我哪里理解错了

lennon 2016-07-11 浏览量:1188
再ds1302时钟芯片里面有这么一个函数
void write_ds1302_byte(uchar dat)

{
uchar i;
for(i=0;i<8;i++)
{
sck=0;
io=dat&0x01;
dat=dat>>1;
sck=1;
}
}
就是将命令dat由低位到高位写入io中,也就是是命令写入函数 。

正确的理解是例如 dat=0x45即dat=0100 0101和0x01进行‘’“&”运算,
i=0时,屏蔽掉前七位 即0100 0101&0000 0001=0000 0001,此时io
的最低位是1.dat右移一位 dat=0010 0010
i=1时,屏蔽掉前七位即0010 0010&0000 0001=0000 0000,此时io
的次低位时0.dat右移一位dat=0001 0001
.
.
.直到i=8,就将dat=0100 0101写入到io中。

但是我的理解是依据上面的函数
i=0;
dat=0x45即dat=0100 0101时,io=dat&0x01
此时io=0000 0001;dat右移一位 dat=0010 0010;
i=1;
dat=0010 0010 此时 io=dat&0x01; 即io=0010 0010&0000 0001=0000 0000;
dat右移一位dat=0001 0001
i=3;
dat=0001 0001此时io=dat&0x01 即io=0001 0001&0000 0001 =0000 0001
直到i=7,最后的io值是0000 0000 并不等于dat 0x45啊 求大神我错在哪里了?
1 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • lennon 发表于 2016-7-11 23:33
    你说的没错,io定义的是一个串行口。
    我给你发开发板自带的程序吧。上面那个是我自己理解举得例子。
    void ...

    每次通过IO写入的0或1,都已经写进ds1302了。
    你看程序的注释:

    SCLK = 1;//数据在上升沿时,DS1302读取数据

    你向SCLK写1,则该引脚由原来低电平变为高电平,即一个上升沿信号。
    当DS1302识别到SCLK为上升沿信号时,就把IO的值保存起来了。

    也就是说,ds1302一次只能读一个bit.
    而dat是uchar(8个bit),那么只能一次通过io写给ds1302一个bit,
    循环移位8次即把dat的8个bit依次写给了ds1302。
    • 发布于 2016-07-11
    • 举报
    • 评论 0
    • 2
    • 0

其他答案 数量:5
  • 本帖最后由 999 于 2016-7-11 23:36 编辑

    从你的程序来看,我猜你的io定义的是一个引脚,而不是整个port。(即使是一个port也应该是低位的引脚与ds1302相连)
    所以io的值只两种可能:0或1,不可能等于0x45。
    同时dat&0x01的值就两种:不是0就是1。
    从你的程序上理解,时钟信号为低电平时写数据有效。
    将dat由低到高写进ds1302,通过io引脚每次写一位。循环移位后即把整个字节写给了ds1302
    另外应该结合芯片datasheet的时序图,感觉你这个sck的信号有可能有问题。
    sck的高低电平持续时间手册上一定有要求的。
    • 发布于2016-07-11
    • 举报
    • 评论 0
    • 2
    • 0

  • 那个循环移位只是依次提取dat的各个bit的值,然后通过io写入ds1302。
    你的io就一个引脚,数据带宽只有1个bit。想传大数据,只能依次按规定的时序写给ds1302.
    就像你和你的小伙伴8个人,要通过只能容一个人通过的窄门。
    8个人并排走,肯定过不去,
    那么就排队依次通过这个门。而通过门的人,他并没有消失,已经在门外了。
    就像你说前7次的数据,每次已经写进ds1302了,并没丢失
    • 发布于2016-07-12
    • 举报
    • 评论 0
    • 1
    • 0

  • 999 发表于 2016-7-11 23:05
    从你的程序来看,我猜你的io定义的是一个引脚,而不是整个port。(即使是一个port也应该是低位的引脚与ds13 ...

    你说的没错,io定义的是一个串行口。
    我给你发开发板自带的程序吧。上面那个是我自己理解举得例子。
    void Ds1302Write(uchar addr, uchar dat)
    {
    uchar n;
    RST = 0;
    _nop_();

    SCLK = 0;//先将SCLK置低电平。
    _nop_();
    RST = 1; //然后将RST(CE)置高电平。
    _nop_();

    for (n=0; n<8; n++)//开始传送八位地址命令
    {
    DSIO = addr & 0x01;//数据从低位开始传送
    addr >>= 1;
    SCLK = 1;//数据在上升沿时,DS1302读取数据
    _nop_();
    SCLK = 0;
    _nop_();
    }
    for (n=0; n<8; n++)//写入8位数据
    {
    DSIO = dat & 0x01;
    dat >>= 1;
    SCLK = 1;//数据在上升沿时,DS1302读取数据
    _nop_();
    SCLK = 0;
    _nop_();
    }

    RST = 0;//传送数据结束
    _nop_();
    }
    我的疑惑就是如何通过8次循环将一个八位dat或者八位addr写入的?你的意思就是i通过一次循环只能写入一个0或者1, 8次以后就写入了八位数据? 可是当i=7时,diso=0或者1(我没算具体是几),那前七次循环计算的数据存储在哪里了?我的理解是diso都会把前一次计算的都覆盖了,只留i=7的计算结果,那不是就没有把数据写入吗?
    • 发布于2016-07-11
    • 举报
    • 评论 0
    • 0
    • 0

  • 999 发表于 2016-7-12 00:01
    那个循环移位只是依次提取dat的各个bit的值,然后通过io写入ds1302。
    你的io就一个引脚,数据带宽只有1个bi ...

    哎呀,这么一说我就明白了。真是论坛高手多呀,自己学起来身边每个能给指导的真的很费劲,谢谢你的答案
    • 发布于2016-07-12
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

大家帮我看看这个我哪里理解错了