|
马老师:
你好,最近在搞PCF8563的驱动,但不能把芯片驱动起来,程序是参考网上的资料略微修改的。程序看起来也都可以解释得通,但我对8563的读与写都好像没反应。我对时钟芯片初始化,然后再读出里面的数据放eeprom,发现根本没有写入或没有读出。现把这一块贴出来,希望马老师有时间帮忙看看,谢谢!
希望解决问题:能对时钟芯片写入初值,然后能读出来。
(原文件名:时钟电路.JPG)
MCU:m48
#define SDA PORTB.1
#define SCL PORTB.0
//8563.c
uchar TAB_T[7]={0x55,0x30,0x20,//秒,分,时
0x13,0x01,0x07,0x08};//日,星期,月,年.
uchar *pTime=TAB_T;
eeprom char t0; //测试用
eeprom char t1;
eeprom char t2;
eeprom char t3;
eeprom char t4;
eeprom char t5;
eeprom char t6;
//起动后数据线与时钟线均为低电平,准备接收数据
void Start(void)
{
SDA=1; //数据线为高电平;
SCL=1; //时钟线为高电平;
delay_us(5);
SDA=0; //SDA=1 --> SDA=0,在数据线下降沿起动
delay_us(5);
SCL=0;
}
//结束后数据线与时钟线均为高电平,准备下一次的起动
void Stop(void)
{
SDA=0; //数据线为低电平
SCL=1; //时钟线为高电平
delay_us(5);
SDA=1; //SDA=0 --> SDA=1,在数据线上升沿结束
delay_us(5);
}
//怀疑是此处出问题,但以下这样写:等待SDA=0好像也可以。
void Reack(void)
{
uchar i=0;
SCL=1; //准备检测SDA
delay_us(5);
while((SDA==1)&&(i<100))i++;//SDA=0为应答信号,SDA=1为非应答
SCL=0; //准备下一变化数据
}
void WriteByte(uchar ucByte)
{
uchar i;
SCL=0;
for(i=0;i<8;i++)
{
if(ucByte&0x80) //先写入高位
SDA=1;
else SDA=0;
SCL=1;
delay_us(5);
SCL=0;
ucByte<<=1;
}
SDA=1; //释放数据线
}
uchar ReadByte(void)
{
uchar i,ucByte=0;
SCL=0;
for(i=0;i<8;i++)
{
ucByte<<=1;
if(SDA) ucByte++;
SCL=1;
delay_us(5);
SCL=0;
}
return ucByte;
}
void Write8563(uchar ucAddr,uchar ucData)
{
Start();
WriteByte(0xa2);
Reack();
WriteByte(ucAddr);
Reack();
WriteByte(ucData);
Reack();
Stop();
}
uchar Read8563(uchar ucAddr)
{
uchar ucData;
Start();
WriteByte(0xa2); //写器件地址
Reack();
WriteByte(ucAddr); //写字节地址
Reack();
Start();
WriteByte(0xa3); //写器件地址,最低为1表示读
Reack();
ucData=ReadByte(); //写字节地址
Stop();
return ucData; //读数据
}
void Init8563(void)
{
uchar i,ucAddr=0x02;
Write8563(0x00,0x20);
for(i=0;i<7;i++)
{
Write8563(ucAddr,TAB_T);
ucAddr++;
}
Write8563(0x00,0x00);
Write8563(0x01,0x11);
}
void GetTime(void)
{
uchar i,ucData1,ucData2,ucAddr=0x02;
for(i=0;i<7;i++)
{
pTime=Read8563(ucAddr);
ucAddr++;
}
pTime[0]&=0x7f; //屏蔽无效位
pTime[1]&=0x7f;
pTime[2]&=0x3f;
pTime[3]&=0x3f;
pTime[4]&=0x07;
pTime[5]&=0x1f;
for(i=0;i<7;i++)
{
ucData1=pTime/16; //BCD码转十六进制
ucData2=pTime%16;
pTime=ucData1*10+ucData2;
}
}
//main.c
#include <mega48.h>
#include <delay.h>
#include "8563.c"
void main(void)
{
// Crystal Oscillator division factor: 8
//熔丝位为8M内部振荡源,8分频后得1M系统时钟
#pragma optsize-
CLKPR=0x80;
CLKPR=0x03;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTB=0x03;
DDRB=0x03;
Init8563();
GetTime(); //读出时间值,并送到eeprom保存起来
t0=pTime[0]; //7f t0-t6读出的值与GetTime()里相与的值相同,证时没有写入或者没有读出.
t1=pTime[1]; //7f
t2=pTime[2]; //3f
t3=pTime[3]; //3f
t4=pTime[4]; //07
t5=pTime[5]; //1f
t6=pTime[6]; //ff
while (1);
} |
|