简单的I2C协议理解 i2c程序(调试通过)
- 格式:docx
- 大小:16.53 KB
- 文档页数:8
简单的I2C协议理解I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
是微电子通信控制领域广泛采用的一种总线标准。
它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。
I2C 总线支持任何IC 生产过程(CMOS、双极性)。
通过串行数据(SDA)线和串行时钟(SCL)线在连接到总线的器件间传递信息。
每个器件都有一个唯一的地址识别(无论是微控制器——MCU、LCD 驱动器、存储器或键盘接口),而且都可以作为一个发送器或接收器(由器件的功能决定)。
LCD 驱动器只能作为接收器,而存储器则既可以接收又可以发送数据。
除了发送器和接收器外,器件在执行数据传输时也可以被看作是主机或从机。
主机是初始化总线的数据传输并产生允许传输的时钟信号的器件。
此时,任何被寻址的器件都被认为是从机。
一. 技术性能:工作速率有100K和400K两种;支持多机通讯;支持多主控模块,但同一时刻只允许有一个主控;由数据线SDA和时钟SCL构成的串行总线;每个电路和模块都有唯一的地址;每个器件可以使用独立电源i2C接口的SCL和SDA均为漏极开路,需要加上拉电阻,不同器件的供电电压可以不同,如3.3V和5V,但是低电压供电的芯片相应引脚需要5V耐受。
漏极开路输出和集电极开路一样,顾名思义,开漏电路就是指从MOSFET的漏极输出的电路。
典型的用法是在漏极外部的电路添加上拉电阻到电源如图所示。
完整的开漏电路应由开漏器件和开漏上拉电阻组成。
这里的上拉电阻R的阻值决定了逻辑电平转换的上升/下降沿的速度。
阻值越大,速度越低,功耗越小。
因此在选择上拉电阻时要兼顾功耗和速度。
标准的开漏脚一般只有输出的能力。
添加其它的判断电路,才能具备双向输入、输出的能力。
很多单片机等器件的I/O就是漏极开路形式,或者可以配置成漏极开路输出形式,如51单片机的P0口就为漏极开路输出。
i2c协议详解
I2C(Inter-Integrated Circuit)协议是一种双向串行总线,也称作IIC、TWI(Two-Wire Interface)或SMBus(System Management Bus),由Philips公司于1982年开发,用来连接多个微处理器和其它通信芯片。
I2C协议有两根线,分别是SCL(时钟线)和SDA(数据线),使用双线的好处就是只要两根线就可以完成数据传输,而不需要增加额外的线路,能够大大减少系统所需要的线路,减少系统的复杂度和成本。
I2C协议需要一个主控制器来控制整个系统,主控制器通过SCL线来发送时钟,并通过SDA线来发送和接收数据,从控制器则只负责接收数据。
I2C协议有7个基本信号,START、STOP、ACK、NACK、READ、WRITE和REPEAT START,START在传输数据前发出,STOP则在传输结束后发出,ACK和NACK则用来表示接收方是否正确接收到数据,READ和WRITE则用来指示当前传输的数据是读数据还是写数据,REPEAT START则用来重新开始新一轮的传输。
I2C协议的最大优点是简单、易用,而且可以支持多个从控制器,不过它的缺点也是显而易见的,它的传输速度相对较慢,而且它的传输距离也有限,约在50cm左右。
i2c 调试总结I2C(Inter-Integrated Circuit)是一种串行通信总线,广泛应用于各种电子设备中,用于连接微控制器、传感器、存储器等器件。
I2C 调试是电子设备开发过程中必不可少的一环,以下是对I2C调试的一些总结:1. 理解I2C通信原理:- I2C总线由两根线组成:SDA(数据线)和SCL(时钟线)。
-通信过程中,主设备控制SCL,而SDA的数据传输由主从设备共同控制。
-常用的I2C速率有标准模式(100kHz)、快速模式(400kHz)、高速模式(3.4MHz)和超高速模式(5MHz以上)。
2. 选择正确的I2C地址:-每个I2C设备都有一个或多个唯一的地址,确保在编程时使用了正确的地址。
-有时设备可能允许通过配置引脚来改变其I2C地址。
3. 检查硬件连接:-确保SDA和SCL线正确连接,没有短路或断路。
-确保上拉电阻(如果有的话)正确连接,并且阻值适当。
-如果使用外部I2C总线扩展器或集线器,请检查其连接和配置。
4. 初始化配置:-根据所使用的硬件和软件平台,正确配置I2C接口,包括设置正确的速率、选择从设备地址等。
-在嵌入式系统中,可能需要编写或修改初始化代码来配置I2C控制器。
5. 软件调试:-使用调试工具,如串口输出、逻辑分析仪或示波器等,来监控SDA和SCL的波形。
-检查I2C通信的起始条件、地址发送、数据读写、停止条件等是否符合I2C协议规范。
6. 电源和接地:-确保所有设备有稳定的电源供应,并且接地良好。
-电源不稳或接地不良可能导致通信失败或设备损坏。
7. 固件和驱动程序:-确保使用的固件或驱动程序与硬件兼容,并且没有已知的bug。
-如果可能,尝试使用官方提供的示例代码或库文件。
8. 检查从设备:-如果使用多个从设备,请单独测试每个设备,以排除设备故障的可能性。
-检查从设备的电源、接地和初始化设置。
9. 外部干扰:-某些情况下,外部电磁干扰可能影响I2C通信。
linux系统i2c协议详解I2C总线概述I2C(两线接口)是一种串行通信协议,用于连接嵌入式系统中的集成电路(IC)。
它以其低成本、低功耗和高可靠性著称。
I2C总线需要两条双向信号线:串行数据线(SDA)和串行时钟线(SCL)。
这些信号线由一个主设备控制,可以与多个从设备通信。
I2C通信I2C通信由以下步骤组成:起始条件:主设备将SDA线下拉至低电平,同时保持SCL线为高电平。
设备地址:主设备发送7位或10位从设备地址,后跟一个读/写位。
数据传输:主设备和从设备交换数据。
停止条件:主设备将SDA线拉至高电平,同时保持SCL线为高电平。
主设备和从设备I2C总线上的设备分为两种:主设备和从设备。
主设备:发起通信并控制总线。
通常是主微控制器或处理器。
从设备:响应主设备请求并提供或接收数据。
可以是传感器、执行器或其他外围设备。
I2C寻址从设备通过唯一的7位或10位地址进行寻址。
地址的最高位表示是否可读/写,0表示写,1表示读。
I2C模式I2C协议支持以下模式:主写从读:主设备向从设备写入数据,然后从从设备读取数据。
主读从写:主设备从从设备读取数据,然后向从设备写入数据。
从读从写:两个从设备在主设备的监督下进行通信。
I2C传输速率I2C传输速率通常在10kbps到400kbps之间。
速率由主设备设置。
I2C错误检测I2C协议包含几个错误检测机制,例如校验和和超时。
这些机制有助于确保数据的可靠传输。
I2C应用I2C总线用于各种应用,包括:传感器和执行器接口EEPROM和闪存编程LED和LCD控制模拟-数字转换器(ADC)和数字-模拟转换器(DAC)接口电源管理时钟同步I2C优点I2C协议的优点包括:低成本:无需额外的硬件接口低功耗:仅使用两根信号线高可靠性:错误检测机制确保数据完整性容易使用:简单的协议易于实施广泛采用:支持广泛的设备和库I2C缺点I2C协议的缺点包括:数据速率低:与其他串行接口相比,数据速率较低主机限制:总线上只能有一个主设备总线无仲裁:在总线冲突的情况下,没有内置的仲裁机制有限的寻址范围:仅支持有限数量的设备地址I2C技术演进I2C协议正在不断发展,以满足新应用的需求。
I2C通信原理及程序详细讲解I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器、传感器和其他外部设备。
I2C通信协议由荷兰飞利浦公司于1982年开发,它使用两根信号线(SDA和SCL)进行数据传输。
I2C通信协议采用主从结构,一个主设备(如微控制器)可以连接多个从设备(如传感器)。
主从设备之间通过SDA和SCL线进行数据传输。
SDA线是双向数据线,用于传输数据,SCL线是时钟线,用于同步数据传输。
I2C通信协议中,设备的地址是一个重要概念。
每个设备都有一个唯一的地址,通过该地址可以选择和通信特定的设备。
地址由7个位组成,其中最高位是固定的,并取决于设备是主设备还是从设备。
如果最高位为0,则表示该设备是主设备;如果最高位为1,则表示该设备是从设备。
通过以下步骤,让我们详细了解如何在I2C总线上进行通信。
1.初始化I2C总线:在程序开始时,需要初始化I2C总线。
这通常包括初始化SDA和SCL引脚,设置时钟频率等。
具体的初始化步骤取决于使用的硬件和软件环境。
2.发送开始信号:开始信号表示I2C数据传输的开始。
它由主设备发送,并且SDA线从高电平转为低电平时发出。
发送开始信号后,SDA线上的数据将被解释为地址数据。
3.发送设备地址:主设备发送一个包含设备地址和读/写位(R/W)的数据字节。
设备地址是唯一的,并且由主设备选择。
读/写位指示从设备是要读取数据还是写入数据。
4.等待从设备响应:主设备发送设备地址后,会等待从设备的响应。
从设备将响应一个应答位(ACK)来确认地址接收成功。
如果收到ACK位,则继续进行下一步,否则可能是设备未连接或通信错误。
5.发送数据:主设备发送数据给从设备。
数据可以是命令、配置或实际数据,具体取决于应用场景。
发送数据的方式是将每个数据字节传输到SDA线上,并在每个数据字节后发送一个ACK位。
6.接收数据:从设备将数据发送给主设备。
数据可以是传感器读数、存储器数据等。
i2c通信的详细讲解I2C(Inter-IntegratedCircuit,又名“两线制”)是一种开源的连接性协议,只需要两根线,一条用于连接数据(SDA),另一条用于传输时钟信号(SCL),另外无须任何外部设备,就能构建一个灵活的和可扩展的系统。
I2C的主要特性在于,他可以让多个芯片之间运行在同一总线上,开销较少、高效,是用来连接主机和外围设备,特别是嵌入式系统的一个常用的接口技术。
I2C的原理是什么?I2C工作的原理是,它仅有两个线,一条传输时钟信号(SCL),一条传输数据(SDA),当设备要发出数据时,它发出一个信号,信号告诉另外一个设备,双方之间有了一个连接,此时设备可以给另一设备传输信息,如果不需要进行跨流程的传输,可以省略时钟信号和失能信号,两设备之间的数据传输是相互独立的,每当一设备发送完成后,还需要发出一个复位信号,来进行重新启动。
I2C协议规定,有7种信号类型:START和STOP,ACK和NACK,SDA和SCL,失能信号(DISABLE),每种信号都有自己的特定用途。
当一个设备要发出或接收数据时,一定先发出一个START信号,当发送完成后要发出一个STOP信号,ACK和NACK用于检测接受成功与否,SDA和SCL分别用来传输数据和传输时钟信号,失能信号用于切断设备之间的通信。
I2C协议规定,主设备可以接收从设备的信息,而从设备则只能给主设备发送信息,在通信的过程中,主设备可以控制传输的方向,并且在发送完一条信息后,要检查是否收到另一个设备的回复,当另一个设备收到主设备发送的信息时,必须迅速进行回复,或者发出一个ACK或者NACK,来接受或拒绝信息。
总的来说,I2C通信协议非常简单而有效,只需要两根线,就可以在多个设备之间进行高速通信,并且可以进行大范围的扩展,使用I2C可以实现两个设备之间的双向通信,从而实现两个设备的同步通信。
此外,由于I2C协议数据传输的灵活性和可靠性,也是嵌入式系统开发的主要技术之一。
I2C 通信:起始条件:SCL为高电平,SDA电平从高变低,这一变化即完成了通信的起始条件。
起始条件和数据通信间,通常会有延时要求具体的指标见设备说明。
数据传输阶段:一字节需要9个时钟周期;且每一位需要一个时钟周期;如上图所示,ADDRESS为目标设备的地址,R/ w为通信的的方向位;"1"时表示读,即后续的数据由目标设备发出,主机进行接收;"0"时表示写,即后续的数据由主机发出目标设备进行接收。
当ACK信号为"0"时,说明接收成功;为"1"时,说明接收失败。
每个字节的传输都是由高位(MSB)到低位(LSB)依次进行传输。
在数据通信过程中,总是由数据接收方发出ACK信号。
终止阶段:当主机完成数据通信,并终止本次传输时会发出终止信号。
当SCL 是高电平时,SDA电平由低变高,这个变化意味着传输终止。
注:每个时钟周期的高电平期间,SDA的数据状态达到稳定。
下面给出了模拟I2C总线进行读写的伪代码,用以说明如何使用GPIO 实现I2C通信:int i2c_start() /* I2C起始条件*/{//初始化GPIO口set_gpio_direction(SDA, OUTP); //设置SDA方向为输出set_gpio_direction (SCL, OUTP); //设置SCL方向为输出set_gpio_value(SDA, 1); //设置SDA为高电平set_gpio_value(SCL, 1); //设置SCL为高电平delay(); //延时//起始条件set_gpio_value(SDA, 0); //SCL为高电平时,SDA由高变低delay(); //适当延时}void i2c_stop() /* I2C终止条件*/{set_gpio_value(SCL, 1);set_gpio_direction(SDA, OUTP);set_gpio_value(SDA, 0);delay();set_gpio_value(SDA, 1); //SCL高电平时,SDA由低变高}/* I2C读取ACK信号(写数据时使用)返回值:0表示ACK信号有效;非0表示ACK信号无效*/unsigned char i2c_read_ack(){unsigned char r;set_gpio_direction(SDA, INP); //设置SDA方向为输入set_gpio_value(SCL,0); // SCL变低r = get_gpio_value(SDA); //读取ACK信号delay();set_gpio_value(SCL,1); // SCL变高delay();return r;}/* I2C发出ACK信号(读数据时使用) */int i2c_send_ack(){set_gpio_direction(SDA, OUTP); //设置SDA方向为输出set_gpio_value(SCL,0); // SCL变低set_gpio_value(SDA, 0); //发出ACK信号delay();set_gpio_value(SCL,1); // SCL变高delay();}void i2c_write_byte(unsigned char b) /* I2C字节写*/{int i;set_gpio_direction(SDA, OUTP); //设置SDA方向为输出for (i=7; i>=0; i--){set_gpio_value(SCL, 0); // SCL变低delay();set_gpio_value(SDA, b & (1<<i)); //从高位到低位依次发送数据set_gpio_value(SCL, 1); // SCL变高delay();}i2c_read_ack(); //检查目标设备的ACK信号}/* I2C字节读*/unsigned char i2c_read_byte(){int i;unsigned char r = 0;set_gpio_direction(SDA, INP); //设置SDA方向为输入for (i=7; i>=0; i--){set_gpio_value(SCL, 0); // SCL变低delay();r = (r <<1) | get_gpio_value(SDA); //高位到低位依次数据读取set_gpio_value(SCL, 1); // SCL变高delay();}i2c_send_ack(); //向目标设备发送ACK信号return r;}/* I2C读操作addr:目标设备地址buf:读缓冲区len:读入字节的长度*/void i2c_read(unsigned char addr, unsigned char* buf, int len){int i;unsigned char t;i2c_start(); //起始条件,开始数据通信//发送地址和数据读写方向t = (addr << 1) | 1; //低位为1,表示读数据i2c_write_byte(t);//读入数据for (i=0; i<len; i++)buf[i] = i2c_read_byte();i2c_stop(); //终止条件,结束数据通信}/* I2C写操作addr:目标设备地址buf:写缓冲区len:写入字节的长度*/void i2c_write (unsigned char addr, unsigned char* buf, int len){int i;unsigned char t;i2c_start(); //起始条件,开始数据通信//发送地址和数据读写方向t = (addr << 1) | 0; //低位为0,表示写数据i2c_write_byte(t);//写入数据for (i=0; i<len; i++)i2c_write_byte(buf[i]);i2c_stop(); //终止条件,结束数据通信}。
I2C总线协议及工作原理I2C(Inter-Integrated Circuit)是一种串行通信总线协议,由Philips公司提出,适用于在电路板上连接各种集成电路的短距离通信。
I2C总线协议的工作原理是基于主从结构的,其中一个设备作为主设备,其他设备作为从设备。
主设备负责发起通信操作,而从设备则被动响应主设备的指令。
主设备在总线上发出启动信号,然后发送器件地址。
发起通信的主设备控制总线的速度和时序,并且主设备确定读写的类型。
从设备根据地址进行匹配,并根据主设备请求的读写进行响应。
通信完成后,主设备会发送停止信号释放总线。
在I2C总线上,每个设备都有一个唯一的7位或10位地址。
主设备在传输数据之前,会发送起始信号,这个信号告诉从设备通信即将开始。
随后主设备会发送一个地址字节,包含了要通信的从设备的地址和读写控制位。
如果从设备的地址和发送的地址匹配,从设备会发送一个应答(ACK)信号,表示准备好接收数据。
主设备然后才开始发送或接收数据。
数据在I2C总线上传输是以字节为单位的,并且每个字节之后都会有一个应答信号。
主设备负责设置时钟线的电平来控制数据的传输,而从设备负责读取或发送数据位。
在读取数据时,主设备会发送应答位,如果从设备准备好读取下一个字节,会发送应答信号;反之,如果从设备不准备好,会发送非应答信号。
在I2C总线上,主设备还可以使用多主模式,允许多个主设备操作相同的总线。
当多个主设备在通信总线上发起通信时,总线的冲突可能会发生。
为了解决这个问题,I2C总线使用了仲裁机制。
仲裁机制根据优先级决定那个设备能够继续发送数据,优先级高的设备可以中断优先级低的设备的传输,从而保证通信的顺利进行。
总结起来,I2C总线协议是一种简单、高效的串行通信协议。
它通过两根线实现设备之间的通信,并且支持多主模式。
它的工作原理是基于主从结构,主设备发起通信,从设备被动响应。
通过仲裁机制,解决了多主模式下的冲突问题。
I2C通讯协议介绍I2C(Inter-Integrated Circuit)是一种串行通信协议,用于在集成电路中的各个部件之间进行数据传输。
它最初由Philips(现在的NXP 半导体)在1980年代开发,并于1992年首次发布。
I2C是一种简单而灵活的通信协议,广泛应用于各种嵌入式系统和电子设备中。
I2C协议使用双线(一根串行数据线SDA和一根串行时钟线SCL)进行通信。
它采用主从结构,其中一个设备作为主设备控制总线,其他设备作为从设备进行通信。
主设备是由软件控制的,可以向从设备发送命令并接收数据。
从设备则在主设备的控制下执行命令,并将响应的数据发送回主设备。
I2C协议的通信速率通常在几百KHz到几兆Hz之间,可以根据具体应用的需求选择适当的速度。
通信的起始和停止由主设备发出的特殊序列(起始和停止位)标志着每个数据传输的开始和结束。
数据传输是以字节为单位进行的,每个字节包含8位数据(从高位到低位)。
在每个字节的传输期间,时钟线的状态决定了数据线的有效性。
在I2C协议中,每个设备都有一个唯一的地址,用于在总线上识别该设备。
主设备通过在总线上发送设备地址来选择要与之通信的设备。
设备地址由7位或10位组成,取决于I2C规范的版本。
7位地址模式支持最多128个设备,10位地址模式支持最多1024个设备。
除了地址选择之外,主设备还可以向设备发送命令或数据。
命令和数据是通过字节传输的,在发送字节时,设备可以返回一个确认信号,指示它已成功接收到数据。
主设备可以发送一个字节序列来实现复杂的数据传输,包括读和写操作。
I2C协议还定义了一些标准模式来处理特殊情况。
例如,重复起始条件允许主设备在不释放总线的情况下与多个设备进行连续通信。
仲裁器制度可以处理并发传输时的冲突。
还定义了一些保留地址,用于特殊用途,如广播命令。
I2C协议的灵活性和简单性使其成为各种应用的理想选择。
它广泛应用于嵌入式系统中的各种设备之间的通信,如传感器、存储器、显示器、开关和其他外围设备。
简单的I2C协议理解
一. 技术性能:
工作速率有100K和400K两种;
支持多机通讯;
支持多主控模块,但同一时刻只允许有一个主控;
由数据线SDA和时钟SCL构成的串行总线;
每个电路和模块都有唯一的地址;
每个器件可以使用独立电源
二. 基本工作原理:
以启动信号START来掌管总线,以停止信号STOP来释放总线;
每次通讯以START开始,以STOP结束;
启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R /W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
每个数据字节在传送时都是高位(MSB)在前;
写通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4. 主控收到ACK后开始发送第一个数据字节;
5. 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;
读通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信
号(ACK);
4. 主控收到ACK后释放数据总线,开始接收第一个数据字节;
5. 主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;
四. 总线信号时序分析
1. 总线空闲状态
SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;
2. 启动信号START
时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。
启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;
3. 停止信号STOP
时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。
4. 数据传送
SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。
只有在SCL线为低电平期间,SDA上的电平允许变化。
5. 应答信号ACK
I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。
6. 无应答信号NACK
在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:
a. 一般表示接收器未成功接收数据字节;
b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。
五. 寻址约定
地址的分配方法有两种:
1. 含CPU的智能器件,地址由软件初始化时定义,但不能与其它的器件有冲突;
2. 不含CPU的非智能器件,由厂家在器件内部固化,不可改变。
高7位为地址码,其分为两部分:
1. 高4位属于固定地址不可改变,由厂家固化的统一地址;
2. 低三位为引脚设定地址,可以由外部引脚来设定(并非所有器件都可以设定);
i2c程序(调试通过)
本程序是在周立功网上的程序的基础上修改的,原例里的ACK时序有点问题
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit BELL_OUT=P3^5; sbit SCL="P1"^3;
sbit SDA="P1"^4;
bit ack;
void Start_I2c()
{
SDA="1";
_nop_();
SCL="1";
_nop_();
SDA="0";
_nop_();
SCL="0";
_nop_();
}
void Stop_I2c()
{
SDA="0";
_nop_();
SCL="1";
_nop_();
SDA="1";
_nop_();
}
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) {
SCL="0";
if((c<<BITCNT)&0X80)>
else SDA="0"; SCL="1";
_nop_();
}
//从机应答,可以用应答和非应答信号代替 _nop_();
SCL="0";
_nop_();
SDA="1"; //
_nop_();
_nop_();
if(SDA==1){ack=0;}
else ack="1";
SCL="0";
_nop_();</BITCNT)&0X80)>
}
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc="0";
for(BitCnt=0;BitCnt<8;BitCnt++) {
SCL="1";
_nop_();
retc="retc"<<1;
if(SDA==1) retc="retc"+1;
SCL="0";
}
return(retc);
}
void Ack_I2c()
{
SDA="0";
_nop_();
_nop_();
SCL="1";
_nop_();
SCL="0";
_nop_();
SDA="1";
_nop_();
}
void NoAck_I2c()
{
SDA="1";
_nop_();
SCL="1";
_nop_();
SCL="0";
}
bit ISendByte(uchar sla,uchar c)
{
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(c);
if(ack==0)return(0);
Stop_I2c();
return(1);
}
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
uchar i;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
for(i=0;i
{
SendByte(*s);
if(ack==0)return(0);
s++;
}
Stop_I2c();
//delayMs(1); //
return(1);
}
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
*c=RcvByte();
NoAck_I2c();
Stop_I2c();
return(1);
}
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
Start_I2c(); SendByte(sla); if(ack==0)return(0);
SendByte(suba); if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
while(no!=1)
{
*s=RcvByte();
Ack_I2c();
s++;
no--;
}
*s=RcvByte();
NoAck_I2c(); Stop_I2c(); return(1);
}。