资讯详情

板内板间通信协议及接口(三)I2C

这节展开I2C通信协议简介。

I2C是什么 在消费电子、工业电子等领域,将使用各种芯片,如微控制器、电源管理、显示驱动、传感器、存储器、转换器等,它们有不同的功能,有时需要快速的数据交互,为了使用最简单的方式使芯片互联,所以I2C诞生了,I2C(Inter-Integrated Circuit)一般的总线协议。它是由Philips(飞利浦)公司,现在NXP(恩智浦)半导体开发的简单双向两线总线协议标准。

对于硬件设计师来说,芯片之间的通信只需要两个管脚,很少的连接线和面积,软件开发者可以使用相同的管脚I2C驱动库实现了不同设备的驱动,大大降低了软件的开发时间。极低的工作电流降低了系统的功耗,完善的响应机制大大提高了通信的可靠性。

5种速率 I2C协议可以在以下五种速率模式下工作,不同的设备可以支持不同的速率。

标准模式(Standard):100kbps 快速模式(Fast):400kbps 快速模式 (Fast-Plus):1Mbps 高速模式(High-speed):3.4Mbps 超快模式(Ultra-Fast):5Mbps(单向传输)

【bps:bit/s,即SCL的频率】

超快模式通常用于单向数据传输LED、LCD不需要响应的设备和正常的设备I2C操作顺序相似,但只写数据,不需要考虑ACK应答信号。

在I2C协议官方文件NXP_UM10204_I2C-bus specification and user manual_Rev.6.超快模式等模式3.2和3.一章分别介绍。

4种信号 I2C协议中最基本的信号是:开始、停止、响应和非响应信号。

起始信号 I2C协议规定,SCL在高电平时,SDA这种信号从高到低变化为起始信号。

停止信号 I2C协议规定,SCL高电平,SDA这种信号是从低到高的停止信号。

数据有效性

I2C协议对数据的采样发生在SCL在数据传输过程中,除了开始和停止信号外,SCL高电平时,SDA必须,不允许改变,在SCL只有在低电平时才能改变。

应答信号 I2C最大的特点之一是有一个完善的响应机制。当机器接收到主机的数据时,它会回复响应信号,通知主机我收到了。

一个字节传输完成后,出现响应信号,即第九个SCL主机需要在时钟周期内释放SDA总线将总线控制权移交给从机器。由于上拉电阻的作用,此时总线为高电平。如果从机器正确收到主机发送的数据,它将被移交SDA拉低,表示响应。

使用MCU、FPGA当控制器实现时,需要在第个SCL时钟周期把SDA如果读取设置为高阻输入状态SDA为低电平,则表示数据已成功接收,可进行下一步操作。

非应答信号

当第9个SCL时钟周期,SDA保持高电平,表示非应答信号。

非应答信号可能是由主机或从机产生的,产生非应答信号的主要情况如下:

I2C从机设备总线上没有主机指定的地址 从机器正在执行一些操作,处于忙碌状态,还没有准备好与主机通信 从机器不支持主机发送的一些控制命令 当主机接收从机数据时,主机产生非响应信号,通知从机数据传输结束,不再发送数据 读写时序 将指定的数据操作顺序写入指定的寄存器地址:

请注意,读取数据时有两个起始信号。

7位和10位地址

大多数I2C器件支持有些设备也支持模式,两种类型的设备可以连接到同一个I2C在总线上,目前有10个地址的设备

主机发送,从机接收。用10个地址写时序:

主机接收,从机发送。阅读时序使用10位地址:

I2C保留字节

I2C除了制造商指定的设备地址外,还有一些保留字节,主要有两组 xxx和1111 xxx,保留字节的含义:

上述10位地址模式使用最后一个字节。

