IIC为一个串行总线。单片机和IIC之间相连这数据线(CLK)和时钟线(SDA)。
IIC总线需通过上拉电阻接正电源,总线空闲时,为高电平。
注
上拉电阻的作用
1.让引脚在悬空(开漏)的状态下有确定的电平
2.增加驱动电流
void iic_start()
{
SDA = 1;
SCL = 1;
delay_us(1);
SDA = 0;
delay_us(1);
SCL = 0;
}
void iic_stop()
{
SDA = 0;
SCL = 1;
delay_us(1);
SDA = 1;
delay_us(1);
SCL = 0;
}
void iic_send_byte(unsigned char byte)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SDA = byte & 0x80;
SCL = 1;
delay_us(1);
SCL = 0;
byte <<= 1;
}
SCL = 1;
SDA = 1;
delay_us(1);
if(0 == SDA)
{
ack = 1;
}
else
{
ack = 0;
}
SCL = 0;
// return ack;
}
unsigned char iic_recv_byte()
{
unsigned char i,a;
unsigned char temp = 0;
SDA = 1;
for(i = 0; i < 8; i++)
{
SCL = 0;
delay_us(1);
SCL = 1;
if(SDA)
{
a = 0x01;
}
else
{
a = 0;
}
temp |= (a << 7-i);
delay_us(1);
}
SCL = 0;
return temp;
}
void iic_ack()
{
SDA = 0;
SCL = 1;
delay_us(1);
SCL = 0;
}
void iic_noack()
{
SDA = 1;
SCL = 1;
delay_us(1);
SCL = 0;
}
unsigned char AT24C02_send_str(unsigned char devadd, unsigned char romadd, unsigned char *s, unsigned char num)
{
unsigned char i;
iic_start();
iic_send_byte(devadd);
if(0 == ack)
{
return FAIL;
}
iic_send_byte(romadd);
if(0 == ack)
{
return FAIL;
}
for(i = 0; i < num; i++)
{
iic_send_byte(*s);
if(0 == ack)
{
return FAIL;
}
s++;
}
iic_stop();
return SUCC;
}
unsigned char AT24C02_rev_str(unsigned char devadd, unsigned char romadd, unsigned char *s, unsigned char num)
{
unsigned char i;
iic_start();
iic_send_byte(devadd);
if(0 == ack)
{
return FAIL;
}
iic_send_byte(romadd);
if(0 == ack)
{
return FAIL;
}
iic_start();
iic_send_byte(devadd+1);
for(i = 0; i < num - 1; i++)
{
*s = iic_recv_byte();
iic_ack();
s++;
}
*s = iic_recv_byte();
iic_noack();
iic_stop();
return SUCC;
}
void main()
{
unsigned char test[11] = {'I','l','o','v','e','s','t','u','d','y','\0'};
unsigned char temp[11];
lcd_init();
AT24C02_send_str(0xae,100,test,11);
delay_ms(20);
AT24C02_rev_str(0xae,100,temp,11);
delay_ms(20);
lcd_string(1,2,temp);
while(1);
}