C51程序综合程序设计范例五I.ppt
11,C51综合程序设计范例(五),2,Engineering Technical Colledge-1959,本讲主要内容:,11-1.综合程序设计范例五(I2C接口程序设计)11-2.I2C总线接口协议11-3.24C02与单片机接口11-3.实验十,3,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,设计范例:设计程序实现向24C02的第一个单元写入一个数据,再将该数据读出,并将其显示在数码管上。,4,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件:24C02特性24C02与P89V51RD2的接口程序设计中需要解决的主要问题:I2C总线协议24C02的读写,5,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02:串行E2PROM是在各种串行器件应用中使用较频繁的器件,和并行E2PROM相比,串行E2PROM的数据传送的速度较低,但是其体积较小,容量小,所含的引脚也较少。所以,它特别适合于需要存放非挥发数据,要求速度不高,引脚少的单片机的应用。24CXX系列的E2PROM有10种型号,其中典型的型号有24C01/02/04/08/16等5种,它们的存储容量分别是128/256/512/1024/2048字节。24CXX系列的E2PROM 支持I2C 总线数据传送协议,通过器件地址输入端A0、A1、A2 可以将最多8 个24C01/24/C02 器件,4 个24C04 器件,2 个24C08 器件,1 个24C16 器件连接到总线上。这里我们就24C02的进行分析,其它型号与此类似。,6,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02:,7,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02:,8,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02:,A0 A1 A2器件地址输入端:当使用24C02 时最大可级联8 个器件,如果只有一个24C02 被总线寻址这三个地址输入脚A0 A1 A2 可悬空或连接到GND。WP写保护:如果WP 管脚连接到Vcc,所有的内容都被写保护(只能读).当WP 管脚连接到GND或悬空,允许器件进行正常的读/写操作。,9,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02:,SCL串行时钟:24C02串行时钟输入管脚用于产生器件所有数据发送或接收的时钟这是一个输入管脚。SDA串行数据/地址:24C02 双向串行数据/地址管脚用于器件所有数据的发送或接收SDA 是一个开漏输出管脚可与其它开漏输出或集电极开路输出进行线与(wire-OR)。,10,Engineering Technical Colledge-1959,11-1 综合程序设计范例五,范例分析:硬件24C02与P89V51RD2的接口:,11,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:I2C 总线支持任何IC 生产过程NMOS CMOS 双极性两线串行数据SDA 和串行时钟。SCL 线在连接到总线的器件间传递信息每个器件都有一个唯一的地址识别无论是微控制器、LCD驱动器、存储器或键盘接口。而且都可以作为一个发送器或接收器由器件的功能决定。很明显LCD驱动器只是一个接收器而存储器则既可以接收又可以发送数据。除了发送器和接收器外器件在执行数据传输时也可以被看作是主机或从机。主机是初始化总线的数据传输并产生允许传输的时钟信号的器件,此时任何被寻址的器件都被认为是从机。,12,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:SDA 和SCL 都是双向线路都通过一个电流源或上拉电阻连接到正的电源电压。都是高电平连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。I2C 总线上数据的传输速率在标准模式下可达100kbit/s 在快速模式下可达400kbit/s 在高速模式下可达3.4Mbit/s。,13,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:数据的有效性 SDA 线上的数据必须在时钟的高电平周期保持稳定。数据线的高或低电平状态只有在SCL 线的时钟信号是低电平时才能改变。,14,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:启始信号:时钟线保持高电平期间,数据线电平从高到低跳变作为I2C 总线的起始信号。,起始信号函数:void I2CStart(void)SDA=1;SCL=1;SomeNoP();延时 SDA=0;SomeNOP();SCL=0;,15,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:停止信号:时钟线保持高电平期间,数据线电平从低到高跳变作为I2C 总线的起始信号。,停止信号函数:void I2CStop(void)SCL=0;SDA=0;SomeNOP();延时 SCL=1;SomeNOP();SDA=1;,16,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:应答信号:I2C 总线数据传送时,每成功地传送一个字节数据后,接收器都必须产生一个应答信号。应答的器件在第9 个时钟周期时将SDA 线拉低,表示其已收到一个8 位数据。,void SendAck(void)/应答信号 SDA=0;/*SDA先清0,发应答信号*/SomeNOP();SCL=1;/*SCL由低变高,产生一个时钟*/SomeNOP();SCL=0;/*SCL恢复到低电平,以便继续接收*/,17,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:非应答信号:I2C 总线数据传送时,当接受结束时,接收器都必须产生一个非应答信号。器件在第9 个时钟周期时将SDA 线置高,表示已经接收完毕。如果主机接收数据时,它收到最后一个数据字节后,必须向从机发送一个非应答信号(/A),使从机释放SDA线,以便主机产生终止信号,从而停止数据传送。,void SendNotAck(void)/非应答信号 SDA=1;/*SDA先置1,发非应答信号*/SomeNOP();SCL=1;/*SCL由低变高,产生一个时钟*/SomeNOP();SCL=0;/*SCL恢复到低电平,以便继续接收*/,18,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节格式发送到SDA 线上的每个字节必须为8 位,每次传输可以发送的字节数量不受限制。每个字节后必须跟一个响应位。首先传输的是数据的最高位MSB,如果从机要完成一些其他功能后,例如一个内部中断服务程序才能接收或发送下一个完整的数据字节,可以使时钟线SCL 保持低电平迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续。,19,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:器件地址:I2C总线上的每一个从机均有一个唯一的地址,每次主机发出起始信号后,必须接着发出一个字节的地址信息,以选取挂在总线上的某一从机。地址信息的格式如下:,其中D7-D0位表示从机的地址,D0位是数据传送方向,为0时,表示主机向从机发送数据(写),为1时,表示主机由从机处读取数据。主机发送地址时,总线上的每一个从机都将这7位地址码与自已的器件地址进行比较,如果相同则认为自已正被主机寻址,根据读写位将自已确定为发送器或接收器。从机的地址由一个固定部分和一个可编程部分组成。固定部分为器件的编号地址,表明了器件的类型,出厂时固定的。可编程部分为器件的引脚地址,视硬件接线而定。,20,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:器件地址:I2C总线上的每一个从机均有一个唯一的地址,每次主机发出起始信号后,必须接着发出一个字节的地址信息,以选取挂在总线上的某一从机。地址信息的格式如下:,例:24C02的地址格式如下:其中高四位1010为器件标识类型。A2A0:引脚地址,对应于该芯片引脚A2A0的取值,当A2-A0引脚均接低电平时,该器件的地址为A0H或A1H,如果为A0H表示写数据到该器件,A1H表示从该器件读数据。说明:从机地址只表明选择挂在总线的哪一个器件及传送方向,而器件内部的地址是由编程者传送的第一数据中指定的,即第一个数据为器件内的子地址。,21,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节写时序:在字节写模式下,主器件发送起始命令和从器件地址信息(R/W 位置零)给从器件,在从器件产生应答信号后,主器件发从器件的字节地址.主器件在收到从器件的另一个应答信号后,再发送数据到被寻址的存储单元。从器件再次应答,并在主器件产生停止信号后开始内部数据的擦写,在内部擦写过程中(对于24C02而言这一过程大概需要5ms),从器件不再应答主器件的任何请求。,22,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节写时序:,I2CStart();I2CSendByte();WaitAck();I2CSendByte();WaitAck();I2CSendByte();WaitAck();I2CStop();for(j=0;j200;j+);SomeNOP();,23,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节读时序立即读:24C02 的地址计数器内容为最后操作字节的地址加1。也就是说,如果上次读/写的操作地址为N,则立即读的地址从地址N+1 开始。如果N=E(这里对24C02,E=255),则计数器将翻转到0 且继续输出数据。24C02 接收到从器件地址信号后(R/W 位置1),它首先发送一个应答信号,然后发送一个8 位字节数据。主器件不需发送一个应答信号,但要产生一个停止信号。,24,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节读时序:,I2CStart();I2CSendByte();WaitAck();I2CSendByte();WaitAck();I2CStart();I2CSendByte();WaitAck();i=I2CReceiveByte();,25,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节读时序页写:,26,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节读时序随机读:,27,Engineering Technical Colledge-1959,11-2 I2C总线接口协议,范例分析:程序设计I2C总线协议:字节读时序顺序读:,28,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考流程(设计程序实现对小车上的外扩24C02写入数据2,然后读出该数据,并将其显示在数码管上。),29,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,#include#include#include#include#include#include#define uchar unsigned char#define uint unsigned int#define bool bit#define SomeNOP();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();sbit SCL=P21;sbit SDA=P22;void I2CStart(void);void I2CStop(void);,30,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,void I2CSendByte(uchar x);uchar I2CReceiveByte(void);void SendAck(void);void SendNotAck(void);bool WaitAck(void);void delay(uchar x)/延时程序 while(x-)SomeNOP();SomeNOP();SomeNOP();SomeNOP();SomeNOP();SomeNOP();,31,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,/*I2C相关函数*/void I2CStart(void)SDA=1;SCL=1;SomeNOP();SDA=0;SomeNOP();SCL=0;void I2CStop(void)SCL=0;SDA=0;SomeNOP();SCL=1;SomeNOP();SDA=1;,32,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,bool WaitAck(void)/等待应答信号 uchar errtime=255;SDA=1;SomeNOP();SCL=1;SomeNOP();while(SDA)errtime-;if(!errtime)I2CStop();return 0;SCL=0;return 1;,33,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,void SendNotAck(void)/非应答信号 SDA=1;SomeNOP();SCL=1;SomeNOP();SCL=0;void SendAck(void)/应答信号 SDA=0;SomeNOP();SCL=1;SomeNOP();,34,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,void I2CSendByte(uchar x)/发送一个字节数据 uchar i=8;while(i-)SCL=0;_nop_();SDA=(bit)(x,35,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,uchar I2CReceiveByte(void)/接受一个字节数据 uchar i=8;uchar temp=0;SDA=1;while(i-)temp=1;SCL=0;SomeNOP();SCL=1;SomeNOP();temp=temp|SDA;SCL=0;return temp;,36,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,void main()uchar i,j;SDA=1;/把新的节目源编号存到EEPROM中 I2CStart();I2CSendByte(0 xA0);/发送24C02的器件地址/(写控制字节)WaitAck();I2CSendByte(0 x00);/24C02内部存储单元子地址 WaitAck();I2CSendByte(0 x23);/向24C02发送的数据字节 WaitAck();I2CStop();for(j=0;j200;j+)/Here must delay enough time for writing SomeNOP();,37,Engineering Technical Colledge-1959,11-3 24C02与单片机的接口,参考程序,I2CStart();I2CSendByte(0 xA0);/读24C02之前的伪写地址 WaitAck();I2CSendByte(0 x00);/WaitAck();I2CStart();I2CSendByte(0 xA1);/24C02的读地址 WaitAck();i=I2CReceiveByte();/SendAck();SendNotAck();I2CStop();SomeNOP();SomeNOP();SomeNOP();SomeNOP();SomeNOP();SomeNOP();SomeNOP();,38,Engineering Technical Colledge-1959,实验十:1、完成演示范例中的程序;要求:I2C各个时序要求用单独函数完成。扩展:1、要求将写入和读出的数据进行比较,若相等时数码管显示C,否则显示F。2、尝试向24C02内写入一页数据,然后将其读出,并在数码管上将其显示出来(相邻数字间隔1秒。)也可以在液晶上等间隔显示。,11-4.实验十,