I2C协议代码

合集下载

I2C通讯协议(中文译版)I2C_Spec

I2C通讯协议(中文译版)I2C_Spec
11 标准模式 I2C 总线规范的扩展 ............................................................................. 16 12 快速模式 ............................................................................................................. 17 13 Hs 模式 ............................................................................................................... 17
1.1 版本 1.0-1992 .................................................................................................................... 3 1.2 版本 2.0-1998 .................................................................................................................... 3 1.3 版本 2.1-2000 .................................................................................................................... 3 1.4 购买 Philips 的 I2C 总线元件 .............................................................................................. 3

I2C总线协议AT24c02程序

I2C总线协议AT24c02程序

I2C总线协议(AT24c02)程序主:STC89C54从:AT24C02电路图时序图下面是代码#include ;#define uchar unsigned char#define addr_x 0xae//写#define addr_d 0xaf//读sbit sda = P2^1;//数据管脚sbit scl = P2^0;//时钟管脚bit ack;void DelayUs2x(unsigned char t)//延时1{while(--t);}void DelayMs(unsigned char t)//延时2{ while(t--){ //大致延时1mS DelayUs2x(245); DelayUs2x(245);}}void delay() //延时大于4μs{;;}void i2_qs()//起始信号{sda = 1;//拉高数据scl = 1;//拉高时钟delay();//延时大于 4μssda =0;//拉低数据产生起始信号(下降沿)delay();//延时大于 4μsscl = 0;//拉低时钟delay();//延时大于4μs}void i2_tz()//停止信号{sda = 0;//拉低数据scl = 1;//拉高时钟delay();//延时大于 4μssda = 1;//拉高时钟产生结束信号(上升沿)delay();//延时大于4μs}void i2_ack(bit _ack)//入口产生 0 ack 1nak{sda = _ack;//ack或者nakscl = 1;//拉高时钟delay();//延时大于 4μsscl = 0;//拉低时钟delay();//延时大于 4μs}void i2_fs(uchar Data) //发送8位数据{uchar i;for(i=0;i<8;i++)//8位计数{Data <<= 1;//把最高位移送到进制标志位中(CY)sda = CY;//把进制位中的数据赋值给数据线scl = 1;//拉高时钟delay();//延时大于 4μsscl = 0;//拉低时钟//这里}//下面代码是接收ACK的代码delay();//延时大于4μssda = 1;//拉高数据准备接收ACKscl = 1;//拉高时钟产生稳定的有效的数据(相对的)if(sda==1)//确认接收的是ACK还是NAKack = 0;//ackelseack = 1;//nakscl = 0;//拉低时钟delay();//延时大于 4us}uchari2_js()//接收8位数据{uchar i,Data = 0;sda = 1;//使能内部上拉,准备读取数据for(i=0;i<8;i++)//8位计数器{Data <<= 1;//移出数据的最高位scl = 1;//拉高时钟delay();//延时大于 4usData |= sda;//接收数据scl = 0;//拉低时钟delay();//延时大于 4us}return Data;}void i2_sj_x(uchar addr,uchar Data)//往设备内写入数据(参数 1、寄存器地址 2、写入的数据){i2_qs();//起始信号i2_fs(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_fs(Data);//写入设备的数据i2_tz();//停止信号}uchar i2_sj_d(uchar addr)//读取数据(参数寄存器地址){ucharData;i2_qs();//起始信号i2_fs(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_qs();//起始信号i2_fs(addr_d);//设备地址+读信号Data =i2_js();//读取数据i2_ack(0);//ACK应答i2_tz();//停止信号return Data;//返回读取的数据}voidmain(void){uchar dat;i2_sj_x(3,0x0f); //数据写入24c02DelayMs(50);dat = i2_sj_d(3); //从24c02中读取数据P1 = dat;//使用8个LED显示读出的数据while(1){;}}以上代码只是简单的实现I2C总线的读写。

I2C通信时序图解析

