||
#include <compat/twi.h>
byte ReadTimeIC(byte *buf, byte addr, byte len); //从时钟芯片读数据到RAM
byte WriteTimeIC(byte *buf, byte addr, byte len); //将RAM中的数据写入到时钟芯片
static byte StartI2C(byte device);
static void WriteI2C(byte dat);
//------------------------------------------------------
//从时钟芯片读数据到RAM
unsigned char ReadTimeIC(byte *buf, byte addr, byte len)
{
byte i;
byte *p;
byte rv;
p = buf;
byte ecount = MAX_ITER; //错误次数
begin:
rv = 0;
if (0==(--ecount)) goto quitr;
if (ERROR == StartI2C(WRITE_TIME)) goto begin;
WriteI2C(addr);
if (TW_MT_DATA_ACK != TW_STATUS) goto begin;
if (ERROR == StartI2C(READ_TIME)) goto begin;
byte tempaddr = addr;
for (i = len; i > 0; i--)
{
if (1 == i) {TWCR = (1<<TWINT)|(1<<TWEN);} //最后一个字节发NAK
else {TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);};
while (0==(TWCR & (1<<TWINT))); //等传输结束
if ((TW_MR_DATA_ACK == TW_STATUS)||(TW_MR_DATA_NACK == TW_STATUS))
{
if (tempaddr == 6) {*buf++ = TWDR&0x07;}
else if (tempaddr == 7){*buf++ = TWDR&0x1f;}
else {*buf++ = TWDR;}
rv++;
tempaddr++;
}
else {
buf = p;
goto begin;
}
};
quitr:
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //发停止位
return rv;
}
//---------------------------------------------------
//将RAM中的数据写入到时钟芯片
byte WriteTimeIC(byte *buf, byte addr, byte len)
{
byte i;
byte rv = 0;
byte ecount = MAX_ITER; //错误次数
restart:
rv = 0;
if (0==(--ecount)) {goto quitw;};
if (ERROR == StartI2C(WRITE_TIME)) goto restart;
WriteI2C(addr);
if (TW_STATUS != TW_MT_DATA_ACK) goto restart;
for (i = len; i > 0; i--)
{
WriteI2C(*buf);
buf++;
if (TW_STATUS == TW_MT_DATA_ACK)
{
rv++;
}
else {goto restart;};
};
quitw:
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //发停止位
return rv;
}
//---------------------------------------------------
//选择设备,如设备成功接收地址返回1,否则返回0
byte StartI2C(byte device)
{
byte status;
TWCR= 0X00;
TWBR= 0x01; TWSR= 0xF9; //设SCL约150K
do
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //发送启始位
while (0==(TWCR & (1<<TWINT))); //等发完
status = TW_STATUS;
} while ((TW_START!=status) && (TW_REP_START!=status));
WriteI2C(device);
status = TW_STATUS;
if (0x01 & device)
{
if (TW_MR_SLA_ACK == status) return OK;
return ERROR;
};
if (TW_MT_SLA_ACK == status) return OK;
return ERROR;
}
//-----------------------------------------------------
//向设备写一个字节
void WriteI2C(byte dat)
{
TWDR = dat;
TWCR = (1<<TWINT) | (1<<TWEN);
while (0==(TWCR & (1<<TWINT))); //等传完
}