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()```请注意,这只是一个示例,实际代码实现会依赖于具体的硬件和软件环境。

学习笔记一:I2C协议学习和Verilog实现

学习笔记一:I2C协议学习和Verilog实现

学习笔记⼀:I2C协议学习和Verilog实现1//////////////////////////////////////////////////2//clk = 20 MHz ,⼀个周期50ns3//sck = 100 kHz (scl) ,⼀个周期 1000ns4//I2C在sck下降沿更新数据,上升沿读取(采样)数据5///////////////////////////////////////////////////6module demo_I2C #(parameter F100K = 9'd200)(clk,rstn,start_sig,word_addr,wr_data,rd_data,done_sig,scl,sda,sq_i);78input clk ;9input rstn ;1011input [1:0] start_sig ; //12input [7:0] word_addr ; //word address13input [7:0] wr_data ; //Data14output [7:0] rd_data ; //Data from EEPROM15output done_sig ;1617output scl ; //sda和scl其实是⽤来作为仿真信号添加在这⾥的,寄存器信号都⽤rscl和rsda表⽰了,最后⽤assign将rscl和rsda赋值给sda和scl,连到模块外部仿真⽤ 18inout sda ; //sda表⽰当前sda的in或out的值1920output [4:0] sq_i ;21/************************************22在这⾥,iic_func_module.v 的步骤i已经被引出来了。

读者要知道步骤i在⽆论是在设计上还是仿真上都有许多的好处。

23步骤i在仿真中可以充当“调试跟踪”的作⽤,因为只要模块的那个部分出问题,步骤i就会指向它。

I2C代码

I2C代码
byte *g_pong_space=g_incoming_storage; // the data pointer to be processed
size_t g_ping_cnt=0, g_pong_cnt=0, g_ptr=0, g_tic_cnt=TIMEOUT, g_tr_session_flag=0; // the number of data & its index pointer to buffer
bool g_use_fifo=false; // true: fifo, false: normal
const byte *g_ping_space; // the commands pointer to be processed
// I use piccolo as master, ezdsp as slave with the same code ("xxxxx" marked to altered).
// FIFO doesn't work because spec says nothing
// It's funny, to use gpios is far more simpler than use this module. Why i suffer this.
};
byte g_incoming_storage[RX_MAX_LEN]; // to store received data
bool g_is_master=false; // true: master, false: slave
bool g_is_slave_be_tx=false; // it is a slave transmitter only if this variable is true

I2C协议说明及verilog实现读写I2C器件

I2C协议说明及verilog实现读写I2C器件

1.2 I2C 总线的数据传送
1.2.1 起始和终止信号
如图 1-3 所示,SCL 线为高电平期间,SDA 线由高电平向低电平的变化表示起始信号; SCL 线为高电平期间,SDA 线由低电平向高电平的变化表示终止信号。
产品用户手册
三英卓越科技发展有限公司 1
三英卓越科技发展有限公司
K2FPGA
实验教程
2.2 特性
z 低工作电流:典型值为 0.25μA(VDD=3.0V,Tamb=25℃时)。 z 世纪标志。
1.2.3 数据传送格式...................................................................................................2
1.2.4 I2C 总线寻址 ....................................................................................................4

图 1-6 方式 1
哈 注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。A 表示应答,
A 非表示非应答(高电平)。S 表示起始信号,P 表示终止信号。
b) 主机在第一个字节后,立即从从机读数据,如图 1-7 所示。
图 1-7 方式 2
c) 在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次, 但两次读/写方向位正好反相,如图 1-8 所示。
卓 3. 代码示例...................................................................................................................7

i2cc语言编程实例

i2cc语言编程实例

I2C语言编程实例I2C是一种用于短距离通信的串行通信协议。

在嵌入式系统中,I2C总线被广泛使用于芯片之间的通信。

本示例将展示如何使用I2C 总线进行通信。

1. 初始化I2C总线在开始使用I2C总线之前,必须先初始化它。

初始化步骤包括设置时钟频率、启用I2C中断等。

下面是一个初始化I2C总线的示例代码:```c// 初始化I2C总线void init_i2c(void) {// 设置I2C时钟频率为100kHzI2C_SetClockRate(100000);// 启用I2C中断I2C_EnableInterrupts(I2C1, I2C_IT_ERR | I2C_IT_TCR | I2C_IT_TC);// 初始化I2C1I2C_Init(I2C1, I2C1_PSC_16, I2C1_DRR_OPEN, I2C1_DUTY_ONE_SHOT, I2C1_滤波_ENABLED, I2C1_低电平触发_DISABLED, 384);}```2. 设置从设备地址和读写位在通信过程中,从设备地址和读写位是必不可少的。