I2C通信时序图解析

I2C通信时序图解析⼀、I2C协议简介 I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被⼴泛地使⽤在系统内多个集成电路(IC)间的通讯。

关于I2C协议的更多内容,可阅读《I2C总线协议》,本博⽂主要分析I2C波形图,对于I2C的基础知识不在做介绍。

⼆、I2C协议标准代码2.1 起始信号&停⽌信号 起始信号:当 SCL 线是⾼电平时 SDA 线从⾼电平向低电平切换。

停⽌信号:当 SCL 线是⾼电平时 SDA 线由低电平向⾼电平切换。

2.1.1 起始信号代码void I2C_Start(void){I2C_SDA_High(); //SDA=1I2C_SCL_High(); //SCL=1I2C_Delay();I2C_SDA_Low();I2C_Delay();I2C_SCL_Low();I2C_Delay();}2.1.2 停⽌信号代码void I2C_Stop(void){I2C_SDA_Low();I2C_SCL_High();I2C_Delay();I2C_SDA_High();I2C_Delay();}2.2 发送⼀个字节 CPU向I2C总线设备发送⼀个字节(8bit)数据u8 I2C_SendByte(uint8_t Byte){uint8_t i;/* 先发送⾼位字节 */for(i = 0 ; i < 8 ; i++){if(Byte & 0x80){I2C_SDA_High();}else{I2C_SDA_Low();}I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();if(i == 7){I2C_SDA_High(); /* 释放SDA总线 */}Byte <<= 1; /* 左移⼀位 */I2C_Delay();}} 2.3 读取⼀个字节 CPU从I2C总线设备上读取⼀个字节(8bit数据)u8 I2C_ReadByte(void){uint8_t i;uint8_t value;/* 先读取最⾼位即bit7 */value = 0;for(i = 0 ; i < 8 ; i++){value <<= 1;I2C_SCL_High();I2C_Delay();if(I2C_SDA_READ()){value++;}I2C_SCL_Low();I2C_Delay();}return value;}2.4 应答2.4.1 CPU产⽣⼀个ACK信号void I2C_Ack(void){I2C_SDA_Low();I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();I2C_SDA_High();}2.4.2 CPU产⽣⼀个⾮ACK信号void I2C_NoAck(void){I2C_SDA_High();I2C_Delay();I2C_SCL_High();I2C_Delay();I2C_SCL_Low();I2C_Delay();}2.4.3 CPU产⽣⼀个时钟,并读取器件的ACK应答信号uint8_t I2C_WaitToAck(void){uint8_t redata;I2C_SDA_High();I2C_Delay();I2C_SCL_High();I2C_Delay();if(I2C_SDA_READ()){redata = 1;}else{redata = 0;}I2C_SCL_Low();I2C_Delay();return redata;}三、I2C通信时序图解析 有了上边的I2C总线标准代码的基础,下⾯我们进⼊本博⽂所要讲解的内容,怎么分析I2C的时序图,以O2Micro的OZ9350为例,OZ9350是⼀款模拟前端(AFE)的IC器件。

i2c通信协议

i2c通信协议

i2c通信协议I2C通信协议一、简介I2C (Inter-Integrated Circuit),即集成电路互连,是用于在集成电路之间进行通信的串行通信协议。

它是由Philips(飞利浦)公司于1982年提出,并在当今的电子设备中广泛应用。

I2C通信协议采用两根总线:串行数据线SDA(Serial Data Line)和串行时钟线SCL(Serial Clock Line)。

不同于其他协议,I2C通信协议具有简单、节约外设引脚的特点,被广泛应用于各种嵌入式系统中,如传感器、温度计、数字信号处理器等。

二、基本原理在I2C通信协议中,设备之间的通信通过主从关系进行。

主设备负责生成时钟信号和控制总线的传输,从设备则根据主设备的请求进行响应。

主设备和从设备之间的通信是基于传输一个字节数据的方式进行的。

传输的字节数据由一个起始位、八位数据位、一个奇偶校验位和一个停止位组成。

信息按照从高位到低位的顺序传输,同时由时钟信号进行同步。

三、通信过程I2C通信协议的通信过程主要包括起始信号、地址传输、数据传输和停止信号四个阶段。

1. 起始信号起始信号由主设备产生,用于标识接下来的通信过程开始。

起始信号的产生是通过将数据线(SDA)从高电平切换到低电平时完成的。

在通信开始之前,主设备需要发送起始信号来获取总线控制权。

2. 地址传输主设备在发送起始信号后,紧接着发送一个I2C从设备的地址。

地址由7位或10位组成,其中7位地址方式是I2C通信协议最常用的方式。

地址中的最高位表示对从设备进行读取(1)或写入(0)操作。

通过这个地址,主设备可以选择与特定从设备进行通信。

3. 数据传输地址传输完成后,主设备和从设备之间的数据传输开始。

数据的传输顺序是从高位到低位。

主设备向从设备传输数据时,从设备通过拉低SDA线来接收数据。

从设备向主设备传输数据时,主设备必须确认数据的接收情况,操作是保持SDA线为高电平。

4. 停止信号通信结束时,主设备发送停止信号,用于标示通信过程的结束。

STM32系列芯片I2C源代码

STM32系列芯片I2C源代码

/* I2C configuration */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
{
file:///C|/Users/ding/Desktop/I2C.txt[2014/9/12 22:53:03]
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
/* Configure I2C1 pins: SCL and SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); }
}
/* Private function prototypes -----------------------------------------------*/

I2C串行通信原理及代码演示

I2C串行通信原理及代码演示

I2C串行通信原理及代码演示I2C串行通信标准的从属模式和多主控模式,串行接口仅由两条信号线组成:串行时钟(SCL)和串行数据(SDA)。

串行数据(SDA)SDA引脚是一个开漏极双向输入/输出引脚,用于在设备之间连续传输数据。

SDA引脚必须使用外部向上拉式电阻拉动(值不超过10 kΩ),并且可以与同一母线上其他设备的任意数量的其他开漏或开路集电器引脚相连。

串行时钟(SCL)SCL引脚用于为设备提供一个时钟,并控制进出设备的数据流。

SDA引脚上的命令和输入数据总是锁定在SCL的上升边缘上,而SDA引脚上的输出数据则锁定在SCL的下降边缘上。

当串行总线空闲时,SCL必须被强制高或使用外部上拉电阻拉高。

SCL引脚用于接收来自主的的时钟信号,而双向SDA引脚用于接收来自主机的的命令和数据信息,并将数据发送回主机。

数据总是被锁定在SCL上升边缘的中,并且总是从SCL下降边缘的设备输出。

在总线通信期间,每个时钟周期传输一个数据比特,在传输8位(1字节)数据之后,接收设备必须在主设备生成的第9个时钟周期(ACK/NACK时钟周期)中以确认(ACK)或不确认(NACK)响应比特进行响应。

因此,传输的数据每一个字节需要9个时钟周期。

在数据传输期间,SDA引脚上的数据只能在SCL低时改变,并且当SCL高时数据必须保持稳定。

如果当SCL较高时,SDA销上的数据发生变化,则将发生开始或停止条件。

启动和停止条件用于启动和结束主设备和从设备之间的所有串行总线通信。

在开始和停止条件之间传输的数据字节数不受限制,并由主节点决定。

为了使串行总线空闲,SCL和SDA引脚必须同时处于逻辑高状态。

时钟和数据转换要求SDA引脚是一个开漏端,因此必须用外部的拉式电阻拉高。

SCL是一个输入端,可以驱动高或拉高使用外部拉上电阻。

SDA引脚上的数据只能在SCL的低时间段内发生变化。

SCL高电平期间的数据变化将定义的开始或停止条件。

1、启动条件启动条件当SDA引脚发生“高到低”的转变,而SCL引脚处于稳定的逻辑“1”状态,将使设备脱离待机状态。

I2C通讯协议

I2C通讯协议

I2C通讯协议协议名称:I2C通讯协议一、引言I2C(Inter-Integrated Circuit)通讯协议是一种串行通信协议,用于在集成电路(IC)之间进行数据传输。

本协议旨在规范I2C通讯的数据格式、传输速率、地址分配和错误处理等方面的要求,以确保不同设备之间的互操作性和数据的可靠传输。

二、范围本协议适用于使用I2C通讯协议进行数据传输的所有设备,包括但不限于芯片、传感器、模块等。

三、术语定义1. 主设备(Master):发起I2C通讯的设备。

2. 从设备(Slave):响应I2C通讯的设备。

3. 传输速率(Bit Rate):数据传输的速度,单位为bps。

4. 起始条件(Start Condition):主设备发出的开始信号,表示I2C通讯的开始。

5. 停止条件(Stop Condition):主设备发出的停止信号,表示I2C通讯的结束。

6. 传输字节(Data Byte):在I2C通讯中传输的8位数据。

7. 地址(Address):从设备的唯一标识,用于选择通讯对象。

四、通讯流程1. 主设备发起通讯:a) 主设备发送起始条件。

b) 主设备发送从设备地址和读写位(R/W)。

