【IIC通讯协议】

IIC通讯协议

一、什么是IIC

IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边设备而发展。

二、IIC协议简介

I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。

为了避免总线信号的混乱,要求各设备连接到总线的输出端时必须是漏极开路(OD)输出或集电极开路(OC)输出。设备上的串行数据线SDA接口电路应该是双向的,输出电路用于向总线上发送数据,输入电路用于接收总线上的数据。而串行时钟线也应是双向的,作为控制总线数据传送的主机,一方面要通过SCL输出电路发送时钟信号,另一方面还要检测总线上的SCL电平,以决定什么时候发送下一个时钟脉冲电平;作为接受主机命令的从机,要按总线上的SCL信号发出或接收SDA上的信号,也可以向SCL线发出低电平信号以延长总线时钟信号周期。总线空闲时,因各设备都是开漏输出,上拉电阻Rp使SDA和SCL线都保持高电平。任一设备输出的低电平都将使相应的总线信号线变低,也就是说:各设备的SDA是“与”关系,SCL也是“与”关系。

总线对设备接口电路的制造工艺和电平都没有特殊的要求(NMOS、CMOS都可以兼容)。在I2C总线上的数据传送率可高达每秒十万位,高速方式时在每秒四十万位以上。另外,总线上允许连接的设备数以其电容量不超过400pF为限。

三、通讯过程

总线接口 MCU 通过 SDA 和 SCL 端口与 ET6934 进行数据传输。

1、数据有效性

当 SCL 信号处于高电平时,SDA 端口上的数据都是有效稳定的。

只有当 SCL 信号处于低电平时, 才能改变 SDA 端口上的电平高低。

2、开始(重新开始)和停止工作条件
当 SCL 信号为高电平,SDA 信号由高电平转为低电平开始工作或者重新开始工作, 而 SCL 信号为高电平,SDA 信号由低电平转为高电平时停止工作。

3、字节格式
数据线的每个字节由 8 位组成。每个字节包含一个应答位。传输第一个数据是 MSB。

4、应答
在应答时钟期间,主机使 SDA 端口处于高电平,在写模式期间,ET6934 会发出应答信号使 SDA 端 口在应答期间处于低电平。
在这里插入图片描述
注:ACK=应答信号 MSB=字节的最高位
S=起始信号 RS=重新开始信号 P=停止信号
最大时钟速度=400KBITS/S
Restart: 此时 SDA 电平翻转如波形中虚线所表示

四、代码实现

#define   I2C_SDA1              P27//
#define   I2C_SCL1              P26//
/*****************************************************
*函数名称:void I2cStart()
*函数功能:启动i2c
*入口参数:void
*出口参数:void
*****************************************************/
void I2cStart(void)
{
	I2C_SCL1=1;	//总线空闲时,SCL,SDA为高电平
	I2C_SDA1=1;
	_nop_(); 	//SCL高电平保持	4.7US,拉低SDA,产生起始信号
  _nop_();
  _nop_();
  _nop_();
	I2C_SDA1=0;
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();	
	I2C_SCL1=0;
  _nop_(); 
}
/*****************************************************
*函数名称:bit I2cRecAck()
*函数功能:检查应答信号
*入口参数:void
*出口参数:ask
*****************************************************/

void I2cRecAck(void)
{
	I2C_SDA1=1; //主机主动释放SDA,为读ASK做准备
  P2CON &=0x7F;       //0b1111 0111
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	I2C_SCL1=1;
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	I2C_SCL1=0;
  P2CON |=0x80;      //0b0000 0000
}
/*****************************************************
*函数名称:I2cStop(void)
*函数功能:停止I2C
*入口参数:void
*出口参数:void
*****************************************************/
void I2cStop(void)
{		
	I2C_SDA1=0;
	I2C_SCL1=0;
  _nop_();
  _nop_();
	I2C_SCL1=1;		
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	_nop_();
  _nop_();
  _nop_();
	I2C_SDA1=1;
  _nop_();
}
/*****************************************************
*函数名称:I2cWriteByte(uchar dat)
*函数功能:写入一个字节
*入口参数:void
*出口参数:void
*****************************************************/
void I2cWriteByte(unsigned char dat)
{
	unsigned char temp;

	for(temp=0;temp<8;temp++)
	 {     
		if((dat&0X80)==0)
			I2C_SDA1=0;
	  else
			I2C_SDA1=1;
		dat=dat<<1;
    _nop_();
		I2C_SCL1=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
		I2C_SCL1=0;	//SCL低电平时,数据允许变化		
    _nop_();
	}	
}
/******************写入所有数据***********************/
void I2cWrAllData(unsigned char *p,unsigned char lengh)
{
		unsigned char i;
  	for (i=0;i<lengh;i++)	//发送最多16字节的显存数据
  	{
			
			I2cWriteByte(*p);        //写入数据
    	p++;
			I2cRecAck();
  	}
}
/******************写完整数据***********************/
void I2cWrStruct(unsigned char *p,unsigned char length)
{
  I2cStart();
	I2cWriteByte(device_addr);
	I2cRecAck();
	I2cWrAllData(p,length);	
	I2cStop();
}
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值