IIC协议上手

Posted 文某9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IIC协议上手相关的知识,希望对你有一定的参考价值。

1. IIC开始信号,时钟线保持高,数据线由高变低(下降沿)

开始信号伪代码(delay是延时)

SCL=1;
SDA=1;
delay_us(4);
SDA=0;
delay_us(4);

上面已经完成了起始信号的产生,但是我们还应该考虑数据的方向性

开始信号优化后的伪代码

SDA_OUT();//单片机引脚切换输出模式
IIC_SCL=1;
IIC_SDA=1;
delay_us(4);
IIC_SDA=0;
delay_us(4);
IIC_SCL=0;

两种起始信号都可以直接使用,我在驱动中都有看到,第一种用于OLED0.96的驱动函数中,第二种用于dht11温湿度传感器中,我的猜想是因为两种硬件的原理,OLED不需返回数据,dht11需要返回数据,所以驱动有了差异。

2.IIC停止信号,SCL拉高,SDA由低到高(上升沿)

停止信号伪代码

scl=1;
sda=0;
delay_us(4);
sda=1;
delay_us(4);

停止信号优化后伪代码(带方向)

SDA_OUT();//单片机引脚切换输出模式
SCL=0;
SDA=0;
delay_us(4);
SCL=1; 
SDA=1;
delay_us(4);							  

3.IIC应答信号,其实就是把SDA置为0

SCL=0;
SDA=0;
delay_us(4);
SCL=1;
delay_us(4);
SCL=0;

4.IIC非应答信号,其实就是把SDA置为1

SCL=0;
SDA=1;
delay_us(4);
SCL=1;
delay_us(4);
SCL=0;

5.发送一个字节,其实就是发送八次高低位,值得注意的是,时钟线为高,数据稳定开始发送,时钟线为低数据可以随意变化。

如何实现这个流程?8位数据和0x80进行与操作,然后往左移7位得到最高位的值,而这个值只可能是1/0,所以通过判断改变SDA的状态,每发送一位要把原数据往左移动一位,让次高位变成最高位,这样才能实现数据更新,最终完成8位的发送

发送字节函数伪代码

u8 t;   
SDA_OUT(); //方向为输出	    
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
              
IIC_SDA=(txd&0x80)>>7;
txd<<=1; 	  
delay_us(2);
IIC_SCL=1;//每个上升沿完成一次数据发送
delay_us(2); 
IIC_SCL=0;	
delay_us(2);
	 

6.接收一个字节(高电平期间才能读取信号)

如何实现?首先创建receive变量,在8次循环中,每次把receive往左移一位,根据读取的数据改变receive的值,高为1,低为0,8次移位保存一个字节的数据

接收字节伪代码

u8 a=0;u8 receive=0;
for(;a<8;a++)

SCL=0;
delay_us(2);
SCL=1;
receive<<1;
if(read_apio_pin) receive++;

if(ACK);RETURN 1;
if(NACK);RETURN 0;

以上是关于IIC协议上手的主要内容,如果未能解决你的问题,请参考以下文章

IIC总线协议——esp32学习笔记

通信协议之IIC总线

通信协议之IIC总线

通信协议之IIC总线

通信协议之IIC总线

IIC设备