DS1302 的 BURST 模式
扫描二维码
随时随地手机看文章
进行产品开发的时候,逻辑的严谨性非常重要,如果一个产品或者程序逻辑上不严谨,就有可能出现功能上的错误。比如我们15.3.4节里的这个程序,我们再回顾一下,当单片机定时器时间到了 200 ms 后,我们连续把 DS1302 的时间参数的7个字节读了出来。但是不管怎么读,都会有一个时间差,在极端的情况下就会出现这样一种情况:假如我们当前的时间是00:00:59,我们先读秒,读到的秒是59,然后再去读分钟,而就在读完秒到还未开始读分钟的这段时间内,刚好时间进位了,变成了00:01:00这个时间,我们读到的分钟就是01,显示在液晶上就会出现一个00:01:59,这个时间很明显是错误的。出现这个问题的概率极小,但却是实实在在可能存在的。
为了解决这个问题,芯片厂家肯定要给我们提供一种解决方案,这就是 DS1302 的突发模式。突发模式也分为 RAM 突发模式和时钟突发模式,RAM 部分我们不讲,我们只看和时钟相关的 clock burst mode。
当我们写指令到 DS1302 的时候,只要我们将要写的5位地址全部写1,即读操作用 0xBF,写操作用 0xBE,这样的指令送给 DS1302 之后,它就会自动识别出来是 burst 模式,马上把所有的8个字节同时锁存到另外的8个字节的寄存器缓冲区内,这样时钟继续走,而我们读数据是从另外一个缓冲区内读取的。同样的道理,如果我们用 burst 模式写数据,那么我们也是先写到这个缓冲区内,最终 DS1302 会把这个缓冲区内的数据一次性送到它的时钟寄存器内。
要注意的是,不管是读还是写,只要使用时钟的 burst 模式,则必须一次性读写8个寄存器,要把时钟的寄存器完全读出来或者完全写进去。
下边就提供一个 burst 模式的例程给大家学习一下,程序的功能还是与上一节一样的。 /*Lcd1602.c 文件程序源代码***/ (此处省略,可参考之前章节的代码)
/*****************************main.c文件程序源代码******************************/#includesbitDS1302_CE=P1^7;sbitDS1302_CK=P3^5;sbitDS1302_IO=P3^4;bitflag200ms=0;//200ms定时标志unsignedcharT0RH=0;//T0重载值的高字节unsignedcharT0RL=0;//T0重载值的低字节voidConfigTimer0(unsignedintms);voidInitDS1302();voidDS1302BurstRead(unsignedchar*dat);externvoidInitLcd1602();externvoidLcdShowStr(unsignedcharx,unsignedchary,unsignedchar*str);voidmain(){unsignedcharpsec=0xAA;//秒备份,初值AA确保首次读取时间后会刷新显示unsignedchartime[8];//当前时间数组unsignedcharstr[12];//字符串转换缓冲区EA=1;//开总中断ConfigTimer0(1);//T0定时1msInitDS1302();//初始化实时时钟InitLcd1602();//初始化液晶while(1){if(flag200ms){//每200ms读取依次时间flag200ms=0;DS1302BurstRead(time);//读取DS1302当前时间if(psec!=time[0]){//检测到时间有变化时刷新显示str[0]='2';//添加年份的高2位:20str[1]='0';str[2]=(time[6]>>4)+'0';//“年”高位数字转换为ASCII码str[3]=(time[6]&0x0F)+'0';//“年”低位数字转换为ASCII码str[4]='-';//添加日期分隔符str[5]=(time[4]>>4)+'0';//“月”str[6]=(time[4]&0x0F)+'0';str[7]='-';str[8]=(time[3]>>4)+'0';//“日”str[9]=(time[3]&0x0F)+'0';str[10]='