当前位置:文档之家› 实验二 I2C存储器实验

实验二 I2C存储器实验

I2C存储器实验实验目的1、了解I2C总线的工作原理2、掌握I2C总线驱动程序的设计和调试方法3、掌握I2C总线存储器的读写方法实验仪器单片机开发板、稳压电源、计算机实验原理1、 I2C总线常识I2C总线采用一个双线式漏极开路接口,可在一根总线上支持多个器件和主控器。

所连接的器件只会把总线拉至低电平,而决不会将其驱动至高电平。

总线在外部通过一个电流源或上拉电阻器连接至一个正电源电压。

当总线空闲时,两条线路均为高电平。

在标准模式中,I2C 总线上的数据传输速率高达100kbit/s,而在快速模式中则高达400kbit/s。

I2C总线上的每个器件均由一个存储于该器件中的唯一地址来识别,并可被用作一个发送器或接收器(视其功能而定)。

除了发送器和接收器之外,在执行数据传输时,还可把器件视作主控器或受控器。

主控器是负责启动总线上的数据传输并生成时钟信号以允许执行该传输的器件。

同时,任何被寻址的器件均被视作受控器。

CAT24WC01/02/04/08/16是一个1K/2K/4K/8K/16K位串行CMOS EEPROM,内部含有128/256/512/1024/2048个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗,CAT24WC01有一个8字节页写缓冲器,CAT24WC02/04/08/16有一个16字节页写缓冲器,该器件通过I2C总线接口进行操作,有一个专门的写保护功能,并且器件能与400KHzI2C 总线兼容。

引脚名称和功能如图1所示。

图1 24系例I2C存储器引脚说明通过器件地址输入端A0、A1和A2可以实现将最多8个24WC01和24WC02器件4个24WC04器件,2个24WC08器件和1个24WC16器件连接到总线上。

2、I2C总线协议(1)只有在总线空闲时才允许启动数据传送。

(2)在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变。

时钟线为高电平时,数据线的任何电平变化将被看作总线的起始或停止信号。

(3)起始信号时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C 总线的起始信号。

(4) 停止信号时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C 总线的停止信号。

I2C 总线时序:I2C 总线时序图I2C总线启动停止信号波形:SCL为高电平,SDA降沿为启动信号;SCL为高电平,SDA 上升沿为停止信号。

I2C 总线启动停止信号I2C总线写周期波形:SCL正脉冲锁存数据,或SCL为高电平数据有效。

SCL高电平期间SDA数据应保持不变。

I2C 总线写时序波形I2C总线应答信号波形:I2C总线数据传送时,每成功地传送一个字节数据后,接收器都必须产生一个应答信号。

应答的器件在第9个时钟周期时将SDA线拉低,表示其已收到一个8 位数据。

I2C 总线读时序3、24C系列存储器读写操作(1)24系列常用存储器器件地址安排24系例存储器器件地址安排(2)字节写操作在字节写模式下,主器件发送起始命令和从器件地址信息(R/W位置零)给从器件,在从器件产生应答信号后,主器件发送CAT24WC01/02/04/08/16的1字节地址(存储容量大的存储器字节地址两字节),主器件在收到从器件的另一个应答信号后,再发送数据到被寻址的存储单元。

CAT24WC01/02/04/08/16再次应答,并在主器件产生停止信号后,开始内部数据的擦写,在内部擦写过程中从器件不再应答主器件的任何请求(10ms)。

如图所示。

字节写操作数据帧结构(3)页写操作(提高写入速度)根据页缓冲区的大小,页写的字节数不能超过缓冲区大小。

如果在发送停止信号之前主器件发送超过缓冲区大小,地址计数器将自动翻转,先前写入的数据被覆盖。

如图所示。

页写操作数据帧结构(4)当前地址读操作当读取一个字节数据后,存储器内部地址计数器加1。

当读到最后一字节时,计数器将翻转到0且继续输出数据。

CAT24WC01/02/04/08/16 接收到从器件地址信号后(R/W 位置1),它首先发送一个应答信号,然后发送一个8位字节数据。

主器件产生一个非应答信号(这里是主器件发送的非应答信号),再产生一个停止信号。

如图所示。

当前地址读操作数据帧结构(5)任意地址读操作、连续读操作任意地址读、连续读操作数据帧结构4、I2C总线存储读写程序设计I2C总线存储器读写程序分为两层:硬件接口程序和存储器读写程序。

其中硬件接口程序有:总线启动、停止、发数据、收数据、发响应、发非响应、读从器件响应状态等。

存储器读写程序有:单字节写数据、页写数据、当前地址读数据、任意地址读数据、连续读数据等。

参考上面的时序图设计硬件接口相关子程序。

I2C总线接口程序流程图I2C总线数据读写流程图存储器读写程序设计。

这里以单字节读、写程序为例说明,其它子程序由读者自行设计。

