您的当前位置:首页IIC串口

IIC串口

2021-08-17 来源:爱问旅游网
IC总线补充资料 222

附录第 页 一、基于IC总线的扩展是串行扩展。IC总线((Inter-Integrated Circuit,集成电路间)是PHILIP等公司联盟开发的多主控器双向二线制同步串行总线(我们现在只讲单主控器): 2①IC总线由串行时钟线(SCL)和串行数据线(SDA)双向二线组成。基于IIC总线的通信是串行同步通信:即以SCL为同步信号来定位数据信号线上的数据位,开始位和停止位。 2

②在总线上挂接的IC接口器件,有标志本器件类别的器件类型码(内臵4bit)和器件片选地址(引脚设定,P196)。 ③在单主控器的IIC总线中,无论发送还是接收,SCL均由主控方提供,单向,由主控器传送给从器件;而SDA是双向的。

2

④挂接在总线上的集成电路总数仅受总线总电容≤400pF的限制。 ⑤ IC总线协议支持三种工作模式:标准S(100Kbit/s)、快速F(400Kbit/s)、高速Hs(3.4Mbit/s)。

22

二、我们这一讲从以下三个方面来初步认识IC总线协议,并以具有IC接口的EEPROM存储器芯片24CWxx的应用为例来具体理解和认识基于IIC总线的系统扩展。 222⒈ IC接口的电原理结构:①凡具有IC接口的器件,其内部双向口线均为漏极(或集电极)开路输出电路/带缓冲的输入电路。所有器件,包括主控器的输出口线均以“线与方式”挂接在IC总线上,总线上有上拉电阻(5~10kΩ)。双向口线和“线与”方式,便于总线双向数据传输和控制权转移。某器件要在SDA线上输出1,或要放弃对SDA线的控制,均应向SDA线输出1。

22

②在具有IC总线接口的器件内,均有实现IC通信协议的控制逻辑;51单片机基本型89C51没有这种控制逻辑,但可以用编程方式来模拟这种控制逻辑;51系列中的8XC550/552/752

22

等增强性机种内就预构了具备IC控制逻辑的IC通信模块。

22

⒉ 信息结构:①IC串行通信基于“位传输”,即通信传输中的底层单位是“位”。但“位”不独立存在,必须由多个“位”组成一定格式的“基本单位”,并以这个基本单位进行IC通信。所谓“基本单位”与异步串行通信中的“帧”相当(不完全相同),我们就借用“帧”这个概念了。通信中,主从双方有序组织多个“帧”进行“交互式通信”,以完成信息传送。 ②“帧”组成格式:由8bit数据位(高位在前,低位在后)、应答位ACK(或非应答位NACK)构成,根据通信开始或结束的需要,在“帧”的前后拼装开始信号S或停止信号P。见后页的图。 ③数据位是SDA在SCL高电平期间的稳定值。在SCL高电平期间SDA必须稳定;而数据位的更新必须在SCL低电平期间进行,且必须在SCL的上升沿以前提前建立准备好数据位。 ④应答位(Acknowledge)是在发送方发送8位数据位后,在第9个SCL高电平期间,接收方在SDA线上向发送方回应的信号。其值为0则为ACK(应答),其值为1则为NACK(非应答,即否定性应答)。在发送方和接收方的通信中,谁发谁收,关系是明确的,但信息中还夹带有来有往的应答,是交互的,我们更通俗的说“对话式通信”——虽然教科书不这样讲。 ⑤开始信号START是SCL和SDA两线信号的特定组合:即SCL高电平期间的SDA下降沿↓,简称为S。在开始IIC通信的那一“帧”前,需拼装开始信号。 ⑥停止信号STOP也类似:是SCL高电平期间的SDA上跳沿↑,简称为P。在IIC通信结束的那一“帧”后,需拼装发送结束信号。

2

⑦上述的SCL和SDA信号均有时序的要求,见下页IC时序图表。如,SCL=1时的SDA稳定值是数据位,SDA必须在SCL=1前预先建立准备好,在SCL=0后还要保持,等等。

22

⒊ 操控命令结构:在以单片机为单主控方的IC总线上挂接功能不同的各种IC芯片,都是从器件(slave)。单片机作为主控方对这些不同从器件的一切操控,都是通过主控器与从器件进行对话式的IIC通信来实现的:即有序组织多个“帧”构成不同的“对话序列”, 以有来有往的对话,来实现不同目的的读写操作。 “对话序列”一般含多个“帧”,但不管对话序列如何不同,第一个“帧”必须是由主控方发出的含有器件类型码、片选地址码和控制码信息的“控制帧”,这个“控制帧”的构成是:起始信号S、器件类型(4bit)、器件片选地址(3bit)、R/W控制位(1bit,1为读、0为写)、从器件应答位(ACK或NACK)。在这个“控制帧”后,再根据不同读写操作的需要,下跟其它“帧”,比如地址帧、数据帧等构成不同的对话序列。以24WCxx为例,这样的对话序列有A/D/C/D/E/F/G共计7种(见下表),可完成目的不同的读写操作。这个“对话序列”组成各不相同,其实很有规律性。下表中:未加方框的,是主控方发送的信息或“帧”;加方框的,表示从器件方发送的信息或“帧” 。

2

24WCXX是EPROM(见P199表,它的器件类型码是“1010”,器件地址(片选地址A2/A1/A0)和写保护WP(write protect)由24WCXX芯片引脚上的的电平设定。 片内块数 页/每块 页内字节 片选 / 片内块选地址 可挂接器件数 地址构成 24WC32以后的芯片,片内或片内块的容量24WC01 (1Kbit)128Byte 1 16 8 A2 A1 A0 8 片内7位地址 均超过256单元,地址均24WC02 (2Kbit)256Byte 1 32 16 A2 A1 A0 8 片内8位地址 超过8位,因此,在发送24WC04 (4Kbit)512Byte 2 16 16 A2 A1 P0 4 片内8位地址+ P0块地址码 “写地址控制帧”后,下跟地址帧就需要高地址24WC08 (8Kbit)1KByte 4 16 16 A2 P1 P0 2 片内8位地址+ 2位块地址码 和低8位地址这两个地址9 24WC16 (16Kbit)2KByte 8 16 16 P2 P1 P0 1 片内8位地址+3位块地址码 帧。 24WC32 (16Kbit)4KByte 1 128 32 A2 A1 A0 8 片内12位地址 表中Pi 的含义是片内的块选地址码,由引脚24WC64 (64Kbit)8KByte 1 256 32 A2 A1 A0 8 片内13位地址 上的高低电平设定。 24WC128 (128Kbit)16KByte 8 32 64 P2 P1 P0 1 片内11位地址+3位块地址码 24WC256 (256Kbit)32KByte

1 512 64 - A1 A0 4 片内15位地址 IC总线补充资料

2

附录第 页

主控器对CAT24WCXX进行写操作的对话序列 指定地址,单字节写 S、器件类型、器件地址、R/W0 主控器对CAT24WCXX进行读操作的对话序列 A B 指定地址,页内多字节写 S、器件类型、器件地址、R/W0 主控方查询及应答 S、器件类型、器件地址、R/W0 C D 当前地址 单字节读 S、器件类型、器件地址、R/W1 E 当前地址 页内多字节读 S、器件类型、器件地址、R/W1 F 指定地址, 单字节读 S、器件类型、器件地址、R/W0 G 指定地址,页内多字节读 S、器件类型、器件地址、R/W0 1 2 3 ACK 指定器件内地址8位 ACK 指定器件内地址8位 要写入的数据8位 ACK ACK应答表示24WC已ACK NACK (紧接着,主控方发送) P ACK ACK (从器件继续提供读出数据) 下一个地址单元数据8位 ACK ACK ACK NACK ACK 指定器件内地址8位 ACK 写入数据8位 ACK 经完成内部擦写过程。 S、器件类型、器件地址、R/W0 当前地址单元数据8位 当前地址单元数据8位 指定器件内地址8位 ACK Sr、器件类型、地址、R/W1 ACK ACK 下一个写入数据8位 下一个写入数据8位 NACK 非应答NACK,表示24WC正在进行内部擦写,不能Sr、器件类型、地址、R/W1 ACK 下一个地址单元数据8位ACK ACK (从器件继续提供读出的数据) 下一个地址单元数据8位 4 (在P后,从器件才开始内部擦和写操作) (紧接着,主器件方发送) P ( 主控方继续提供写入数据) 当前地址单元数据8位 当前地址单元数据8位 ACK 响应其它操作。 ACK 24WCXX内部的擦写过程需要时间,一般不超过10ms,典型时间5ms。在内部擦写期间,禁止数据地址的读写,但可以接受并回应主器件的查询。 因此,主控方要继续进行读写操作,需要先查询。 所谓主控方的查询,其实就是试探发送一个“写控制帧”,以24CW的应答位来判断它的状态罢了。 ACK 下一个地址单元数据8位(如果读完,不再读了,主控方就要回应) NACK 5 (紧接着,主控方发送) P (如读完主控方就) NACK (紧接着,主控方发送) P 6 继续向页内写入下一个单元的数据,究竟可以连续写入多少个单元,要受页内大小的制约。 (如果写完,主控方应发送) (紧接着,主控方再发送) P 所谓“当前地址”,就是“默认地址”,就是在本次操作前,已经在24CW中指定的地址。 P 注意:Sr是插入在会话中的又一个开始位,是重开始位,Sr与S信号的形式完全一样,毫无二致。 为什么要发Sr? 因为前面发送了一个写控制帧,并随后写入了指定地址值。但紧接着需要对24CW中指定的地址单元进行读操作,因此还要向24CW从器件发一个读控制帧,凡发送一个IIC通信的控制帧,必须拼装开始信号S。 在主控方发送P后,从器件才开始内部的擦写操作 阴影部分和左边“A”和“B”会话序列的前二行一样,是读取字节的指定地址的“写操作”,但后续行不一样了。

IC总线补充资料

2

附录第 页

IC总线时序图表(时序图中显示了两个不完整的“基本单位”)

什么是时序图?数字电路系统中,在统一时间坐标轴上(也许隐含),对多个数字信号波形图所作的集成二维图示。

所谓二维:在X(左右)方向上能反映数字信号随时间进程的变化;Y(上下)方向上可以在各时间断面上反映各数字信号之间的关系。

2

⑦总线空闲时间

⑩SCL和SDA下降时间

②开始位保持时间

⑧ ②开始位保持时间 参数的意义 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ④ ①开始位准备时间 标准模式S 参数指标 参数符号 最小值 最大值 0 4.7 4 4.7 4 250 4 4.7 5 100 1000 300 0.1Vcc 0.2Vcc 快速模式F ⑥停止位建立准备时间 最小值 最大值 单位 KHz μs μs μs μs ns μs μs μs ns ns

2

在第五章中的串行通信接口和这里基于IC总线的串行通信学习中,我们先后采用了两种不同的学习方法:“不打开”的和“打开”的方法。在这里,我们具体到每一个“位传输”过程的

2

干预,甚至干预到“提前多少时间建立准备好数据”、“数据保持多少时间”这样精细的程度,是一种“打开”的方法。这是因为89C51没有IC总线通信模块,我们不得不以编程方式来模

22

拟实现IC协议所致。这里,我们从初步认识IC协议、学习时序图的精细规定,学习精细的底层操作,尤其是培养了一份耐心。在今后的工作学习中,我们要辩证地掌握和使用这两种学习方法,特别在“知识爆炸”的今天,注意以“不打开”、“拿来主义”、“知识模块化平台化”为特征的“工程化学习方法”。这是何立民教授、周立功董事长告诫我们的。

fSCL SCL时钟频率 tSU;STA 开始位建立(准备)时间 tHD;STA 开始位保持时间 tLOW SCL低电平保持时间 tHIGH SCL高电平保持时间 tSU;DAT 数据建立(准备)时间 tSU;STO 停止位建立(准备)时间 停止位和开始位之间的总线空闲时间 tBUF tHD;DAT 数据保持时间 tr SDA和SCL信号上升时间 tf SDA和SCL信号下降时间 每个连接的器件低电平时的噪声容限 0.1Vcc 每个连接的器件高电平时的噪声容限 0.2Vcc 0 0.6 0.6 1.3 0.6 100 0.6 1.3 0 20 20 400 0.9 300 300

IC总线补充资料 2

附录第 页 45. } 软件环境: Keil uVision 4.10 46.} 硬件环境: CT107单片机综合实训平台(Fosc=12MHz) /***** 在I2C总线发送一个字节数据⑤ *****/ 日 期: 2011-8-9 ******/ /**入口条件:IIC总线控制权必须在单片机,且SCL=0,以2/*****这是“工信部长天杯”竞赛提供的IC总线驱动程序包:由便SDA建立更新数据。**/ 22IC.C源程序文件和IC. h头文件两个文件构成: 47.void IIC_SendByte(unsigned char byt) 2源程序文件中含6个关于IC通信的基础函数,每一个函数48.{ unsigned char i; 都不能完成一个完整的IIC通信,所以叫“基础操作”。但借助49. for(i=0;i<8;i++) 2它们,根据IC总线上某器件的具体规定(比如24C02,P8591),50. { 2有序组织这些基础函数,进行相应的IC“交互通信序列”,就可51. if(byt&0x80) //如果byt的位8是1,就… 以实现我们需要的读写操作。我们要学习和掌握如何调用这些基52. { 础接口函数,来实现我们的目的。 ******/ 53. SDA = 1; //向SDA发送1 2/*****以下,是单片机作为IC总线的单主控方,以模拟方式进54. } 2行IC通信基础操作的C源程序“IIC.C”文件 *****/ 55. else //否则… 1.#include \"iic.h\" //文件iic.h见后面 56. { /***** 发送IIC总线启动信号的函数 ① *****/ 57. SDA = 0; //向SDA发送0 /**入口条件:单片机作为主控方,必须掌握IIC总线控制权:58. } 因为本函数既要操作SCL,也要操作SDA****/ 59. somenop; //数据建立了,要保证时间⑤,才能… 2.void IIC_Start(void) 60. SCL = 1; 3.{ SDA = 1; 61. byt <<= 1; // 4. SCL = 1; //这是初始状态,见时序图 62. somenop; //保证时间④,才能… 5. somenop; //延时,保证时间① 63. SCL = 0; //给SDA提供下一次更新数据的条件 6. SDA = 0; //SDA↓,发出开始信号S 64. } 7. somenop; //保证时间②,才能… 65 . } 28. SCL = 0; //注意这个出口状态 /***** 从IC总线上接收一个字节数据⑥ *****/ 9.} /****入口条件:必须放弃SDA控制权(即SDA口线=1),让从器件控/***** 发送总线停止信号的函数 ② *****/ 制SDA。必须SCL=0,以便从器件在SDA上建立更新数据。****/ /**入口条件:IIC总线控制权必须在单片机,原因同上。**/ 66.unsigned char IIC_RecByte(void) 10.void IIC_Stop(void) 67.{ unsigned char da; 11.{ SDA = 0; 68. unsigned char i; 12. SCL = 1; 69. for(i=0;i<8;i++) 13. somenop; //保证时间⑥,才能… 70. { SCL=1; 14. SDA = 1; //SDA↑,发出停止信号P 71. somenop; //保证时间④ 15.} //注意出口条件 72. da <<= 1; 73. if(SDA) da |= 0x01; 发送应答位的函数 ③ *****/ /***** //读取SDA上的1,拼装在da的位0上。否则不… /**入口条件:IIC总线控制权必须在单片机。而且必须SCL=0,74. SCL=0; 此时SDA才可以建立或更新数据。注意形参ackbit **/ 75. somenop; //保证时间⑧ 16.void IIC_Ack(bit ackbit) /**** 提供延时,以保证从器件的SDA保持时间⑧。另外,17.{ if(ackbit) 也需要保证从器件下一个SDA的建立时间⑤(0.25μs)。在下一轮18. { SDA = 0; //发应答信号 的for语句头中,将执行i++和i<8判断等操作,对IIC总线时序而言,20. } 客观上也延了一些时间。 ****/ 21. else 76. } 22. { SDA = 1; //或,发非应答信号 77. return da; //将所得的da返回主调函数 24. } 78.} 25. somenop; //数据建立后,保证时间⑤,才能… /*******以下是IIC.H文件:**********/ 26. SCL = 1; 1.#ifndef _IIC_H /****条件编译:如符号“_IIC_H_ ”未27. somenop; //保证时间④,才能… 被定义,则编译2~15行;否则不编译。 ****/ 28. SCL = 0; 2.#define _IIC_H 29. SDA = 1; //放弃SDA线控制权,归还给从器件 3.#include \"reg52.h\" 30. somenop; //保证时间? 4.#include \"intrins.h\" 31.} //这是C51编译器库函数中“内部函数”原型声明头文件 /***** 接收应答位的函数 ④ *****/ 5.#define somenop /** 入口条件:必须SCL=0,让从器件在SCL=0期间建立或{ _nop_();_nop_();_nop_();_nop_();_nop_(); }更新SDA上的数据。注意函数的返回数据。 **/ //将somenop宏定义为5个空操作语句组,延时。 32.bit IIC_WaitAck(void) 6.#define SlaveAddrW 0xA0 //从器件地址写 33.{ SDA = 1; //放弃SDA线控制权,让给从器件 7.#define SlaveAddrR 0xA1 //从器件地址读 34. somenop; //给从器件提供时间⑤ 8.sbit SDA = P2^1; /* 数据线 */ 35. SCL = 1; 9.sbit SCL = P2^0; /* 时钟线 */ 36. somenop; //保证时间④ //将总线引脚以位变量的名义定义: 37. if(SDA) //如果SDA数据是1,非应答NACK… //以下是“IIC.C”中提供的6个基础函数的函数声明语句: 38. { SCL = 0; 10.void IIC_Start(void); 39. IIC_Stop(); //发送结束信号 11.void IIC_Stop(void); 40. return 0; //返回0,表示NACK 12.void IIC_Ack(bit ackbit); 41. } 13.bit IIC_WaitAck(void); 42. else //否则… 14.void IIC_SendByte(unsigned char byt); 43. { SCL = 0; 15.unsigned char IIC_RecByte(void); 44. return 1; //返回1,表示ACK 16.#endif /******************/ /*程序说明:51单片机模拟操作 I2C总线的驱动程序 I2

C总线补充资料 MCS-51单片机模拟I2C软件包(V1.1) 文件名:VI2C_C51.C 相关文件:VI2C_C51.H,VI2C_C51.LIB 功能说明:本I2C模拟软件包中有5个I2C的基础函数,完成发送数据及接收数据、应答位发送等基础操作;并提供6个直接面对器件的接口函数,很方便的与用户程序连接并可扩展。 注意:函数中采用软件延时的方法产生SCL脉冲,对晶振频率更高的单片机,为保证时序的要求,须作相应修改(本软件包设定晶振频率12MHZ,机器周期是1us)。 本软件包模拟的I2C总线时序符合I2C标准模式,即100Kbit/S。更新时间:2002.06.05 附加说明:这是周立功公司提供的I2C模拟软件包,并非仅仅针对24WCxx器件,而是针对所有I2C总线器件的。软件包中的接口函数4 中所指“无子地址(片内地址)器件”似乎不是说24WCxx存储器。但接口函数4“从无子地址(无片内地址)器件读单字节数据”的函数,仍然可以应用于24WCxx存储器:我们理解为是对24WCxx存储器进行“当前片内地址(即缺省片内地址)的单字节读”操作,即前面的会话序列D。 ****************************/ 1 #include 2 #include //内部库函数头文件 3 #define uchar unsigned char /*宏定义*/ 4 #define uint unsigned int /*宏定义*/ 5 #define _Nop() _nop_() //宏定义空指令 6 sbit SDA=P3^4; /*模拟I2C数据传送位*/ 7 sbit SCL=P3^5; /*模拟I2C时钟控制位*/ 8 bit bdata ack; /*应答标志位*/ /***************起动总线函数 底层函数1 ************ 函数原型:void Start_I2c(); 功能:启动I2C总线,即发送I2C起始条件. 入口条件:IIC总线控制权在主控方,且SCL=0 出口状态:SDA=0,SCL=0,主控方继续控制I2C总线。 **************************/ 9 void Start_I2c() 10 { SDA=1; /*发送起始条件的数据信号*/ 11 _Nop(); 12 SCL=1; // 13 _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); /*起始位准备时间①≥4.7us,延时*/ 14 SDA=0; /*发送起始信号*/ 15 _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); /*起始位保持时间②≥4μs*/ 16 SCL=0; /*钳住I2C总线,准备发送或接收数据 */ 17 _Nop(); _Nop(); // 18 } /*** 结束总线函数 底层函数2 *********** 函数原型: void Stop_I2c(); 功能: 结束I2C总线,即发送I2C结束条件. 出口状态:SDA=1,SCL=1。主控方已放弃对I2C总线的操控。 ******************************************/ 19 void Stop_I2c() 20 { SDA=0; /*发送结束条件的数据信号*/ 21 _Nop(); /*发送结束条件的时钟信号*/ 22 SCL=1; 23 _Nop();_Nop(); _Nop();_Nop(); _Nop(); /*结束位建立时间⑥大于4μs*/ 24 SDA=1; //发送I2C总线结束信号 25 _Nop();_Nop();_Nop();_Nop(); //保证时间⑦≥4.7μs ? } /*********一字节数据发送(写)函数 底层函数3 ******** 函数原型: void SendByte(uchar c); 功能: 将数据c发送出去,可以是地址,也可以是数据。发完后等待应答,并根据对方应答状态进行操作:对方不应答或非应答都使ack=0;对方正常应答,ack=1。ack是全局位变量。 出口状态:SDA=1,SCL=0。*******************/ 26 void SendByte(uchar c) 附录第 页 27 { uchar BitCnt ; 28 for(BitCnt=0;BitCnt<8;BitCnt++) /*要发送(写)的数据长度为8位*/ 29 { 30 if((c<附录第 页 但我们可以理解为是缺省片内地址,即所谓“当前片内地址”。那么,这个接口函数应用于24WCxx存储器中,可理解为“向当前片内地址读单字节数据”这样的操作,即前面会话表格的D会话序列。****************/ bit IRcvByte(uchar sla,uchar *c) 从器件地址sla。函数返回值是bit值,如果返回1表示操作成功,否则操作有误。 注意:使用前必须已结束总线。 ****************************/ 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); //返回1表示成功 } /****向有子地址器件发送(写)多字节数据函数 接口函数2 函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no); 功能:从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。如果返回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 #include #define uint unsigned int #define uchar unsigned char #define nop() _nop_() sbit SCL=P1.0; sbit SDA=P1.1; /*****主控方发送I2C开始信号 基础函数1 开始信号发送后的出口状态:SDA=SCK=0 ******/ void s_i2c(void) { SDA=1 ; _nop() ; SCL=1 ; _nop() ; _nop() ; _nop() ; _nop() ; _nop() ; //保证时间①(开始位准备时间) 2

附录第 页 //主控器读取SDA线上的数据,SDA为1,就给rec最低位赋值1 //如SDA为零,就让rec最低位为0 _nop() ; _nop() ; //保证T③?④? } SCL=0 ; _nop() ; _nop() ; return(rec) ; //向主调函数返回数据rec } /******主控器向从器件发送ACK或NACK 基础函数五** ****************************************************************/ void ack_i2c(bit a) //形参是位变量a { if(a==0)SDA=0 ; //应答ACK else SDA=1 ; //或否应答NACK nop() ;nop() ;nop() ;nop() ; //保证数据建立时间⑤ SCL=1 ; nop() ; _nop() ; _nop() ; _nop() ; _nop() ; SDA=0; //发送START nop() ; _nop() ; _nop() ; _nop() ; _nop() ; // 保证时间②(开始位保持时间) SCL=0 ; // 这是开始信号 nop() ; _nop() ; } /**************主控器发送I2C结束信号 **************** 入口状态:SDA=SCK=0 基础函数2 出口状态:SDA=SCK=1 **************/ void p_i2c(void) { SDA=0 , _nop() ; SCL=1 ; _nop() ; _nop() ; _nop() ; _nop() ; _nop() ; //保证T⑥(停止位准备时间) SDA=1 ; //发送停止位 _nop() ; _nop() ; _nop() ; _nop() ; _nop() ; //保证T⑦(总线空闲时间) } /*************主控器发送(写)一个字节数据 基础函数3 入口状态:应该是SDA=SCK=0 出口状态:SDA仍然释放,SCL=0 **************/ void sendbyte(uchar c) { uchar i ; for(i=0 ; i<8 ; i++) { if((c<

因篇幅问题不能全部显示,请点此查看更多更全内容