c) 主设备等待从设备的应答信号。

d) 从设备应答后,主设备继续发送数据或接收数据。

2. 从设备响应通讯:a) 从设备接收起始条件。

b) 从设备接收自身地址和读写位(R/W)。

c) 从设备发送应答信号。

d) 主设备发送或接收数据。

五、数据格式1. 起始条件和停止条件:a) 起始条件:SDA(串行数据线)从高电平跳变到低电平,同时SCL(串行时钟线)保持高电平。

b) 停止条件:SDA从低电平跳变到高电平,同时SCL保持高电平。

2. 传输字节格式:a) 数据传输是以字节为单位进行的,每个字节由8位二进制数据组成。

b) 数据传输的最高位为起始位(Start Bit),接下来是7位数据位(D7-D1),最低位为停止位(Stop Bit)。

iic协议代码

iic协议代码

iic协议代码IIC协议,也称为I2C协议或IIC,是一种用于连接低速外围设备的串行通信总线。

它是由飞利浦公司(现在的恩智浦半导体)在1980年代早期为了让主板、嵌入式系统或手机中的芯片之间能通过少量的引脚进行通信而开发的。

IIC协议的代码通常指的是实现IIC通信协议的软件或固件代码。

在不同的编程环境和应用中,实现IIC协议的细节可能会有所不同。