I2C存储器单字节读写流程图实验参考程序:/******************************************************************************普中科技--------------------------------------------------------------------------------* 实验名 : 24C02EEPROM存储试验* 实验说明 : 使用LCD1602显示写入的数据和读出的数据* 连接方式 : 见连接图* 注意 :******************************************************************************/ #include<reg51.h>#include"i2c.h"#include"lcd.h"//--定义使用的IO口--////数码管IO#define GPIO_DIG P0sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;//按键IOsbit K1=P3^0;sbit K2=P3^1;sbit K3=P3^2;sbit K4=P3^3;//--定义全局变量--//unsigned char wordCode0[6] = "write:";unsigned char wordCode1[6] = " read:";//--声明全局函数--//void At24c02Write(unsigned char ,unsigned char );unsigned char At24c02Read(unsigned char );void Delay10ms(unsigned int c); //误差 0us/****************************************************************************** * 函数名 : main* 函数功能 : 主函数* 输入 : 无* 输出 : 无******************************************************************************/ void main(){unsigned int num0 = 0,num1 = 0,n;LcdInit();LcdWriteCom(0x80);for(n=0; n<6; n++){LcdWriteData(wordCode0[n]);}LcdWriteCom(0x80 + 0x40);for(n=0; n<6; n++){LcdWriteData(wordCode1[n]);}while(1){if(K1 == 0) //按键1按下{Delay10ms(1);if(K1 == 0)At24c02Write(2,num0);while((n < 50)&&(K3==0)){n++;Delay10ms(1);}n=0;n=0;}if(K2 == 0) //按键2按下{Delay10ms(1);if(K2 == 0)num1 = At24c02Read(2);while((n < 50)&&(K2 == 0)){n++;Delay10ms(1);}n=0;}if(K3 == 0) //按键3按下{Delay10ms(1);if(K3 == 0)num0++;while((n < 50)&&(K3 == 0)){n++;Delay10ms(1);}n=0;if(num0==256)num0=0;}if(K4 == 0) //按键4按下{Delay10ms(1);if(K4 == 0)num0 = 0;while((n < 50) && (K4 == 0)){n++;Delay10ms(1);}n=0;}LcdWriteCom(0x87);LcdWriteData('0' + (num0/1000));//千位LcdWriteData('0' + (num0%1000/100));//百位LcdWriteData('0' + (num0%1000%100/10));//十位LcdWriteData('0' + (num0%1000%100%10));//个位LcdWriteCom(0x87 + 0x40);LcdWriteData('0' + (num1/1000));//千位LcdWriteData('0' + (num1%1000/100));//百位LcdWriteData('0' + (num1%1000%100/10));//十位LcdWriteData('0' + (num1%1000%100%10));//个位}}/****************************************************************************** * 函数名 : Delay10ms* 函数功能 : 延时函数,延时10ms* 输入 : 无* 输出 : 无******************************************************************************/void Delay10ms(unsigned int c) //误差 0us{unsigned char a, b;//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--){for (b=38;b>0;b--){for (a=130;a>0;a--);}}}/****************************************************************************** * 函数名 : void At24c02Write(unsigned char addr,unsigned char dat)* 函数功能 : 往24c02的一个地址写入一个数据* 输入 : 无* 输出 : 无******************************************************************************/void At24c02Write(unsigned char addr,unsigned char dat){I2C_Start();I2C_SendByte(0xa0, 1);//发送写器件地址I2C_SendByte(addr, 1);//发送要写入内存地址I2C_SendByte(dat, 0); //发送数据I2C_Stop();}/****************************************************************************** * 函数名 : unsigned char At24c02Read(unsigned char addr)* 函数功能 : 读取24c02的一个地址的一个数据* 输入 : 无* 输出 : 无******************************************************************************/unsigned char At24c02Read(unsigned char addr){unsigned char num;I2C_Start();I2C_SendByte(0xa0, 1); //发送写器件地址I2C_SendByte(addr, 1); //发送要读取的地址I2C_Start();I2C_SendByte(0xa1, 1); //发送读器件地址num=I2C_ReadByte(); //读取数据I2C_Stop();return num;}#include"i2c.h"/****************************************************************************** * 函数名 : Delay1us()* 函数功能 : 延时* 输入 : 无* 输出 : 无******************************************************************************/void I2C_Delay10us(){uchar a, b;for(b=1; b>0; b--){for(a=2; a>0; a--);}}/****************************************************************************** * 函数名 : I2C_Start()* 函数功能 : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿* 输入 : 无* 输出 : 无* 备注 : 起始之后I2C_SDA和I2C_SCL都为0******************************************************************************/void I2C_Start(){I2C_SDA = 1;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7usI2C_SDA = 0;I2C_Delay10us();//保持时间是>4usI2C_SCL = 0;I2C_Delay10us();}/****************************************************************************** * 函数名 : I2C_Stop()* 函数功能 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿* 输入 : 无* 输出 : 无* 备注 : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲******************************************************************************/void I2C_Stop(){I2C_SDA = 0;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();//建立时间大于4.7usI2C_SDA = 1;I2C_Delay10us();}/****************************************************************************** * 函数名 : I2cSendByte(uchar num)* 函数功能 : 通过I2C发送一个字节。

相关主题