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协议上手的主要内容,如果未能解决你的问题,请参考以下文章