下面是一个非常基础的伪代码示例,展示了如何实现一个简单的IIC通信过程:```python# 假设我们有一个IIC通信类class IICCommunication:def __init__(self, sda_pin, scl_pin):self.sda_pin = sda_pinself.scl_pin = scl_pin# 初始化IIC引脚为输入模式pinMode(sda_pin, INPUT)pinMode(scl_pin, INPUT)# 初始化其他必要的变量def start(self):# 发送起始条件digitalWrite(self.sda_pin, HIGH)digitalWrite(self.scl_pin, HIGH)# 等待时钟线变为低电平while digitalRead(self.scl_pin) == HIGH:pass# 设置SDA为低电平,表示开始条件digitalWrite(self.sda_pin, LOW)def send_byte(self, byte):# 发送一个字节for i in range(8):# 发送位bit = byte & 0x01# 设置SDA线digitalWrite(self.sda_pin, bit)# 等待时钟线变为低电平while digitalRead(self.scl_pin) == HIGH:passbyte >>= 1# 发送ACK位(应答位)digitalWrite(self.sda_pin, LOW)def read_byte(self):# 读取一个字节byte = 0for i in range(8):byte <<= 1# 等待时钟线变为低电平while digitalRead(self.scl_pin) == HIGH:pass# 读取SDA线状态bit = digitalRead(self.sda_pin)byte |= bit# 发送ACK位digitalWrite(self.sda_pin, LOW)return bytedef stop(self):# 发送停止条件digitalWrite(self.sda_pin, LOW)digitalWrite(self.scl_pin, LOW)# 等待时钟线变为高电平while digitalRead(self.scl_pin) == LOW:passdigitalWrite(self.sda_pin, HIGH)# 使用IICCommunication类进行通信iic = IICCommunication(D2, D1) # 假设D2和D1是控制SDA和SCL的GPIO引脚iic.start()iic.send_byte(0x55) # 发送设备地址# 接收应答ack = iic.read_byte()if ack == 0: # 如果接收到ACK,继续通信iic.send_byte(0x00) # 发送命令或数据data = iic.read_byte() # 读取数据# ...处理数据...iic.stop()```请注意,这只是一个示例,实际代码实现会依赖于具体的硬件和软件环境。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

