协议学习系列(一)------IIC协议

系列文章目录

协议学习系列(一)------IIC协议



前言

主要记录一下工作中常用的几种通讯协议。


一、IIC总线是什么

IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。I²C的正确读法为“I平方C”(“I-squared-C”),而“I二C”(“I-two-C”)则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用I²C协议已经不需要支付专利费,但制造商仍然需要付费以获取I²C从属设备地址。
在这里插入图片描述
IIC总线由一根数据线SDA和一根时钟线SCL组成,IIC总线上允许连接多个微处理器以及各种外围设备,如存储器、LED及LCD驱动器、A/D及D/A转换器等。为了保证数据可靠地传送,任一时刻总线只能由某一台主机控制,各微处理器应该在总线空闲时发送启动数据,为了妥善解决多台微处理器同时发送启动数据的传送(总线控制权)冲突,以及决定由哪一台微处理器控制总线的问题,I2C总线允许连接不同传送速率的设备。多台设备之间时钟信号的同步过程称为同步化。

二、IIC总线协议

1.信号类型

IIC总线在数据传输过程中共有三种信号类型,分别是起始信号、应答信号、和结束信号;总线数据开始传输时必须以起始信号作为开始条件,以结束信号作为停止条件;从机在接收到8bit数据后应向发送数据的IC发送应答信号。其中,起始信号是必须的,应答信号和结束信号不是必须的。

起始信号:IIC总线在空闲状态时(SCL和SDA高电平),SCL为高电平时,SDA由高到低电平跳变。
在这里插入图片描述
停止信号:IIC总线在忙状态时(SCL为高电平,SDA为低电平),SCL为高电平时,SDA由低到高电平跳变。
在这里插入图片描述
应答信号:协议规定主机每传完一个字节的数据即外设每收到一个字节的数据,外设就要在第9个时钟脉冲到来的时候,将SDA数据线拉低进行应答(ACK),且必须是稳定的低电平,表示已经收到了一个字节的数据,拉高表示不进行应答(注意这里是外设将SDA数据线拉低)。
在这里插入图片描述

2.数据传输

上面我们讲完IIC传输的几种信号类型,接下来我们来看下总线数据传输的流程。

总线上的每一个器件都有唯一的地址,而主机和从机之间的通信也是建立在总线寻址的基础上。即主机在传输数据之前须先指定要访问的从机的地址(大部分器件都是7位寻址——地址为7bit),再确定数据传输方向(1bit——为“0”表示主机向从机写数据,为“1”表示主机由从机读数据),最后才能进行数据传输。

主机向从机发送数据:
1.主设备发送起始(START)信号
2.主设备发送设备地址到从设备
3.等待从设备响应(ACK)
4.主设备发送数据到从设备,一般发送的每个字节数据后会跟着等待接收来自从设备的响应(ACK)
5.数据发送完毕,主设备发送停止(STOP)信号终止传输
在这里插入图片描述
主机向从机读取数据:
1.设备发送起始(START)信号
2.主设备发送设备地址到从设备
3.等待从设备响应(ACK)
4.主设备接收来自从设备的数据,一般接收的每个字节数据后会跟着向从设备发送一个响应(ACK)
5.一般接收到最后一个数据后会发送一个无效响应(NACK),然后主设备发送停止(STOP)信号终止传输
在这里插入图片描述
注:在实际应用中还是要根据芯片手册通信规则来进行程序编写。

三、I2C程序

//i2c引脚初始化,我这里用的是软件i2c
void OLED_I2C_Init(void)
{
	GPIO_InitTypeDef OLEDGPIO_InitStructure;
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
 	OLEDGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	OLEDGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	OLEDGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 	GPIO_Init(GPIOA, &OLEDGPIO_InitStructure);
	OLEDGPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
 	GPIO_Init(GPIOA, &OLEDGPIO_InitStructure);
	
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

//你们测试有问题的话按照时序图加个10us延时函数
//起始信号
void OLED_I2C_Start(void)
{
	OLED_W_SDA(1);
	OLED_W_SCL(1);
	OLED_W_SDA(0);
	OLED_W_SCL(0);
}
//结束信号
void OLED_I2C_Stop(void)
{
	OLED_W_SDA(0);
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}
//这里我为了方便没有写应答信号
//字节传输,用for循环和位移操作来传输每一个电平,每循环一次右移一位
void OLED_I2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
	{
		OLED_W_SDA(Byte & (0x80 >> i));
		OLED_W_SCL(1);
		OLED_W_SCL(0);
	}
	OLED_W_SCL(1);	
	OLED_W_SCL(0);
}
//0x78是地址
void OLED_WriteCommand(uint8_t Command)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		
	OLED_I2C_SendByte(0x00);		
	OLED_I2C_SendByte(Command); 
	OLED_I2C_Stop();
}
//写数据
void OLED_WriteData(uint8_t Data)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		
	OLED_I2C_SendByte(0x40);		
	OLED_I2C_SendByte(Data);
	OLED_I2C_Stop();
}

i2c的程序编写大概就是这样,我这里结合OLED库函数编写了一个OLED的显示屏程序,你们有兴趣可以下载看一下。
OLED显示屏驱动程序


总结

以上就是今天记录的内容,本文仅仅简单介绍了IIC总线及IIC总线协议的通讯过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值