各位高手,小弟写了一个1302的驱动程序,在有的ds1302上面能正确运行,有的ds1302上无法运行,搞到现在没有搞明白,请教一下大家。
本人写的ds1302的驱动贴在下面,大家帮忙看看有没有什么错误的地方。
奇怪的事情在这,本人买了2个ds1302,字是白色的印刷上去的,用指甲一弄就掉,上面印的是ds1302 0722A4 +107AA。
这个ds1302用我写的驱动读写正常,显示也完全正常,就是不走时,也就是不走秒,但是奇怪的是我拔掉晶振用手捏住接晶振的两端的时候,开始走秒,但是走的比较快,运行也比较正常,就是手一松就停止了,有时候不装晶振他也走时,就是很慢走的。不知道什么原因,请教大家。
由于上面的ds1302太古怪,所以我又去买了3个新的ds1302,不在同一家买的,这次的ds1302是灼刻在芯片表面的,也就是用手擦不掉的,铭牌是 ds1302 ba38hj ,用下面写的驱动也能正常驱动,就是读数不正确,比如读秒显示的是 :00,01,00,03,00,02,07,10,08,13,09,十分混了。
但是自己能自动走,更加不可思议的是我拔掉晶振他居然也在走,而且频率和没拔的时候一样。。。
至今没有调试出来,郁闷啊啊。。。ds1302有鬼啊啊。。。。
请大家指教,下面是我的驱动程序。大家看看是不是时序问题。谢谢大家了!
void write_ds1302(unsigned char Writeaddr,unsigned char Writedata) { unsigned char i; TIMERST=0; TIMECLK=0; TIMERST=1; for(i=8;i>0;i--) { TIMECLK=0; TIMEDATA=Writeaddr&0x01; _nop_(); TIMECLK=1; Writeaddr=Writeaddr>>1; }
for(i=8;i>0;i--) { TIMECLK=0; TIMEDATA=Writedata&0x01; _nop_(); // TIMECLK=1; Writedata=Writedata>>1; }
TIMERST=0; _nop_(); TIMECLK=0; _nop_();
}
/**************************************************************************** 从DS1302读出一个字节的数据 ****************************************************************************/ unsigned char Read_Ds1302(unsigned char Readaddr) { unsigned char i; unsigned char value=0; uchar value1=0; TIMERST=0; TIMECLK=0; TIMERST=1; for(i=8;i>0;i--) { TIMECLK=0; //0 TIMEDATA=Readaddr&0x01; _nop_(); // TIMECLK=1; Readaddr=Readaddr>>1; } for(i=8;i>0;i--) { if(TIMEDATA==1) { value=value|0x80; } value=value>>1; TIMECLK=0; TIMECLK=1; _nop_(); }
TIMERST=0; _nop_(); TIMECLK=0; _nop_(); value1=value&0xf0; value=value&0x0f; value1>>=4; value=value+value1*10; return value; }
/**************************************************************************** DS1302初始化 ****************************************************************************/ void init_1302(void) { while(Read_Ds1302(0xcd)!=0x01) { TIMECLK=0; TIMERST=1; write_ds1302(0x8e,0x00); write_ds1302(0x82,0x01); write_ds1302(0x84,0x02); write_ds1302(0x86,0x03); write_ds1302(0x88,0x04); write_ds1302(0x8a,0x05); write_ds1302(0x8c,0x06); write_ds1302(0x90,0x00); write_ds1302(0xcc,0x01); write_ds1302(0x80,0x01); write_ds1302(0x8e,0x80); if(keyboard(0)) break;
} }
|