第一种广播模式可以写入第二个字节06h来复位I2C总线上的所有从机器件。具体操作时序可查看文档NXP_UM10204_I2C-bus specification and user manual_Rev.6:3.1.12 Reserved addresses详细介绍了章节。其中device ID控制字(1111 1xx一、可读取I2C装置内24位装置ID,通过对照NXP I2C协议设备列表可查询设备的制造商和型号。

设备ID与设备制造商对应的表格

SPI和I2C的对比 I2C是半双工,SPI是全双工。

I2C支持多主多模式,SPI只能有一个主机。

从GPIO占用,I2C占用更少的GPIO,节约资源。

I2C数据可靠性较高的响应机制,SPI没有响应机制。

I2C最高速率3不会太高.4Mbps,SPI能达到很高的速率。

I2C通过设备地址选择机器,机器数量的增加不会导致GPIO的增加,而SPI通过CS选择从机,每增加一个从机就要多占用一个GPIO。

SPI协议在SCLK边缘采样数据,I2C在SCL数据采样采样为高电平装置。

两者大多用于板内设备的短距离通信。

1.IIC简介 I2C是以半双工方式传输的同步通信串行总线。SDA和时钟SCL数据可以发送和接收。CPU与被控IC之间、IC与IC双向传输,高速IIC总线一般可达400kbps以上。

2.读写数据概念 1.阅读数据:指MCU根据一定的顺序从设备的数据总线读取设备的数据。一般来说,MCU提供一个边缘信号,告诉设备可以发送数据,设备检测到边缘信号后,立即在数据总线上更新数据,数据稳定后,MCU可读取数据。

2. 写数据:指MCU将数据写入设备,其操作是:先将数据放在数据总线上,等待其稳定,MCU产生一个边沿信号,将数据写入器件

3.IIC总线读写数据

读数据:MCU发出边缘信号(下降边缘)告诉设备发送数据,检测到边缘信号后,设备更新数据,等待稳定MCU读取数据。 写数据:MCU首先将数据放置在数据总线上,等待其稳定,从机器检测到边缘信号(上升边缘),然后将数据写入设备 3.IIC协议 1. 包含空闲状态、起始信号、停止信号、应答信号、数据的有效性、数据传输

空闲状态:I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时,各设备的输出级场效应管处于截止状态,即释放总线,两条信号线各自的上拉电阻提高电平 起始信号:当SCL为高期间,SDA从高到低的跳变 停止信号:当SCL为高期间,SDA从低到高的跳变

响应信号:每发送一个字节,发送器在时钟脉冲9期间释放数据线,接收器反馈响应信号。 当响应信号为低电平时,规定有效响应位置(ACK简称应答位),表示接收器已成功接收字节;应答信号为高电平时,规定为非应答位(NACK),一般来说,接收器接收字节失败。 对反馈的有效响应位置ACK要求是接收器在第9时钟脉冲前的低电平期间SDA降低线路,确保在此时钟的高电平期间是稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK通知被控发送器结束数据发送并释放信号SDA主控接收器发送停止信号P。

数据的有效性:I2C当总线传输数据时,当时钟信号为高电平时,数据线上的数据必须保持稳定。只有当时钟线上的信号为低电平时,才允许数据线上的高电平或低电平状态发生变化。 即:数据在SCL需要在上升边到来之前做好准备。并且在下降边到来之前必须稳定

简单来说:(首先忽略响应信号;图中SCL同一脉冲)

4.总结 参考博客:I2C 详细说明时序,准确到每个时钟_谁de如花的博客-CSDN博客_i2c时钟

4.1 MCU通过IIC将数据连续写入两个字节

要点:

SCL低电平期,SDA允许数据变化,主机可以发送数据SDA所以要设置主机SDA输出,降低SCL。 SCL高电平期间,SDA数据稳定,通常从机器上写入数据。8个连续脉冲完成字节写入。 第九脉冲,从机在低电平时将响应信号放入SDA主机在高电平期间读取SDA,所以要设置主机SDA为输入,SDA为0则应答,SDA为1则非应答

4.2 MCU通过IIC读取器件数据,读取两个字节

要点:

主机读取数据,因此设置SDA为输入 时钟下降,沿着通知从机将数据放置SDA在低电平期间,从机会上放置数据SDA在接下来的高电平期间,数据稳定,主机正在读取SDA数据 8个连续脉冲完成字节读取 5.正点原子的程序实例:

#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;} #define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<lt;28;}

//IO操作函数     #define IIC_SCL    PBout(6) //SCL #define IIC_SDA    PBout(7) //SDA     #define READ_SDA   PBin(7)  //输入SDA

//初始化IIC void IIC_Init(void) {                              GPIO_InitTypeDef GPIO_InitStructure;     RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE );    //使能GPIOB时钟             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     GPIO_Init(GPIOB, &GPIO_InitStructure);     GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);     //PB6,PB7 输出高 }

//产生IIC起始信号 void IIC_Start(void) {     SDA_OUT();     //sda线输出     IIC_SDA=1;                 IIC_SCL=1;     delay_us(4);      IIC_SDA=0;//when CLK is high,DATA change form high to low     delay_us(4);     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 }      

//产生IIC停止信号 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);                                    }

//等待应答信号到来 //返回值:1,接收应答失败 //        0,接收应答成功 u8 IIC_Wait_Ack(void) {     u8 ucErrTime=0;     SDA_IN();      //SDA设置为输入       IIC_SDA=1;delay_us(1);            IIC_SCL=1;delay_us(1);         while(READ_SDA)     {         ucErrTime++;         if(ucErrTime>250)         {             IIC_Stop();             return 1;         }     }     IIC_SCL=0;//时钟输出0             return 0;   } //产生ACK应答 void IIC_Ack(void) {     IIC_SCL=0;     SDA_OUT();     IIC_SDA=0;//低电平期间将SDA线拉低     delay_us(2);     IIC_SCL=1;     delay_us(2);     IIC_SCL=0; } //不产生ACK应答             void IIC_NAck(void) {     IIC_SCL=0;     SDA_OUT();     IIC_SDA=1;//低电平期间不拉低SDA线     delay_us(2);     IIC_SCL=1;     delay_us(2);     IIC_SCL=0; }  

                                        //MCU通过IIC往从机写入一个字节 //返回从机有无应答 //1,有应答 //0,无应答               void IIC_Send_Byte(u8 txd) {                             u8 t;        SDA_OUT();//设置SDA 为输出           IIC_SCL=0;//拉低时钟开始数据传输     for(t=0;t<8;t++)     {                       IIC_SDA=(txd&0x80)>>7;//SCL低电平期间,主机将一位数据放置SDA上         txd<<=1;                delay_us(2);           IIC_SCL=1;//SCL高电平期间,往从机写入数据         delay_us(2);         IIC_SCL=0;             delay_us(2);     }     }          //MCU通过IIC读取从机一个字节,ack=1时,发送ACK,ack=0,发送nACK    u8 IIC_Read_Byte(unsigned char ack) {     unsigned char i,receive=0;     SDA_IN();//SDA设置为输入     for(i=0;i<8;i++ )     {         IIC_SCL=0;//SCL低电平期间,从机将数据放在SDA上         delay_us(2);         IIC_SCL=1;//SCL高电平期间,主机读取SDA数据         receive<<=1;         if(READ_SDA)receive++;            delay_us(1);     }                         if (!ack)         IIC_NAck();//发送nACK     else         IIC_Ack(); //发送ACK        return receive; }

6.2402芯片的使用

        

(1)芯片的寻址:         AT24C设备地址为如下,前四位固定为1010,A2~A0为由管脚电平。AT24CXX EEPROM Board模块中默认为接地。A2-A0=000,最后一位表示读写操作。所以AT24Cxx的读地址为0xA1,写地址为0xA0。

也就是说如果是 写24C02的时候,从器件地址为10100000(0xA0); 读24C02的时候,从器件地址为10100001(0xA1)。

(2)片内地址寻址:

      芯片寻址可对内部256B中的任一个进行读/写操作,其寻址范围为00~FF,共256个寻址单位。 具体解释:         由于24C02只有256个字节的存储空间,所以只需要1个字节就可以寻址完24C02的存储空间,但是无法寻址完更大容量的存储IC,比如24C04的存储容量是512字节,需要9个bit的地址位才能寻址完。由上图可以看到,24C04的设备地址内是没有A0参数的,被a8代替了,这个a8就是24C04的第9个bit的地址位,也就是说24C04的A0引脚是不起作用的,这样也就造成了在I2C总线上只能同时挂载4个24C04芯片。其它存储器如24C08、24C16也可以这么类推。

24C02的WP引脚是写保护引脚,当WP引脚接高电平的时,24C02只能进行读取操作,不能进行写操作。只有当WP引脚悬空或接低电平时,24C02才能进行写操作。 ———————————————— 版权声明:本文为CSDN博主「惟肖肖肖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xc_123/article/details/111632399

———————————————— 版权声明:本文为CSDN博主「whik1194」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/whik1194/article/details/115040856

标签: 接地电阻cc2520

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台