此模块包括发送数据及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,能很方便的与用户程序进行连接并扩展。

需要注意的是,函数是采用延时方法产生SCL 脉冲,对高晶振频率要做一定的修改!!说明:1us机器周期,晶振频率要小于12MHz返回1 则操作成功,返回0 则操作失败。

sla 为器件从地址,suba 为器件子地址。

************************************************************************* ************/#include "AT89X52.h"#include <intrins.h>#define _Nop() _nop_() //定义空指令sbit SDA = P1^3; //模拟I2C数据传输位sbit SCL = P1^2; //模拟I2C时钟控制位bit bdata I2C_Ack; //应答标志位/************************************ I2C_Start************************************函数名:void I2C_Start()入口:出口:功能描述:启动I2C总线,即发送I2C初始条件调用函数:全局变量:创建者:陈曦日期:2005-6-15修改者:日期:************************************************************************* *********/void I2C_Start(){SDA = 1; //发送起始条件的数据信号_Nop();SCL = 1;_Nop(); //起始条件建立时间大于4.7us,延时_Nop();_Nop();_Nop();_Nop();SDA = 0; //发送起始信号_Nop(); //起始条件建立时间大于4us,延时_Nop();_Nop();_Nop();_Nop();SCL = 0; //钳住I2C总线准备发送或接收数据_Nop();_Nop();}/************************************ I2C_Stop************************************函数名:void I2C_Stop()入口:出口:功能描述:结束I2C总线,即发送I2C结束条件调用函数:全局变量:创建者:陈曦日期:2005-6-15修改者:日期:************************************************************************* *********/void I2C_Stop(){SDA = 0; //发送结束条件的数据信号_Nop();SCL = 1; //发送结束条件的时钟信号_Nop(); //结束条件建立时间大于4us,延时_Nop();_Nop();_Nop();_Nop();SDA = 1; //发送I2C总线结束信号_Nop();_Nop();_Nop();_Nop();}/************************************ I2C_CheckAck************************************函数名:bit I2C_CheckAck(void)入口:出口:0(无应答),1(有应答)功能描述:检验I2C总线应答信号,有应答则返回1,否则返回0,超时值取255调用函数:void I2C_Stop()全局变量:创建者:陈曦日期:2005-6-15修改者:日期:************************************************************************* *********/bit I2C_CheckAck(void){uchar errtime = 255; // 因故障接收方无Ack,超时值为255SDA = 1;_Nop();_Nop();_Nop();SCL = 1;_Nop(); //时钟电平周期大于 4 us_Nop();_Nop();_Nop();_Nop();while(SDA){errtime--;if(errtime==0){I2C_Stop();return(0);}}SCL = 0;_Nop();return(1);}/************************************ I2C_SendB************************************函数名:void I2C_SendB(uchar c)入口:uchar 型数据出口:功能描述:字节数据传送函数,将数据 c 发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作调用函数:bit I2C_CheckAck()全局变量:I2C_Ack************************************************************************* *********/void I2C_SendB(uchar c){uchar BitCnt;for (BitCnt=0; BitCnt<8; BitCnt++) //要传送的数据长度为8位{if((c<<BitCnt)&0x80) //判断发送位(从高位起发送){SDA = 1;}else{SDA = 0;}_Nop();_Nop();SCL = 1; //置时钟线为高通知被控器开始接收数据位_Nop(); //保证时钟高电平周期大于4us_Nop();_Nop();_Nop();_Nop();SCL = 0;}_Nop();_Nop();I2C_Ack = I2C_CheckAck(); //检验应答信号_Nop();_Nop();}函数名:uchar I2C_RcvB()入口:出口:uchar型数据功能描述:接收从器件传来的数据,并判断总线错误(不发应答信号),收完后需要调用应答函数。

