一、IIC
(一)、IIC有什么作用
穿插:
上垃电阻一般接电源,下拉电阻一般接地
上拉电阻作用:
1、增加驱动电流
2、让线悬空电平不好确定,让总线在浮空的状态下,有确定的电平,滤除干扰
(二)、IIC通信协议
1、起始信号
SCL为高电平时,SDA由高变低
SCL为高电平时,SDA由低变高
函数:
void iic_start()
{
SDA = 1;//首先操作SDA,再操作SCK,防止SCK在高电平时,SDA出现高低电平的变化
SCK = 1;
delay_us(1);//10us
SDA = 0;
delay_us(1);//10us
SCK = 0;//钳住总线,让iic总线失效
}
void iic_stop()
{
SDA = 0;
SCK = 1;
delay_us(1);
SDA = 1;
delay_us(1);
SCK = 0;
}
2、IIC总线的数据传送
规定:
SCK(时钟线)为1时,数据必须保持稳定
SCK为0时,数据允许变化
传送一个字节,先发数据最高位,再发次高位,直至最低位
IIC发送数据函数
unsigned char iic_send_byte(unsigned char byte)
{
unsigned char i;
for(i =0; i < 8; i++)
{
SDA = byte & 0x80;//51中,若unsigned char 赋给一个bit类型的,则bit类型的值当unsigned char非0时为1, 否则为0
SCK = 1; //先给SCK赋值,保持时钟为高电平时,数据稳定
delay_us(1);//10us
SCK = 0;
byte <<= 1;
}
//检测应答信号
SDA = 1;
SCK = 1;
delay_us(1);//10us
if(0 == SDA)
{
SCK = 0;
return SUCC;
}
else
{
SCK = 0;
return FAIL;
}
}
IIC接收数据函数
unsigned char iic_rcv_byte()
{
unsigned char i;
unsigned char temp;
SDA = 1;//防止上一次操作将SDA给拉低
for(i = 0; i < 8; i++)
{
SCK = 0;
delay_us(1);
SCK = 1;
delay_us(1);
temp <<= 1;//发送最高位,先放在最低位,然后移位,一直移到第八次
if(1 == SDA)
{
temp += 1;//如果SDA为0,为temp+=0,所以省略
}
}
SCK = 0;//钳住总线
return temp;
}
3、应答信号和非应答信号
应答:在SCK为高电平期间,接收设备将SDA拉低为低电平,
应答信号函数:
void iic_ack()//应答函数
{
SDA = 0;
SCK = 1;
delay_us(1);
SCK = 0;//钳住总线
}
在发送函数末尾可以添加:
//检测应答信号
SDA = 1;
SCK = 1;
delay_us(1);//10us
if(0 == SDA)
{
SCK = 0;
return SUCC;
}
else
{
SCK = 0;
return FAIL;
}
非应答信号:
void iic_noack()//非应答信号
{
SDA = 1;
SCK = 1;
delay_us(1);
SCK = 0;//钳住总线
}
二、EEPROM
型号 容量
AT24C02 256bit (开发板)
AT24C04 512bit
AT24C08 1024bit
AT24C16 2048bit
关于设备的地址:
对EEPROM写入
unsigned char at24c02_send_str(unsigned char device_addr,unsigned char rom_addr,unsigned char *str,unsigned char num)
{
unsigned char result;
unsigned char i;
iic_start();
result = iic_send_byte(device_addr);
if(FAIL == result)
{
return FAIL;
}
result = iic_send_byte(rom_addr);
if(FAIL == result)
{
return FAIL;
}
for(i = 0; i < num; i++)
{
result = iic_send_byte(*str++);
if(FAIL == result)
{
return FAIL;
}
}
iic_stop();
return SUCC;
}
对EERPOM读取:
unsigned char at24c02_rcv_str(unsigned char device_addr,unsigned char rom_addr,unsigned char *str,unsigned char num)
{
unsigned char result;
unsigned char i;
iic_start();
result = iic_send_byte(device_addr);
if(FAIL == result)
{
return FAIL;
}
result = iic_send_byte(rom_addr);
if(FAIL == result)
{
return FAIL;
}
iic_start();
result = iic_send_byte(device_addr + 1);
if(FAIL == result)
{
return FAIL;
}
for(i = 0; i < num - 1; i++)
{
*str++ = iic_rcv_byte();
iic_ack();
}
*str = iic_rcv_byte();
iic_noack();
iic_stop();
return SUCC;
}
上一篇:基于51单片机的按键控制超声波测距及显示的实现
下一篇:C51单片机IIC总线通信协议及简单应用例程
推荐阅读最新更新时间:2024-03-16 16:08