一、什么是IIC?
IIC属于两线式串行总线,由飞利浦公司开发用于微控制器(MCU)和外围设备(从设备)进行通信的一种总线,属于一主多从(一个主设备(Master),多个从设备(Slave))的总线结构,总线上的每个设备都有一个特定的设备地址,以区分同一I2C总线上的其他设备。
物理I2C接口有两根双向线,串行时钟线(SCL)和串行数据线(SDA)组成,可用于发送和接收数据,但是通信都是由主设备发起,从设备被动响应,实现数据的传输。
二、总体特征
SDA 和SCL 都是双向线路,都通过一个电流源或上拉电阻连接到正的电源电压当总线空闲时,这两条线路都是高电平。连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。I²C总线上数据的传输速率在标准模式下可达100kbit/s, 在快速模式下可达400kbit/s, 在高速模式下可达3.4Mbit/s。 连接到总线的接口数量只由总线电容是400pF 的限制决定。
三、IIC协议时序
起始信号(S):当SCL为高电平时,SDA从高电平变为低电平。
停止信号(P):当SCL为高电平时,SDA从低电平变为高电平。
应答信号:上拉电阻影响下SDA默认为高,而从机拉低SDA就是确认收到数据即ACK,否则NACK。
注:1.数据先发送高位 2.数据以字节(8bit)传输 3.数据在SCL高电平稳定 4.空闲状态:高电平
四、代码编写
//起始信号
void iic_start(void)
{//SCL为高电平期间,SDA从高电平往低电平跳变
IIC_SDA(1);
IIC_SCL(1);
iic_delay();//延时看从机(器件)
IIC_SDA(0);
iic_delay();
IIC_SCL(0);
iic_delay();//钳住总线,准备发送/接受数据
}
//停止信号
void iic_stop(void)
{//SCL为高电平期间,SDA从低电平往高电平跳变
IIC_SDA(0);
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SDA(1);//发送总线停止信号
iic_delay();
}
//发送应答信号
void iic_ack(void)
{
IIC_SCL(0);
iic_delay();
IIC_SDA(0);//数据线变为低电平,表示应答
iic_delay();
IIC_SCL(1);
iic_delay();
}
/*·¢ËÍ·ÇÓ¦´ðÐźÅ*/
void iic_nack(void)
{
IIC_SCL(0);
iic_delay();
IIC_SDA(1);//数据线变为高电平,表示非应答
iic_delay();
IIC_SCL(1);
iic_delay();
}
uint8_t iic_read_byte(uint8_t ack)//1:ack 0:nack
{
uint8_t receive=0;
for(uint8_t t=0;t<8;t++)
{//高位先输出,先收到的数据位要左移
receive<<=1;
IIC_SCL(1);
iic_delay();
if(IIC_READ_SDA)receive++;
IIC_SCL(0);
iic_delay();
}
if(!ack)iic_nack();
else iic_ack();
return receive;
五、IIC配置步骤
1、使能SCL和SDA对应时钟:__HAL_RCC_GPIOB_CLK_ENABLE()
2、设置GPIO工作模式:SDA开漏/SCL推挽输出模式,使用HAL_GPIO_Init初始化
3、编写基本信号:起始信号 停止信号 应答信号
主机:send ack/send nack 从机:wait ack
4、编写读和写函数:iic_read_byte/iic_send_byte