当前位置:[北京同好会]>[编程]>[时钟芯片驱动]

 

时钟芯片驱动

[2006-05-24]

以时钟芯片DS1302为例。

管脚排列(extracted from datasheet)

时钟上升沿写,下降沿读。

Vcc2是主电源;Vcc1是备用电源。

指令集(extraced from datasheet)

C51编程:

文件头

//时钟芯片声明代码开始----------------
//定义管脚Time-Keeping Chip TK
sbit TK_CLK=P3^3;
sbit TK_CE=P3^6;
sbit TK_IO=P3^7;

//定义指令
#define TK_RDSEC 0x81
#define TK_WRSEC 0x80
#define TK_RDMIN 0x83
#define TK_WRMIN 0x82
#define TK_RDHR 0x85
#define TK_WRHR 0x84
#define TK_RDDATE 0x87
#define TK_WRDATE 0x86
#define TK_RDMON 0x89
#define TK_WRMON 0x88
#define TK_RDWEEK 0x8B
#define TK_WRWEEK 0x8A
#define TK_RDYR 0x8D
#define TK_WRYR 0x8C
#define TK_WRWP 0x8E
#define TK_RDCLKBURST 0xBF
#define TK_WRCLKBURST 0xBE

//函数声明

void tkwrite(unsigned char address,unsigned char value);
unsigned char tkread(unsigned char address);
void tkreadclock(unsigned char clock[]);
void tksetclock(unsigned char clock[]);
unsigned char bcd2char(unsigned char bcd);
unsigned char char2bcd(unsigned char ch);

//时钟芯片声明代码结束----------------

主程序

//时钟芯片初始化开始---------------
tkwrite(TK_WRWP,0);
tkwrite(TK_WRSEC,0);
//时钟芯片初始化结束---------------

调用

unsigned char clk[8];
......
tksetclock(clk);
......
tkreadclock(clk);
......

子程序

//时钟芯片驱动代码开始----------------
/***************************************************
TimeKeeping Chip TK
写1个字节,仅涉及CLK
***************************************************/
void tksendbyte(unsigned char value){
unsigned char i;
for(i=0;i<8;i++){
if(0x01&value) TK_IO=1;
else TK_IO=0;
TK_CLK=0;
TK_CLK=1;
value>>=1;
}
}

/***************************************************
TimeKeeping Chip TK
读1个字节,仅涉及CLK
***************************************************/
unsigned char tkreadbyte(void){
unsigned char i,res;
res=0;
TK_IO=1;
for(i=0;i<8;i++){
TK_CLK=1;
TK_CLK=0;
res/=2;
if(TK_IO) res+=128;
}
return res;
}

/***************************************************
TimeKeeping Chip TK
在地址address处写入value
***************************************************/
void tkwrite(unsigned char address,unsigned char value){
TK_CLK=0;
TK_CE=0;
TK_CE=1;
tksendbyte(address);
tksendbyte(value);
TK_CLK=0;
TK_CE=0;
}

/***************************************************
TimeKeeping Chip TK
从地址address读出一个字节
返回读出值
***************************************************/
unsigned char tkread(unsigned char address){
unsigned char res;
TK_CLK=0;
TK_CE=0;
TK_CE=1;
tksendbyte(address);
res=tkreadbyte();
TK_CE=0;
return res;
}

/**************************************************
bcd和char格式的转换
**************************************************/
unsigned char bcd2char(unsigned char bcd){
unsigned char res;
res=bcd/16;
res*=10;
res+=bcd%16;
return res;
}

unsigned char char2bcd(unsigned char ch){
unsigned char res;
res=ch/10;
res*=16;
res+=ch%10;
return res;
}

/***************************************************
TimeKeeping Chip TK
burst读时钟转为char输出
***************************************************/
void tkreadclock(unsigned char clock[]){
unsigned char i;
TK_CLK=0;
TK_CE=0;
TK_CE=1;
tksendbyte(TK_RDCLKBURST);
for(i=0;i<8;i++){
clock[i]=bcd2char(tkreadbyte());
}
TK_CE=0;
}

/***************************************************
TimeKeeping Chip TK
转为bcd后burst写时钟
***************************************************/
void tksetclock(unsigned char clock[]){
unsigned char i;

TK_CLK=0;
TK_CE=0;
TK_CE=1;
tksendbyte(TK_WRCLKBURST);
for(i=0;i<8;i++){
tksendbyte(char2bcd(clock[i]));
}
TK_CE=0;
}

//时钟芯片驱动代码结束----------------

[2006-10-7]

发现奇怪的现象。

c51/2051新线路板(1#,89c51)上DS1302的主电源VCC2连到VCC上,VCC通过开关连到电池正极。DS1302的备用电源VCC1直接连到电池正极。故障现象:

安装好后切换开关状态,芯片强烈发热。测量压降,类似短路。仅将VCC1断开,故障消失;仅将VCC2断路,加电时正常,切换开关后发热,这是最令人奇怪的。将芯片换到旧的89c51线路板(2#,89c51)上,(VCC1,VCC2短接连到VCC)故障消失。

新旧线路板逻辑连接都是一样的。在新板上只留下DS1302芯片,其他芯片均移走仍然出现故障。此时与芯片连接的元件只有MAX232的去藕电容。在新板上使用一只1u的电容,在旧板上是0.1u的。判断当开关闭合时,电容充电,DS1302 VCC1的电压出现瞬断造成内部电路紊乱。焊下该电容,故障现象消失。

1#换成3300p电容,反复试验,正常。

[2006-10-11]

匪夷所思的是1#在连接上指示LED,更换了电源开关后故障又出现。最怀疑的是干扰,但看来也还没有找到根本原因。

[2006-10-12]

有些怀疑芯片WP是否应常置位,否则三线输入在断电过程中是否会产生紊乱。

再次试验。用于赤道仪2051的线路板(3#,89c2051)(1u电容),取下MCU,工作正常。将MCU1加上,从而DS1302三线连到了单片机上,异常现象出现。重新编程,令端口上电后即复位(但仍会有正脉冲),现象依旧。

换到1#板。取下MCU,工作正常;加上MCU,异常。重新编程,令端口上电后即复位,同时,只在写时钟前复位WP,写结束后即置位。故障现象消失。试验时钟8小时,准确。

[2006-10-13]

3#板。P1.0,P1.1加上拉电阻。原程序,芯片发热。重新编程,使WP置位。发热现象消失。

所以似乎:WP应常置位,仅在写入前复位。

好景不长,3#又出现问题。将1u电容取下,故障消失。加上,故障出现。

[2006-10-14]

1#线路板51单片机,0.003u电容,WP置位。试验不发热。

3#线路板2051单片机,无电容,WP置位。试验一晚上不发热。

可是,1#重新组装记录器后故障再出现·····,天理难容啊

[2006-10-15]

3#线路板2051单片机,加0.1u电容,WP置位。试验一晚上不发热。