实验二 I2C存储器实验重点讲义资料.docx
- 文档编号:4935791
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:23
- 大小:639.86KB
实验二 I2C存储器实验重点讲义资料.docx
《实验二 I2C存储器实验重点讲义资料.docx》由会员分享,可在线阅读,更多相关《实验二 I2C存储器实验重点讲义资料.docx(23页珍藏版)》请在冰豆网上搜索。
实验二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
#include"i2c.h"
#include"lcd.h"
//--定义使用的IO口--//
//数码管IO
#defineGPIO_DIGP0
sbitLSA=P2^2;
sbitLSB=P2^3;
sbitLSC=P2^4;
//按键IO
sbitK1=P3^0;
sbitK2=P3^1;
sbitK3=P3^2;
sbitK4=P3^3;
//--定义全局变量--//
unsignedcharwordCode0[6]="write:
";
unsignedcharwordCode1[6]="read:
";
//--声明全局函数--//
voidAt24c02Write(unsignedchar,unsignedchar);
unsignedcharAt24c02Read(unsignedchar);
voidDelay10ms(unsignedintc);//误差0us
/******************************************************************************
*函数名:
main
*函数功能:
主函数
*输入:
无
*输出:
无
******************************************************************************/
voidmain()
{
unsignedintnum0=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
*输入:
无
*输出:
无
******************************************************************************/
voidDelay10ms(unsignedintc)//误差0us
{
unsignedchara,b;
//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
for(;c>0;c--)
{
for(b=38;b>0;b--)
{
for(a=130;a>0;a--);
}
}
}
/******************************************************************************
*函数名:
voidAt24c02Write(unsignedcharaddr,unsignedchardat)
*函数功能:
往24c02的一个地址写入一个数据
*输入:
无
*输出:
无
******************************************************************************/
voidAt24c02Write(unsignedcharaddr,unsignedchardat)
{
I2C_Start();
I2C_SendByte(0xa0,1);//发送写器件地址
I2C_SendByte(addr,1);//发送要写入内存地址
I2C_SendByte(dat,0);//发送数据
I2C_Stop();
}
/******************************************************************************
*函数名:
unsignedcharAt24c02Read(unsignedcharaddr)
*函数功能:
读取24c02的一个地址的一个数据
*输入:
无
*输出:
无
******************************************************************************/
unsignedcharAt24c02Read(unsignedcharaddr)
{
unsignedcharnum;
I2C_Start();
I2C_SendByte(0xa0,1);//发送写器件地址
I2C_SendByte(addr,1);//发送要读取的地址
I2C_Start();
I2C_SendByte(0xa1,1);//发送读器件地址
num=I2C_ReadByte();//读取数据
I2C_Stop();
returnnum;
}
#include"i2c.h"
/******************************************************************************
*函数名:
Delay1us()
*函数功能:
延时
*输入:
无
*输出:
无
******************************************************************************/
voidI2C_Delay10us()
{
uchara,b;
for(b=1;b>0;b--)
{
for(a=2;a>0;a--);
}
}
/******************************************************************************
*函数名:
I2C_Start()
*函数功能:
起始信号:
在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿
*输入:
无
*输出:
无
*备注:
起始之后I2C_SDA和I2C_SCL都为0
******************************************************************************/
voidI2C_Start()
{
I2C_SDA=1;
I2C_Delay10us();
I2C_SCL=1;
I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
I2C_SDA=0;
I2C_Delay10us();//保持时间是>4us
I2C_SCL=0;
I2C_Delay10us();
}
/******************************************************************************
*函数名:
I2C_Stop()
*函数功能:
终止信号:
在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿
*输入:
无
*输出:
无
*备注:
结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲
******************************************************************************/
voidI2C_Stop()
{
I2C_SDA=0;
I2C_Delay10us();
I2C_SCL=1;
I2C_Delay10us();//建立时间大于4.7us
I2C_SDA=1;
I2C_Delay10us();
}
/******************************************************************************
*函数名:
I2cSendByte(ucharnum)
*函数功能:
通过I2C发送一个字节。
在I2C_SCL时钟信号高电平期间,
**保持发送信号I2C_SDA保持稳定
*输入:
num,ack
*输出:
0或1。
发送成功返回1,发送失败返回0
*备注:
发送完一个字节I2C_SCL=0,需要应答则应答设置为1,否则为0
******************************************************************************/
ucharI2C_SendByte(uchardat,ucharack)
{
uchara=0,b=0;//最大255,一个机器周期为1us,最大延时255us。
for(a=0;a<8;a++)//要发送8位,从最高位开始
{
I2C_SDA=dat>>7;//起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
dat=dat<<1;
I2C_Delay10us();
I2C_SCL=1;
I2C_Delay10us();//建立时间>4.7us
I2C_SCL=0;
I2C_Delay10us();//时间大于4us
}
I2C_SDA=1;
I2C_Delay10us();
I2C_SCL=1;
while(I2C_SDA&&(ack==1))//等待应答,也就是等待从设备把I2C_SDA拉低
{
b++;
if(b>200)//如果超过200us没有应答发送失败,或者为非应答,表示接收结束
{
I2C_SCL=0;
I2C_Delay10us();
return0;
}
}
I2C_SCL=0;
I2C_Delay10us();
return1;
}
/******************************************************************************
*函数名:
I2cReadByte()
*函数功能:
使用I2c读取一个字节
*输入:
无
*输出:
dat
*备注:
接收完一个字节I2C_SCL=0
******************************************************************************/
ucharI2C_ReadByte()
{
uchara=0,dat=0;
I2C_SDA=1;//起始和发送一个字节之后I2C_SCL都是0
I2C_Delay10us();
for(a=0;a<8;a++)//接收8个字节
{
I2C_SCL=1;
I2C_Delay10us();
dat<<=1;
dat|=I2C_SDA;
I2C_Delay10us();
I2C_SCL=0;
I2C_Delay10us();
}
returndat;
}
#include"lcd.h"
/******************************************************************************
*函数名:
Lcd1602_Delay1ms
*函数功能:
延时函数,延时1ms
*输入:
c
*输出:
无
*说名:
该函数是在12MHZ晶振下,12分频单片机的延时。
******************************************************************************/
voidLcd1602_Delay1ms(uintc)//误差0us
{
uchara,b;
for(;c>0;c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/******************************************************************************
*函数名:
LcdWriteCom
*函数功能:
向LCD写入一个字节的命令
*输入:
com
*输出:
无
******************************************************************************/
#ifndefLCD1602_4PINS//当没有定义这个LCD1602_4PINS时
voidLcdWriteCom(ucharcom)//写入命令
{
LCD1602_E=0;//使能
LCD1602_RS=0;//选择发送命令
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=com;//放入命令
Lcd1602_Delay1ms
(1);//等待数据稳定
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);//保持时间
LCD1602_E=0;
}
#else
voidLcdW
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验二 I2C存储器实验重点讲义资料 实验 I2C 存储器 重点 讲义 资料