从设备地址用于指定从设备的位置,而读写位则用于指示数据传输的方向。

下面是一个设置从设备地址和读写位的示例代码:```c// 设置从设备地址和读写位void set_slave_address(uint8_t address, uint8_t read_write) { // 设置从设备地址I2C_WriteData(I2C1, address << 1 | read_write);}```3. 发送数据发送数据的过程包括设置从设备地址和读写位、发送起始信号、发送数据、发送停止信号等步骤。

下面是一个发送数据的示例代码:```c// 发送数据void send_data(uint8_t data) {// 设置从设备地址和读写位set_slave_address(0x50, I2C_READ);// 发送起始信号I2C_GenerateSTART(I2C1, ENABLE);// 等待起始信号发送完成while (!I2C_GetFlagStatus(I2C1, I2C1_FLAG_SB)) {}// 发送从设备地址和读写位I2C_SendData(I2C1, data);// 等待数据发送完成while (!I2C_GetFlagStatus(I2C1, I2C1_FLAG_TXIS)) {}// 清除发送数据标志位I2C_ClearFlag(I2C1, I2C1_FLAG_TXIS);// 发送停止信号I2C_GenerateSTOP(I2C1, ENABLE);}```4. 接收数据接收数据的过程包括设置从设备地址和读写位、发送起始信号、接收数据、发送停止信号等步骤。

I2C协议—24C08读写操作源程序

I2C协议—24C08读写操作源程序

I2C协议—24C08读写操作源程序以下是一个基于Arduino的24C08 I2C协议读写操作的源程序示例:#include <Wire.h>#define EEPROM_ADDRESS 0x50 // 24C08的I2C地址#define EEPROM_SIZE 1024 // EEPROM 的总容量为1KBvoid setuWire.begin(; // 初始化 I2C 总线Serial.begin(9600); // 初始化串口通信void loo//写入数据到EEPROM的地址0byte dataToWrite = 100;writeByte(0, dataToWrite);//从EEPROM的地址0读取数据byte dataRead = readByte(0);Serial.print("Data read from EEPROM: ");Serial.println(dataRead);delay(1000);void writeByte(int address, byte data)//将地址分成高8位和低8位byte highAddress = address >> 8;byte lowAddress = address & 0xFF;Wire.beginTransmission(EEPROM_ADDRESS); // 开始 I2C 传输//写入内存地址Wire.write(highAddress);Wire.write(lowAddress);//写入数据Wire.write(data);Wire.endTransmission(; // 结束 I2C 传输delay(5); //等待写入完成byte readByte(int address)//将地址分成高8位和低8位byte highAddress = address >> 8;byte lowAddress = address & 0xFF;Wire.beginTransmission(EEPROM_ADDRESS); // 开始 I2C 传输//写入内存地址Wire.write(highAddress);Wire.write(lowAddress);Wire.endTransmission(false); // 结束 I2C 传输,但保持连接Wire.requestFrom(EEPROM_ADDRESS, 1); // 从EEPROM读取1个字节byte dataRead;if (Wire.available()dataRead = Wire.read(;}return dataRead;在该示例中,我们使用了Arduino的Wire库来与24C08 EEPROM芯片进行I2C通信。

iic协议格式

iic协议格式

