海乐工作室 https://bbs.21ic.com/?8048 [收藏] [复制] [RSS]

日志

用AVR中的TWI读写HYM8563的例子

已有 944 次阅读2005-10-9 17:20 |个人分类:MCU实验田|系统分类:单片机

#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);


//wyanxi@sohu.com


//------------------------------------------------------
//从时钟芯片读数据到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)));  //等传完
}


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)