单片机 DS1302 痛苦的调试过程,把我的经验教训分享给大家,希望能给后来者一点帮助
首先把我用的程序贴出来,是网上下的,我已经通过硬件测试,绝对没有问题
#define WRITE_SECOND 0x80#define WRITE_MINUTE 0x82#define WRITE_HOUR 0x84#define READ_SECOND 0x81#define READ_MINUTE 0x83#define READ_HOUR 0x85#define WRITE_PROTECT 0x8E //位寻址寄存器定义sbit ACC_7 = ACC^7;//管脚定义sbit SCLK = P3^5; // DS1302时钟信号 7脚sbit DIO= P3^6; // DS1302数据信号 6脚sbit CE = P3^7; // DS1302片选 5脚 //地址、数据发送子程序void Write1302 ( unsigned char addr,dat ) { unsigned char i,temp; CE=0; //CE引脚为低,数据传送中止 SCLK=0; //清零时钟总线 CE = 1; //CE引脚为高,逻辑控制有效 //发送地址 for ( i=8; i>0; i-- ) //循环8次移位 { SCLK = 0; temp = addr; DIO = (bit)(temp&0x01); //每次传输低字节 addr >>= 1; //右移一位 SCLK = 1; } //发送数据 for ( i=8; i>0; i-- ) { SCLK = 0; temp = dat; DIO = (bit)(temp&0x01); dat >>= 1; SCLK = 1; } CE = 0; } //数据读取子程序unsigned char Read1302 ( unsigned char addr ){ unsigned char i,temp,dat1,dat2; CE=0; SCLK=0; CE = 1; //发送地址 for ( i=8; i>0; i-- ) //循环8次移位 { SCLK = 0; temp = addr; DIO = (bit)(temp&0x01); //每次传输低字节 addr >>= 1; //右移一位 SCLK = 1; } //读取数据 for ( i=8; i>0; i-- ) { ACC_7=DIO; SCLK = 0; ACC>>=1; SCLK = 1; } CE=0; dat1=ACC; dat2=dat1/16; //数据进制转换 dat1=dat1%16; //十六进制转十进制 dat1=dat1+dat2*10; return (dat1);} //初始化DS1302void Initial(void) { Write1302 (WRITE_PROTECT,0X00); //禁止写保护 Write1302 (WRITE_SECOND,0x56); //秒位初始化 Write1302 (WRITE_MINUTE,0x34); //分钟初始化 Write1302 (WRITE_HOUR,0x12); //小时初始化 Write1302 (WRITE_PROTECT,0x80); //允许写保护}
//读取数据 for ( i=8; i>0; i-- ) { [color=#FF0000]SCLK=0;[/color] ACC_7=DIO; SCLK = 0; ACC>>=1; [color=#FF0000]//SCLK = 1;[/color] }
(这下都OK啦,后来自己写了一个很庞大的程序,用键盘修改时间和RAM数据,然后读出来用数码管显示,一切运行正常。不过事情并没有到这里结束,下面又让人更头痛的问题,下面这个问题的原因和现象在网上没有任何资料,大家继续往下看)
先贴我写的一段程序(初始化用的,读时钟和RAM)
void initial(void) { //程序比较乱,大家只要知道:先读时间,只要时间不是00 00和85 85那就读RAM //DS1302初始化,开启时钟 Write1302(WRITE_PROTECT,0X00); //取消写保护 delay(2); Write1302(WRITE_SECOND,0x01); //秒位初始化,开启时钟 delay(2); Write1302(WRITE_PROTECT,0x80); //时钟和存储数据的读取 hour=Read1302(READ_HOUR,1); delay(1); minute=Read1302(READ_MINUTE,1); if(((hour*100+minute)!=0) && ((hour*100+minute)!=8585)){ step=Read1302(SEP_ADD+1,0); if(step==0){ step=2; } QtyValue[0]=Read1302(PLAN_QTY_ADD+1,0)*100 + Read1302(PLAN_QTY_ADD+3,0); delay(1); QtyValue[1]=Read1302(ESTM_QTY_ADD+1,0)*100 + Read1302(ESTM_QTY_ADD+3,0); delay(1); QtyValue[2]=Read1302(ACTL_QTY_ADD+1,0)*100 + Read1302(ACTL_QTY_ADD+3,0); delay(1); paraQty=Read1302(PAH_QTY_ADD+1,0)+2; delay(1); paraStartMode=(bit)Read1302(PAH_MODE_ADD+1,0); delay(1); readPAH2(); delay(1); rest=paraStartMode; delay(1); for(paraEditPoint=0;paraEditPoint>3;paraEditPoint++){ resetHour[paraEditPoint]=Read1302(RESET_TIME_ADD+1+paraEditPoint*4,0); delay(1); resetMinute[paraEditPoint]=Read1302(RESET_TIME_ADD+1+paraEditPoint*4+2,0); delay(1); } } //else{ // QtyValue[2]=hour*100+minute; //} //模式指针初始化 beep();//初始化完后,蜂鸣器叫一声 }