iic协议格式摘要:IIC协议格式简介1.IIC协议概述2.IIC协议的基本格式3.IIC协议的数据传输过程4.IIC协议的优点和应用领域正文:IIC协议格式简介IIC(Inter-Integrated Circuit),又称为I2C(Inter IC),是一种串行双向通信总线,它是由Philips公司于1980年代研发的。

IIC协议主要用于在微处理器和外围设备之间进行低速通信,例如存储器、LCD驱动器、传感器等。

它具有简单、成本低、扩展性强等优点,因此在嵌入式系统和电子设备中得到了广泛应用。

IIC协议的基本格式IIC协议的基本格式包括:起始信号、数据传输、应答信号、停止信号。

1.起始信号:SDA线上的数据从高电平到低电平变化,表示数据传输的开始。

2.数据传输:在SDA线上传输数据,数据是8位的,可以传输一个字节或多个字节。

3.应答信号:在数据传输过程中,每个字节的数据发送后,接收方会发送一个应答信号。

应答信号是SDA线上的数据从低电平到高电平变化。

4.停止信号:SDA线上的数据从低电平到高电平变化,表示数据传输的结束。

IIC协议的数据传输过程IIC协议的数据传输过程分为三个阶段:写数据、读数据和应答。

1.写数据:主设备将数据写入到从设备。

首先,主设备发送起始信号,然后发送数据,接着发送停止信号。

从设备收到数据后,会发送应答信号。

2.读数据:主设备从从设备读取数据。

首先,主设备发送起始信号,然后发送从设备的地址和读数据命令,接着发送停止信号。

从设备收到命令后,会发送应答信号,然后发送数据。

主设备收到数据后,会发送应答信号,最后发送停止信号。

3.应答:在数据传输过程中,每个字节的数据发送后,接收方会发送一个应答信号。

应答信号是SDA线上的数据从低电平到高电平变化。

IIC协议的优点和应用领域IIC协议具有以下优点:1.只需要两根信号线即可实现通信。

2.设备地址唯一,便于识别。

3.支持多主设备,扩展性强。

单片机I2C通讯代码详解

单片机I2C通讯代码详解

单片机I2C通讯代码详解单片机I2C通讯代码详解I2C协议标准代码1. 起始信号&停止信号起始信号:当 SCL 线是高电平时 SDA 线从高电平向低电平切换。

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

2. 起始信号代码void I2cstart() //起始信号{SDA=1;Delay8us();SCL=1;Delay8us();SDA=0;Delay8us();SCL=0;Delay8us();}3. 停止信号代码void I2cstop() //停止信号{SDA=0;Delay8us();SCL=1;Delay8us();SDA=1;Delay8us();}4.发送一个字节unsigned char I2cSendByte(unsigned char dat) //CPU向设备发送一个字节{unsigned char a=0,b=0;for(a=0;a<8;a++){SDA=dat>>7;dat=dat<<1;Delay8us();SCL=1;Delay8us();SCL=0;Delay8us();}SDA=1;Delay8us();SCL=1;while(SDA) //等待设备应答{b++;if(b>200){SCL=0;Delay8us();return 0; //设备无应答,返回0,并跳出此程序}}SCL=0;Delay8us();return 1; //设备有应答,返回1,并跳出此程序}5.读取一个字节unsigned char I2cReadByte() //CPU向设备读取一个字节{unsigned char a=0,dat=0;SDA=1;Delay8us();for(a=0;a<8;a++){SCL=1;Delay8us();dat<<=1;dat|=SDA;Delay8us();SCL=0;Delay8us();}return dat; //返回dat,并跳出此程序}6. 向24C02地址addr,写数据datvoid At24c02Write(unsigned char addr,unsigned char dat) //向24C02地址addr,写数据dat{I2cstart(); //启动I2cSendByte(0xa0); //发送24C02设备地址I2cSendByte(addr); //发送24C02寄存器地址I2cSendByte(dat); //发送数据I2cstop(); //停止}7. 读取24C02寄存器addr中的数据unsigned char At24c02Read(unsigned char addr) //读取24C02寄存器addr中的数据{unsigned char num;I2cstart(); //开始I2cSendByte(0xa0); //发送24C02设备地址-写I2cSendByte(addr); //发送24C02寄存器地址I2cstart(); //改变传输方式,重新开始I2cSendByte(0xa1); //发送24C02设备地址-读num=I2cReadByte(); //接收数据并保存至numI2cstop(); //停止return num; //返回读取值num}8.I2C写数据八个步骤第一步,发送一个起始信号。