uchar I2C_RcvB(){uchar retc;uchar BitCnt; //位retc = 0;SDA = 1; //置数据总线为输入方式for(BitCnt=0;BitCnt<8;BitCnt++){_Nop();SCL = 0; //置时钟线为低准备接收数据位_Nop(); //时钟低电平周期大于4.7us_Nop();_Nop();_Nop();_Nop();SCL = 1; //置时钟线为高使数据有效_Nop();_Nop();retc = retc<<1;if(SDA==1){retc = retc + 1; //读数据位,接收的数据放入retc中}_Nop();_Nop();}SCL = 0;_Nop();_Nop();return(retc);}/************************************ I2C_Ackn************************************函数名:void I2C_Ackn(bit a)入口:0或1出口:功能描述:主控制器进行应答信号(可以是应答或非应答信号)调用函数:全局变量:************************************************************************* *********/void I2C_Ackn(bit a){if(a==0) //在此发送应答或非应答信号{SDA = 0;}else{SDA = 1;}_Nop();_Nop();_Nop();SCL = 1;_Nop(); //时钟电平周期大于 4 us_Nop();_Nop();_Nop();_Nop();SCL = 0; //清时钟线钳住I2C总线以便继续接收_Nop();_Nop();}函数名:bit I2C_ISendB(uchar sla, uchar suba, uchar c)入口:从器件地址sla,子地址suba, 发送字节 c出口:0(操作有误),1(操作成功)功能描述:从启动总线到发送地址、数据,结束总线的全过程,如果返回1,表示操作成功,否则操作有误。

调用函数:I2C_Start(),I2C_SendB(uchar c),I2C_Stop()全局变量:I2C_Ackbit I2C_ISendB(uchar sla, uchar suba, uchar c){I2C_Start(); //启动总线I2C_SendB(sla); //发送器件地址if(!I2C_Ack){return(0);}I2C_SendB(suba); //发送器件子地址if(!I2C_Ack){return(0);}I2C_SendB(c); //发送数据if(!I2C_Ack){return(0);}I2C_Stop(); //结束总线return(1);}函数名:bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)入口:从器件地址sla, 子地址suba, 收到的数据在 c出口:1(操作成功),0(操作有误)功能描述:从启动总线到发送地址、读数据,结束总线的全过程。

调用函数:I2CS_tart(),I2C_SendB(uchar c),I2C_RcvB(),I2C_Ackn(bit a),I2C_Stop()全局变量:I2C_Ackbit I2C_IRcvB(uchar sla, uchar suba, uchar *c){I2C_Start(); //启动总线I2C_SendB(sla);if(!I2C_Ack){return(0);}I2C_SendB(suba); //发送器件子地址if(!I2C_Ack){return(0);}I2C_Start(); //重复起始条件I2C_SendB(sla+1); //发送读操作的地址if(!I2C_Ack){return(0);}*c = I2C_RcvB(); //读取数据I2C_Ackn(1); //发送非应答位I2C_Stop(); //结束总线return(1);}。

相关文档
最新文档