其实AVR的硬件IIC模块挺好用的。我在Mega32上用过,控制EEPROM
现把驱动代码给你,希望有所帮助
void I2C_init(void)
{
TWSR = 0x00; //TWI状态寄存器初始化
TWAR = 0x00; //本机从机地址为0H
//TWBR = 0x08; //速率为100K
TWBR = 0x20;
TWCR = 0x44; //允许ack应答,使能TWI
}
/***************************
产生启动信号
****************************/
unsigned char I2C_Start(void)
{
unsigned char count = 0;
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN);
while( (!(TWCR & (1 << TWINT)))&&(count < 200) )
{
count++;
}
if( (TWSR & 0xf8) != TW_START )
return I2C_ERR;
else
return I2C_OK;
}
/************************
产生停止信号
************************/
void I2C_Stop(void)
{
TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWSTO);
}
/******************************
向总线写1字节,并返回有无应答
*******************************/
unsigned char I2C_Write(unsigned char data)
{
unsigned char count = 0;
TWDR = data;
TWCR = (1 << TWINT)|(1 << TWEN);
while( (!(TWCR & (1 << TWINT)))&&(count < 200) )
{
count++;
}
if( (TWSR & 0xf8) != TW_MT_SLA_ACK )
return I2C_ERR;
else
return I2C_OK;
}
/********************************
读1字节,
ack = 1时,应答。
ack = 0时,不应答
********************************/
unsigned char I2C_Read(unsigned char ack)
{
unsigned char count = 0;
if(ack)
TWCR = (1 << TWINT)|(1 << TWEN)|(1 << TWEA);
else
TWCR = (1 << TWINT)|(1 << TWEN);
while( (!(TWCR & (1 << TWINT)))&&(count < 200) )
{
count++;
}
return TWDR;
}
|