I2C详细介绍及编程

I2C详细介绍及编程

I2C详细介绍及编程I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器、传感器、存储器等设备,以实现数据通信。

本文将详细介绍I2C的原理、特点以及编程。

一、I2C的原理和特点I2C协议由飞利浦(Philips)公司于1982年开发,旨在简化数字电路上周边设备的通信。

I2C使用两条线(SCL和SDA)进行数据传输,其中SCL是时钟线,SDA是数据线。

这种双线式的通信使得I2C可以同时进行数据传输和电源供给,极大地简化了设备之间的连接。

在I2C通信中,主设备(通常是微控制器)发起通信,而从设备被动应答。

主设备通过在SCL线上产生时钟信号来控制通信节奏,并通过SDA 线实现数据传输。

数据的传输可以是单向的(主设备向从设备发送数据)或双向的(主设备与从设备之间的双向数据传输)。

I2C协议中的从设备通过一个唯一的地址来识别和寻址。

主设备可以选择与一个或多个从设备进行通信,只需发送相应的地址即可。

在开始通信前,主设备会发送一个开始信号,然后跟着从设备地址和读写位,然后才是数据或命令。

从设备在收到自己地址后会发出应答信号,主设备接收到应答信号后才会继续发送数据。

通信结束后,主设备会发送停止信号。

I2C的特点包括:1.双向通信:主设备和从设备之间可以进行双向的数据传输,减少通信线的需求和复杂度。

2.主-从结构:I2C通信中有一个主设备控制通信的发起和终止,而从设备被动应答。

3.多从结构:主设备可以与多个从设备进行通信,只需要发送不同的地址。

4.低速传输:I2C通信的时钟频率相对较低,一般在100kHz或400kHz。

二、I2C的编程实现在进行I2C编程之前,需要确保硬件上有I2C接口。

常见的I2C接口引脚包括SCL(时钟线)和SDA(数据线),同时需要进行相应的电源连接。

I2C编程的具体实现会有所差异,根据不同的硬件平台和编程语言而有所不同。

以下是一个基于Arduino平台的简单示例:```cpp#include <Wire.h>#define DEVICE_ADDRESS 0x50void setuWire.begin(;Serial.begin(9600);void loo//发送命令Wire.beginTransmission(DEVICE_ADDRESS);Wire.write(0x00); // 使用写入地址0x00Wire.write(0x01); // 写入数据0x01Wire.endTransmission(;delay(100);//读取数据Wire.requestFrom(DEVICE_ADDRESS, 1);if (Wire.available()int data = Wire.read(;Serial.print("Received: ");Serial.println(data);}delay(1000);```上述示例代码中,我们使用Wire库来实现I2C通信。

I2C(代码)

I2C(代码)

