当前位置:首页 > 单片机 > 单片机
[导读] I2C总线特点I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够

I2C总线特点
I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。


2I2C总线工作原理
I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。如果SCL处于高电平时,SDA上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。

每次数据传输都是以一个起始位开始,而以停止位结束。传输的字节数没有限制。最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
在I2C总线中只有主发送和主接收两种操作方式。在系统初始化时,由指令控制CPU送出相关的数据,经接口送到I2C寄存器内。通过初始化这些寄存器,可以实现I2C总线的主模式控制,以及实现I2C总线上的从设备读写。
当主设备和其中的一个从设备交换数据时,主设备首先发出一个启动Start信号,这个信号被所有的从设备接收。即从设备准备接收CPU的信号,然后主设备再发出它要通信的从设备地址。接下来,所有的从设备将收到的这个地址和它们自己的地址进行比较。
如果收到的地址和它们自己的地址不同,则什么都不做,只是等待主设备发出停止stop信号;如果收到的地址和它自己的地址相同,它就发出一个信号给主设备,这个信号称为应答AcknowLEDge信号。当主设备收到应答信号后,它就开始向从设备发送数据或者从从设备接收数据。当所有操作都进行完毕时,主设备发出一个Stop信号,通信完毕,释放I2C总线;然后所有的从设备都等待下一次Start信号的到来。
3总线基本操作
I2C规程运用主/从双向通讯。器件发送数据到总线上,则定义为发送器,器件接收数据则定义为接收器。主器件和从器件都可以工作于接收和发送状态。总线必须由主器件(通常为微控制器)控制,主器件产生串行时钟(SCL)控制总线的传输方向,并产生起始和停止条件。SDA线上的数据状态仅在SCL为低电平的期间才能改变,SCL为高电平的期间,SDA状态的改变被用来表示起始和停止条件。
3.1控制字节
在起始条件之后,必须是器件的控制字节,其中高四位为器件类型识别符(不同的芯片类型有不同的定义,EEPROM一般应为1010),接着三位为片选,最后一位为读写位,当为1时为读操作,为0时为写操作。
1.写过程
(1)上电后等待一个延时(1ms)。
(2)器件寻址,给一个起始信号(SCL为高电平时SDA给一个下降沿)。发送从器件地址,高5位为10110,然后根据A1/A0(如果和器件的地址相同则那个器件会应答)进行读/写控制(O为读)。
(3)应答,器件在SCL的第9个周期时SDA给出一个低电平,作为应答信号。
(4)开始写有两种模式:字节写模式和页写模式。
·字节模式:给出A15~A8应答,给出A7~A0应答;然后给出DATA和停止信号(SCL为高电平时,SDA给出一个上升沿),接着要等待一个擦写时间。
·页写模式:给出地址以后连续给出64个数据。如果多于64个数据,则地址计数器自动翻转。(如果少于64昵,估计是没有问题的,但是需要实验验证。)
(5)判断擦写操作是否完毕的一个方法(应答查询),如果器件还处于擦写状态,则不会应答器件寻址;如果有应答,则说明擦写完毕。
2.读过程
(1)上电以后等待一个延时(lms)。
(2)器件寻址。
(3)应答。
(4)开始读有三种模式:立即当前地址读、选择/随机读、连续读。
·立即当前地址读:如果上次读/写的操作地址为N,则现在是N+1。不需要ACK,但是需要Stop信号。
·选择/随机读:先伪写(用于给出一个地址),然后再次启动,读取数据。
·连续读:读取一个以后给一个应答,这样器件会再给出下一个地址的数据内容。
(5)开始数据传输Start后、停止数据传输Stop前,SCL高电平期间,SDA上为有效数据。
/*******************************************************************
一、程序说明:
1,24LC02器件地址是1010000R/W.
2,数组写入24LC02采取页写方式.
3,数组code从24LC02读出时采取自由读方式.
4,采用4.00M晶体。
5,采用软件I2C。
二、硬件连接:
1,SDA------->23PIN.(当然你可以任意选择脚位)
2,SCL------->18Pin.(当然你可以任意选择脚位)
3,PORTD----->外接8个LED,显示读出的数据,在这里,读出的刚好是一个闪动的流水灯状态。
*******************************************************************/
#include"pic.h"
#defineucharunsignedchar
#definenop()asm("nop"
#defineSCLTRISC3
#defineSDATRISC4
voidstart_i2c();
voidstop_i2c();
voidsend_byte(ucharc);
ucharreceive_byte();
voidI_send_str(ucharsla,ucharsuba,uchar*s,ucharno);
voiddelay_250ms();
voidi2c_error();
ucharcode[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
ucharno,ack,c,data;

voidmain(void)
{
uchari;
TRISC=0Xff;//C口设为输入RC3为SCL线,RC4为SDA线。
PORTC=0X00;
TRISD=0X00;//D口为输出,显示IC24LC02中读出的内容
PORTD=0X00;//初始显示全亮
I_send_str(0xa0,0x00,code,9);//页写入code数组到24LC02,器件地址为0Xa0,子地址为0X00,共9个数。
delay_250ms();

///////////开始读出到D口进行显示,根据Randomread时序图。
while(1)
{
for(i=0x00;i<0x09;i++)
{
start_i2c();
send_byte(0xa0);//发送器件地址,即DEVICEADDRESS。
if(ack==0)i2c_error();//如果24LC02无应答。则进入I2CERROR错误指示。
send_byte(i);//发送字地址,即WORDADDRESS。D口显示数组。
if(ack==0)i2c_error();
start_i2c();//重新启动总线。
send_byte(0xa1);//发送读命令和器件地址DEVICEADDRESS。
if(ack==0)i2c_error();
data=receive_byte();
stop_i2c();
PORTD=data;
delay_250ms();
}
}
}

/*******************************************************************
起动总线函数
函数原型:voidstart_i2c();
Function:startontheI2Cbus
*******************************************************************/
voidstart_i2c()
{
SDA=1;//发送启始条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop();//24LC02要求建立时间大于4,7S
SDA=0;//发送起始信号
nop();nop();nop();nop();nop();
SCL=0;//钳住I2C总线,准备发送数据或接收数据
nop();nop();
}

/*******************************************************************
停止总线函数
函数原型:voidstop_i2c();
Function:stoptheI2Cbus
*******************************************************************/
voidstop_i2c()
{
SDA=0;//发送结束条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop();
SDA=1;
nop();nop();nop();nop();
}
/*=================================================================
字节数据传送函数
函数原型:voidsend_byte(ucharc);
Function:将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态
位进行操作(不应答或非应答都使ack=0),发送数据正常,ack=1;ack=0
表示被控器无应答或损坏。
==================================================================*/
voidsend_byte(ucharc)
{
ucharbit_count;
for(bit_count=0;bit_count<8;bit_count++)
{
if((c<else{SDA=0;}
nop();
SCL=1;
nop();nop();nop();nop();nop();
SCL=0;
}
nop();nop();
SDA=1;
nop();nop();
SCL=1;
nop();nop();nop();
if(RC4==1)ack=0;
elseack=1;//用ASK=1为有应答信号
SCL=0;
nop();nop();
}
/*==================================================================
字节数据接收函数
函数原型:ucharreceive_byte();
FUNCTION:用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数。
===================================================================*/
ucharreceive_byte()
{
ucharretc,bit_count;
retc=0;
SDA=1;
for(bit_count=0;bit_count<8;bit_count++)
{
nop();
SCL=0;
nop();nop();nop();nop();nop();
SCL=1;
nop();nop();
retc=retc<<1;
if(RC4==1)retc=retc+1;
nop();nop();
}
SCL=0;
nop();nop();
return(retc);
}

/*================================================================
向有子地址器件发送多字节数据函数
函数原型:bitI_send_str(ucharsla,ucharsuba,uchar*s,ucharno);
Function:从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
返回1表示操作成功,否则操作有误。
=================================================================*/
voidI_send_str(ucharsla,ucharsuba,uchar*s,ucharno)
{
uchari;
start_i2c();
send_byte(sla);
if(ack==0)i2c_error();
send_byte(suba);
if(ack==0)i2c_error();
for(i=0;i{
send_byte(*s);
if(ack==0)i2c_error();
s++;
}
stop_i2c();
//return(1);
}
/*****************************************************************
延时函数
函数原型:voiddelay_250ms();
FUNCTION:延明250ms
*****************************************************************/
voiddelay_250ms()
{
unsignedintd=24999;
while(--d);
}
/*****************************************************************
总线错误函数
函数原型: voidi2c_error();
Function:通过RD7闪动8次表示总线操作失败一次报警。
*****************************************************************/
voidi2c_error()
{
uchari;
for(i=0;i<8;i++)
{
RD7=0;
delay_250ms();
RD7=1;
delay_250ms();
}
}
/**********END**************/

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