先定义些东西
#define PORT_IIC PORTC
#define DDR_IIC DDRC
#define BIT_SCL 0
#define BIT_SDA 1
#define TW_START 0X08
#define TW_REP_START 0X10
#define TW_MT_SLA_ACK 0X18
下面切入正题
iic总线初始化
Code
void iic_init(void)
{
TWSR=0;
TWBR=32;//这点要注意下,不要设的速度太高,否则
//proteus仿真可能读不到数据
TWAR=0;
TWCR=(1<<TWEA)|(1<<TWEN);
PORT_IIC|=(1<<BIT_SCL)|(1<<BIT_SDA);
}
void iic_init(void)
{
TWSR=0;
TWBR=32;//这点要注意下,不要设的速度太高,否则
//proteus仿真可能读不到数据
TWAR=0;
TWCR=(1<<TWEA)|(1<<TWEN);
PORT_IIC|=(1<<BIT_SCL)|(1<<BIT_SDA);
}
iic初始与终止位
Code
unsigned char iic_start(void)
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))) ;
if ((TWSR & 0xF8) != TW_START&&(TWSR & 0xF8) != TW_REP_START)
{
return 0;
}
else
{
return 1;
}
}
void iic_stop(void)
{
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
unsigned char iic_start(void)
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))) ;
if ((TWSR & 0xF8) != TW_START&&(TWSR & 0xF8) != TW_REP_START)
{
return 0;
}
else
{
return 1;
}
}
void iic_stop(void)
{
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
iic读取
Code
unsigned char iic_read(unsigned int ack)
{
char data;
if(ack==1)
{
TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);
}
else
{
TWCR=(1<<TWINT)|(1<<TWEN);
}
while(!(TWCR&(1<<TWINT)));
data=TWDR;
return data;
}
iic写入
unsigned char iic_read(unsigned int ack)
{
char data;
if(ack==1)
{
TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);
}
else
{
TWCR=(1<<TWINT)|(1<<TWEN);
}
while(!(TWCR&(1<<TWINT)));
data=TWDR;
return data;
}
Code
unsigned char iic_write(unsigned char data)
{
unsigned char ack=1;
TWDR=data;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))) ;
if((TWSR&0XF8)!=TW_MT_SLA_ACK)//检测应答位
{
ack=0;
}
else
{
ack=1;
}
return ack;
}
eeprom片选
unsigned char iic_write(unsigned char data)
{
unsigned char ack=1;
TWDR=data;
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))) ;
if((TWSR&0XF8)!=TW_MT_SLA_ACK)//检测应答位
{
ack=0;
}
else
{
ack=1;
}
return ack;
}
static
unsigned
char
cs ;
void eeprom24s_set_cs(unsigned char addr)
{
cs = addr;
}
void eeprom24s_set_cs(unsigned char addr)
{
cs = addr;
}
eeprom读取
Code
unsigned char eeprom24s_read(unsigned int addr)
{
unsigned char data;
iic_start();
iic_write(cs<<1);
iic_write(addr>>8);
iic_write(addr);
iic_start();
iic_write((cs<<1)|0x01);
data=iic_read(0);
iic_stop();
delay_us(10);//延时很重要,否则proteus可能出错
return data;
}
eeprom写入
unsigned char eeprom24s_read(unsigned int addr)
{
unsigned char data;
iic_start();
iic_write(cs<<1);
iic_write(addr>>8);
iic_write(addr);
iic_start();
iic_write((cs<<1)|0x01);
data=iic_read(0);
iic_stop();
delay_us(10);//延时很重要,否则proteus可能出错
return data;
}
Code
unsigned char eeprom24s_write(unsigned int addr,unsigned char data)
{
iic_start();
iic_write(cs<<1);
iic_write(addr>>8);
iic_write(addr);
iic_write(data);
iic_stop();
delay_ms(10);)//延时很重要,否则proteus可能出错
}
测试用例
unsigned char eeprom24s_write(unsigned int addr,unsigned char data)
{
iic_start();
iic_write(cs<<1);
iic_write(addr>>8);
iic_write(addr);
iic_write(data);
iic_stop();
delay_ms(10);)//延时很重要,否则proteus可能出错
}
Code
int main( void )
{
unsigned char data;
unsigned char i;
usart_init(9600);
iic_init();
eeprom24s_set_cs(0x50);
eeprom24s_write(0x0010,0x30);
eeprom24s_write(0x0011,0x31);
eeprom24s_set_cs(0x51);
eeprom24s_write(0x0010,0x32);
eeprom24s_write(0x0011,0x33);
eeprom24s_set_cs(0x50);
data=eeprom24s_read(0x0010);
usart_send(data);
data=eeprom24s_read(0x0011);
usart_send(data);
eeprom24s_set_cs(0x51);
data=eeprom24s_read(0x0010);
usart_send(data);
data=eeprom24s_read(0x0011);
usart_send(data);
return 0;
}
测试截图
int main( void )
{
unsigned char data;
unsigned char i;
usart_init(9600);
iic_init();
eeprom24s_set_cs(0x50);
eeprom24s_write(0x0010,0x30);
eeprom24s_write(0x0011,0x31);
eeprom24s_set_cs(0x51);
eeprom24s_write(0x0010,0x32);
eeprom24s_write(0x0011,0x33);
eeprom24s_set_cs(0x50);
data=eeprom24s_read(0x0010);
usart_send(data);
data=eeprom24s_read(0x0011);
usart_send(data);
eeprom24s_set_cs(0x51);
data=eeprom24s_read(0x0010);
usart_send(data);
data=eeprom24s_read(0x0011);
usart_send(data);
return 0;
}