I2C(代码)/********************************************************************//* DEMO1307.c *//* program example for DS1307, DS1337/38/39/40 *//********************************************************************/#include /* Prototypes for I/O functions */#include /* Register declarations for DS5000 *//***************************** Defines *****************************/#define ACK 0#define NACK 1#define ADDRTC 0xd0 /* I2C slave address */#define DS1307 /* compile directive, modify as required *//************************* bit definitions *************************/sbit scl = P0^0; /* I2C pin definitions */sbit sda = P0^1;sbit sqw = P3^2; /* pin function depends upon device *//* General Notes: Define one device to compile options for that device. *//* Will not compile correctly if no device is defined. Not all options *//* for each device are supported. There is no error checking for data *//* entry. Defines may not remove all code that is not relevant to the *//* device. This example was written for an 8051-type micro, the DS2250/ *//* DS5000. The program must be modified to work properly on typical *//* 8051 variants (i.e. assign I2C bus to unused port pins). This *//* program is for example only and is not supported by Dallas Maxim */void I2C_start();void I2C_stop();void I2C_write(unsigned char d);uchar I2C_read(uchar);void readbyte();void writebyte();void initialize();void disp_clk_regs(uchar);void burstramwrite(uchar);void burstramread();void alrm_int();void alrm_read();void tc_setup();/* global variables */uchar sec, min, hr, dy, dt, mn, yr;void I2C_start() /* ----------------------------------------------- */{sda = 1; scl = 1; /* Initiate start condition */sda = 0;}void I2C_stop() /* ----------------------------------------------- */{sda = 0; sda = 0; sda = 0; sda = 0; /* Initiate stop condition */scl = 1; scl = 1; sda = 1;}void I2C_write(uchar d) /* ----------------------------- */{uchar i;scl = 0;for (i = 1; i <= 8; i++){sda = (d >> 7);scl = 1;d = d << 1; /* increase scl high time */scl = 0;}sda = 1; /* Release the sda line */scl = 0;scl = 1;if(sda) printf("Ack bit missing %02X",(unsigned int)d);scl = 0;}uchar I2C_read(uchar b) /* ----------------------------------- */{uchar d, i;sda = 1; /* Let go of sda line */scl = 0;for (i = 1; i <= 8; i++) /* read the msb first */{scl = 1;d = d << 1;d = d | (unsigned char)sda;scl = 0;}sda = b; /* Hold sda low for acknowledge */scl = 0;scl = 1;if(b == NACK) sda = 1; /* sda = 1 if next cycle is reset */scl = 0;sda = 1; /* Release the sda line */return d;}void readbyte() /* -- read one byte of data from the specified address -- */{uchar Add;printf("ADDRESS: "); /* Get Address */scanf("%bx", &Add);I2C_start();I2C_write(ADDRTC);I2C_write(Add);I2C_start();I2C_write(ADDRTC | 1);printf("%2bx", I2C_read(NACK) );I2C_stop();}void writebyte() /* -- write one byte of data to the specified address -- */ {uchar Add;uchar Data;printf("Address: "); /* Get Address */scanf("%bx", &Add);printf("DATA: ");scanf("%bx", &Data); /* and data */I2C_start();I2C_write(ADDRTC);I2C_write(Add);I2C_write(Data);I2C_stop();}void initialize() /* -- initialize the time and date using entries from stdin -- */ /* Note: NO error checking is done on the user entries! */{uchar yr, mn, dt, dy, hr, min, sec, day;I2C_start(); /* The following Enables the Oscillator */I2C_write(ADDRTC); /* address the part to write */I2C_write(0x00); /* position the address pointer to 0 */I2C_write(0x00); /* write 0 to the seconds register, clear the CH bit */ I2C_stop();printf("Enter the year (0-99): ");scanf("%bx", &yr);printf("Enter the month (1-12): ");scanf("%bx", &mn);printf("Enter the date (1-31): ");scanf("%bx", &dt);printf("Enter the day (1-7): ");scanf("%bx", &dy);printf("Enter the hour (1-23): ");scanf("%bx", &hr);hr = hr & 0x3f; /* force clock to 24 hour mode */printf("Enter the minute (0-59): ");scanf("%bx", &min);printf("Enter the second (0-59): ");scanf("%bx", &sec);I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x00); /* write register address, 1st clock register */I2C_write(sec);I2C_write(min);I2C_write(hr);I2C_write(dy);I2C_write(dt);I2C_write(mn);I2C_write(yr);#if defined DS1307 || defined DS1338{I2C_write(0x10); /* enable sqwe, 1Hz output */}#elif defined DS1337 || defined DS1339{I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x0e); /* write register address, control register */I2C_write(0x20); /* enable osc, bbsqi */I2C_write(0); /* clear OSF, alarm flags *//* could enable trickle charger here */}#elif defined DS1340{I2C_write(0x10); /* enable sqwe, 1Hz output */I2C_start(); /* address pointer wraps at 7, so point to flag register */I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x09); /* write register address, control register */I2C_write(0); /* clear OSF */}#endifI2C_stop();}void disp_clk_regs(uchar prv_sec) /* ----------------------------------------- */{uchar Sec, Min, Hrs, Dte, Mon, Day, Yr, mil, pm;printf("Yr Mn Dt Dy Hr:Mn:Sc");while(!RI) /* Read & Display Clock Registers */{I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x00); /* write register address, 1st clock register */I2C_start();I2C_write(ADDRTC | 1); /* write slave address + read */Sec = I2C_read(ACK); /* starts w/last address stored in register pointer */ Min = I2C_read(ACK);Hrs = I2C_read(ACK);Day = I2C_read(ACK);Dte = I2C_read(ACK);Mon = I2C_read(ACK);Yr = I2C_read(NACK);I2C_stop();if(Hrs & 0x40)mil = 0;elsemil = 1;if(Sec != prv_sec) /* display every time seconds change */{if(mil){printf("%02bX/%02bX/%02bX %2bX", Yr, Mon, Dte, Day);printf(" %02bX:%02bX:%02bX", Hrs, Min, Sec);}else{if(Hrs & 0x20)pm = 'A';elsepm = 'P';Hrs &= 0x1f; /* strip mode and am/pm bits */printf("%02bx/%02bx/%02bx %02bx", Yr, (Mon & 0x1f), Dte, Day);printf(" %02bx:%02bx:%02bx %cM", Hrs, Min, Sec, pm); }}if(prv_sec == 0xfe) return;prv_sec = Sec;}RI = 0; /* Swallow keypress before exiting */}void burstramwrite(uchar Data) /* -------- fill RAM with data -------- */{uchar j;I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x08); /* write register address, 1st RAM location */for (j = 0; j < 56; j++) /* write until the pointer wraps around */{I2C_write(Data);}I2C_stop();}void burstramread() /* ----------------------------------------- */{uchar j;I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(8); /* write register address, 1st RAM location -1*/I2C_start();I2C_write(ADDRTC | 1); /* write slave address + read */for (j = 0; j < 56; j++){if(!(j % 16)) printf("%02bX ", j);printf("%02bX ", I2C_read(ACK) );}I2C_read(NACK);I2C_stop();}void alrm_int() /* ----- initialize alarm registers ------ */{uchar M, Sec, Min, Hr, DyDt;printf("1-Alarm each second2-Alarm match=sec3-Alarm match=sec+min");printf("4-Alarm match=sec+min+hr5-Alarm match=sec+min+hr+date");printf("6-Alarm match=sec+min+hr+dayEnter selection: ");M = _getkey(); /* Note-No error checking is done on entries! */switch(M){case '1': M = 0xf; break;case '2': M = 0xe; break;case '3': M = 0xc; break;case '4': M = 8; break;case '5': M = 0; break;case '6': M = 0x40; break;}if(M & 0x40){printf("Enter the day (1-7): ");scanf("%bx", &DyDt);}else{printf("Enter the date (1-31): ");scanf("%bx", &DyDt);}printf("Enter the hour (1-23): ");scanf("%bx", &Hr);printf("Enter the minute (0-59): ");scanf("%bx", &Min);printf("Enter the second (0-59): ");scanf("%bx", &Sec);if( (M & 1) ) Sec |= 0x80;if( ((M >> 1) & 1) ) Min |= 0x80;if( ((M >> 2) & 1) ) Hr |= 0x80;if( ((M >> 3) & 1) ) DyDt |= 0x80;if(M & 0x40) DyDt |= 0x40;I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(7); /* write register address */I2C_write(Sec);I2C_write(Min);I2C_write(Hr);I2C_write(DyDt);I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(0x0e); /* write register address */I2C_write(5); /* enable interrupts, alarm 1 */I2C_stop();}void alrm_read() /* ----- read alarm registers ------ */{uchar Sec, Min, Hr, DyDt;I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(7); /* write register address */I2C_start();I2C_write(ADDRTC | 1); /* write slave address + read */Sec = I2C_read(ACK);Min = I2C_read(ACK);Hr = I2C_read(ACK);DyDt = I2C_read(NACK);printf("Alarm 1: %02bx %02bx %02bx %02bx", Sec, Min, Hr, DyDt);}void tc_setup() /* ---- trickle charger set up routine ---- */{uchar M, val;#if defined DS1339#define TC 0x10 /* address for DS1339 trickle charge register */ #else#define TC 0x08 /* address for DS1340 trickle charge register */ #endifprintf("Enable Trickle Charger (Y/N)? ");M = _getkey();if(M == 'Y' || M == 'y'){printf("1-250 ohm res2-2K res=sec3-4K res");M = _getkey(); /* Note-No error checking is done on entries! */switch(M){case '1': val = 1; break;case '2': val = 2; break;case '3': val = 3; break;}printf("1-no diode2-1 diode");M = _getkey(); /* Note-No error checking is done on entries! */switch(M){case '1': val += 4; break;case '2': val += 8; break;}I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(TC); /* write register address */I2C_write(val | 0xa0); /* enable trickle charger per user input */ I2C_stop();}else{I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(TC); /* write register address */I2C_write(0); /* disable trickle charger */I2C_stop();}I2C_start();I2C_write(ADDRTC); /* write slave address + write */I2C_write(TC); /* write register address */I2C_start();I2C_write(ADDRTC | 1); /* write slave address + read */printf("Trickle Charger: %02bx", I2C_read(NACK) );}main (void) /* ----------------------------------------------------- */{uchar M, M1;sqw = 1; /* set up for read, weak pull-up */while (1){#if defined DS1307printf("DEMO1307 build %s", __DATE__);#elif defined DS1337printf("DEMO1337 build %s", __DATE__);#elif defined DS1338printf("DEMO1338 build %s", __DATE__);#elif defined DS1339printf("DEMO1339 build %s", __DATE__);#elif defined DS1340printf("DEMO1340 build %s", __DATE__);#endifprintf("CI Init RTC CR Read Clock");printf("BR Byte Read BW Write Byte");#if defined DS1337 || defined DS1339 /* only print if part has alarms */ printf("AI Alarm 1 Int AR Alarm Read");#endif#if defined DS1340 || defined DS1339 /* parts that have trickle charger */ printf("Tc Trickle charger");#endif#if defined DS1307 || defined DS1338 /* only print if part has RAM */printf("RR RAM Read RW RAM Write");#endifprintf("Enter Menu Selection:");M = _getkey();switch(M){case 'A':case 'a':printf("Init or Read: ");M1 = _getkey();switch(M1){case 'I':case 'i': alrm_int(); break;case 'R':case 'r': alrm_read(); break;}break;case 'B':case 'b':printf("Read or Write: ");M1 = _getkey();switch(M1){case 'R':case 'r': readbyte(); break;case 'W':case 'w': writebyte(); break;}break;case 'C':case 'c':printf("\rEnter Clock Routine to run:C");M1 = _getkey();switch(M1){case 'I':case 'i': initialize(); break;case 'R':case 'r': disp_clk_regs(0x99); break; }break;case 'R':case 'r':printf("\rEnter Ram Routine to run:R");M1 = _getkey();switch(M1){case 'R':case 'r': burstramread(); break;case 'W':case 'w': printf("Enter the data to write: ");scanf("%bx", &M1);burstramwrite(M1); break; }break;case 'T':case 't': tc_setup(); break;}}}/4726442.html。

  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);}。

相关文档
最新文档