[]()# iic概述
iic:两线式串行总线,它是由__数据线sda__和__时钟线__scl构成的串行总线,可发送和接收数据,其使用io使用较少,
在cpu与被控ic之间、ic与ic之间进行双向传送,高速iic总线一般可达400kbs以上。
时钟线scl:在通信过程起到控制作用。
数据线sda:用来一位一位的传送数据。
iic分为软件iic和硬件iic
软件iic:软件iic通信指的是用单片机的两个i/o端口模拟出来的iic,用软件控制管脚状态以模拟i2c通信波形,软件模拟寄存器的工作方式。
硬件iic:一块硬件电路,硬件i2c对应芯片上的i2c外设,有相应i2c驱动电路,其所使用的i2c管脚也是专用的,硬件(固件)i2c是直接调用内部寄存器进行配置。
补充 :
1.硬件i2c的效率要远高于软件的,而软件i2c由于不受管脚限制,接口比较灵活。
2.iic是半双工通信方式
[]()# iic通信协议
iic通信过程由开始、结束、发送、响应、接收五个部分构成。
1、(在发送、接收数据的时候)当scl为高电平时,sda线不允许变化;当scl线为低电平时,sda线可以任意0、1变化。
2、(在任意时候)只有当scl为高电平时,iic电路才对sda线上的电平(0或者1)进行记录,当scl线为低电平时,无论sda是高还是低,iic电路都不对sda进行采样。
[]()### 空闲状态
在介绍上面五个部分前,我们首先说说空闲状态,什么是空闲状态,就是__没有通信时的状态__( 初始状态 )
i2c总线的sda和scl两条信号同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
[]()### 开始信号与停止信号
开始信号:当scl为高期间,sda由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平。
停止信号:当scl为高期间,sda由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
开始信号程序 :
//产生iic起始信号
//1.设置sda输出
//2.先拉高sda,再拉高scl,空闲状态
//3.拉低sda
//4.准备接收数据
void iic_start(void)
{
sda_out(); //sda线输出
iic_sda=1;
iic_scl=1;
delay_us(4);
iic_sda=0;//start:when clk is high,data change form high to low
delay_us(4);
iic_scl=0;//钳住i2c总线,准备发送或接收数据
}
停止信号程序 :
//产生iic停止信号
//1.设置sda输出
//2.先拉低sda,再拉低scl
//3.拉高scl
//4.拉高sda
//5.停止接收数据
void iic_stop(void)
{
sda_out();//sda线输出iic_scl=0;iic_sda=0;//stop:when clk is high data change form low to high delay_us(4);iic_scl=1; iic_sda=1;//发送i2c总线结束信号delay_us(4);}
[]()### 应答信号
发送器每发送一个字节,就在时钟脉冲9期间释放数据先,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ack简称应答位),表示接收器已经成功接收了该字节;应答信号为高电平时,规定为非应答位(nack),一般表示接收器接收该字节没有成功。
对于反馈有效应答位ack的要求是,接收器在第9个时钟脉冲之前的低电平期间将sda线拉低,并且确保在该时钟的高电平期间位稳定的低电平。如果接收器是主控器,则在它收到最后一个字节后,发送一个nack信号,以通知被控发送器结束数据发送,并释放sda线,以便主控接收器发送一个停止信号p
每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答:
应答信号程序 :
//产生ack应答
//这里就很清楚了,产生应答:scl在sda一直为低电平期间完成低高电平转换
void iic_ack(void)
{
iic_scl=0;sda_out();iic_sda=0;delay_us(2);iic_scl=1;delay_us(2);iic_scl=0;}
//不产生ack应答,购买正品元器件,上唯样商城
//这里就很清楚了,不产生应答:scl在sda一直为高电平期间完成低高电平转换
void iic_nack(void)
{
iic_scl=0;sda_out();iic_sda=1;delay_us(2);iic_scl=1;delay_us(2);iic_scl=0;}
[]()### 发送数据
在i2c总线上传送的每位数据都有一个时钟脉冲相对应(或同步控制),即在scl串行时钟的配合下,sda逐位地串行传送每一位数据。数据位的传输是边沿触发。
//iic发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
//iic_scl=0;
//在scl上升沿时准备好数据,进行传送数据时,拉高拉低sda,因为传输一个字节,一个scl脉冲里传输一个位。
//数据传输过程中,数据传输保持稳定(在scl高电平期间,sda一直保持稳定,没有跳变)
//只有当scl被拉低后,sda才能被改变
//总结:在scl为高电平期间,发送数据,发送8次数据,数据为1,sda被拉高,数据为0,sda被拉低。
//传输期间保持传输稳定,所以数据线仅可以在时钟scl为低电平时改变。
void iic_send_byte(u8 txd)
{
u8 t;
sda_out();
iic_scl=0;//拉低时钟开始数据传输
for(t=0;t>7;
//获取数据的最高位,然后左移7位
//如果某位为1,则sda为1,否则相反
if((txd&0x80)>>7)
iic_sda=1;
else
iic_sda=0;
txd<250)
{
iic_stop();
return 1;
}
}
iic_scl=0;//时钟输出0
return 0;
}
[]()### 接收数据
发送数据是一位一位发送,接收数据也是一位一位接收进来,最后返回应答信号:
//读1个字节,ack=1时,发送ack,ack=0,发送nack
//先拉低scl,延时后拉高
//读取数据
//是否发送应答
u8 iic_read_byte(unsigned char ack)
{
unsigned char i,receive=0;sda_in();//sda设置为输入for(i=0;i<8;i++ ){ iic_scl=0; delay_us(2); iic_scl=1; receive<<=1; if(read_sda)receive++; delay_us(1); } if (!ack) iic_nack();//发送nackelse iic_ack(); //发送ack return receive;}
[]()
构建中土“电力丝绸之路”合作来了解一下
如何实现音频信号检测的设计案例
美呆了,带你走入它的世界,荣耀magic开箱鉴赏图
物联网市场蓬勃发展,泰科电子TE Connectivity助力端到端应用解决方案
解读SD-WAN和IP网络更换的现状
IIC通信的基础知识
3线串行数据通讯EEPROM的使用
新装ETC优惠补贴逐步取消,车辆使用ETC有这些好处
合晶上海厂遭遇病毒攻击,出货延迟但不影响业绩
台积电已成为地缘战略家的必争之地
ADAYO华阳与汽车智能芯片引领者地平签署战略合作协议
极飞科技完成新一轮12亿元人民币融资 目前中国农业科技领域最大一笔融资
电动汽车冬天趴窝续航大减_长续航的电动汽车推荐
云计算并不适用于所有EDA工具,这是EDA漫步于“云端”的原因所在
海尔生物医疗在物联网模式下将开启生物科技行业新蓝海
航管二次雷达射频切换单元FPGA实现
边缘融合软件功能介绍及优势
怎样做到SMT物料的先进先出管理
谷歌Pixel 4爆料,两大亮点吸引眼球
嫦娥五号探测器成功发射