IC读写EEPROM问题总结.docx

上传人:b****0 文档编号:9357657 上传时间:2023-05-18 格式:DOCX 页数:8 大小:26.11KB
下载 相关 举报
IC读写EEPROM问题总结.docx_第1页
第1页 / 共8页
IC读写EEPROM问题总结.docx_第2页
第2页 / 共8页
IC读写EEPROM问题总结.docx_第3页
第3页 / 共8页
IC读写EEPROM问题总结.docx_第4页
第4页 / 共8页
IC读写EEPROM问题总结.docx_第5页
第5页 / 共8页
IC读写EEPROM问题总结.docx_第6页
第6页 / 共8页
IC读写EEPROM问题总结.docx_第7页
第7页 / 共8页
IC读写EEPROM问题总结.docx_第8页
第8页 / 共8页
亲,该文档总共8页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

IC读写EEPROM问题总结.docx

《IC读写EEPROM问题总结.docx》由会员分享,可在线阅读,更多相关《IC读写EEPROM问题总结.docx(8页珍藏版)》请在冰点文库上搜索。

IC读写EEPROM问题总结.docx

IC读写EEPROM问题总结

公司内部编号:

(GOOD-TMMT-MMUT-UUPTY-UUYY-DTTI-9018)

 

IC读写EEPROM问题总结

2017年6月30日星期五

目的:

利用TMS320F2801芯片上外设I2C(2线串口)读写EEPROM数据(24LC128)

关键点1:

24LC时钟频率400KHz,寄存器设置如下:

I2caRegs.I2CPSC.all=9;//Prescaler-need7-12Mhzonmoduleclk

I2caRegs.I2CCLKL=10;//NOTE:

mustbenonzero

I2caRegs.I2CCLKH=5;//NOTE:

mustbenonzero

时钟频率也可设为200KHz,三个参数分别为9、20、20(CPU时钟频率为100MHz)(未测试)

关键点2:

波形分析

问题:

I2C模块是不是只有I2CCNT减到0才会发出停止信号?

I2C模块是硬件的,当检测到发送完了就会发结束自动发信号,不需要人为干预

问题1:

字节写操作正常,但是字节读函数出错

原因:

写EEPROM是在七位器件地址后添加写标志,而读EEPROM需要在七位器件地址后添加写标志。

关键点:

读EEPROM数据需要发送两次命令。

第一次为写地址(此地址会被赋值给EEPROM内的地址指针),因此需要添加写标志;第二次为读数据,将写标志改为读标志。

问题2:

主机接收时,SDA数据线上有数据传输,且I2CDRR接收数据寄存器有数据更新,但寄存器显示不可读,即CPU认为一直没接收到数据,一直停在下面语句

while

关键点:

初始化设置时采用的是FIFO接收方式,因此无效,应查询FIFO接收中断位while方式查询位。

此位只有在非FIFO中断接收方式时才有效。

问题3:

断续单字节读写正常,但是采用连续的单字节读写出错。

原因:

EEPROM写过程的结束并不是I2C总线写结束就结束,实际上I2C总线的写入数据先被保存到了EEPROM内部的缓冲区,当遇到I2C结束条件后,EEPROM才启动内部写过程,这个过程才是保存数据的过程。

非常悲哀的是这个过程比较长,官方文档标注为5ms。

如果在这5ms以内对EEPROM芯片访问将被忽略。

关键点:

读写EEPROM应延时至少5ms,软件延时10ms

do{}while(EEPROM_Timer<=10);//10ms

问题4:

查询EEPROM写过程是否结束造成死机,只能查询EEPROM读过程。

官方文档说EEPROM内部写周期最长为5ms,在很多情况下是远远低于5ms的,为了节约时间,官方给出一个解决办法。

当写周期完毕后就开始进行应答查询,来确定EEPROM写周期何时结束。

所谓应答查询官方解释为:

就是向EEPROM发送一个I2C起始条件后发送器件地址和一个读写标志位,当EEPROM完成内部写周期会回应一个ACK,这时MCU就可以进行正常的其他读写过程了。

官方原文如下:

杯具就是始于我画红线的那句话,它说可以在器件地址后任意填写读写标志。

我就填了读标志,事实证明在EEPROM写入过程采用读查询将导致系统死机,I2C总线不能被正常拉高,可能是EEPROM内部已经把总线拉到了地!

不管怎样,反正就是死机了。

经过多次尝试最终发现应答查询只能采用写应答查询可以正常确定EEPROM内部写周期的结束。

——by

数据传输过程:

从机发送数据?

SDA总线?

I2CRSR缓冲寄存器?

I2CDRR接收数据寄存器?

中间变量?

内存。

问题5:

CPU以字(双字节)为单位读写EEPROM数据有误;

原因:

CPU中的内存单元以字(word-16bit)为单位,而EEPROM中的内存单元是字节(byte-8bit)为单位,因此将CPU内存地址转化为EEPROM指针地址时,因乘以2(左移一位)

问题6:

使用读数据函数式,收到的数据都是1。

原因:

EEPROM初次读取未写过的内存单元时,默认为高电平,即收到的字节为0xFF。

如果已经写过内存单元,则代表数据未成功写入;

写入与读数据的内存地址不一样。

问题7:

写入EEPROM的数据与随后读出来的数据不一致,但读出来的数据又没有规律性。

可能原因:

数据未成功写入;数据读写字节数超过EEPROM的页内字节数(跨页);读写地址不一致;读写EEPROM之间应有一定的延时时间。

解决办法:

若连续读多字节数据,则读取数据之间应加延时,因为数据从I2CRSR数据接收缓冲寄存器(多字节)复制到I2CCDRR数据接收寄存器(一字节)需要时间。

单字节延时25us,双字节(字)延时50us——测试通过

问题8:

使用示波器观测SDA数据线上的波形时,发现每次应答信号之前都有一个毛刺(尖峰),是什么原因导致的?

(不影响数据的正常读写)

类似问题:

使用F28335模拟I2C时序读取惯导器件的数据时,发现在更改SDA的传输方向时,Gpio中数据寄存器会发生变化,导致SDA上有毛刺产生。

问题9:

I2C在跟EEPROM通讯的时候,第一次写入数据,一个一个读取的话,能知道写入EEPROM的值是没有错的,但是在连续读取数据的时候,就会出现,上电第一次读取数据串的时候,是全部读取正确,然后再读取一遍数据串的时候,只有第一个读取的数据是正确的,后面的数据会全部变成FFFF这是怎么回事?

办法1:

大家都说STM32的IIC有点bug,所以很少人用其自带的IIC,一般都是用IO口模拟IIC,模拟很简单而且不会出错。

逻辑分析仪抓取I2C总线数据,?

改为转接板抓取数据,即I2C转USB通讯。

问题10:

I2C给EEPROM写数据时,两字节地址需不需要算进去吗?

答案:

需要,且地址字节数与EEPROM的型号(容量)相关,有些为1字节地址,有些为2字节地址。

24LC128需要两字节地址来区分内存单元,其内存最小单元为1字节,地址从0x00开始,一页64字节,因此地址指针范围为:

0x00~0x3F。

I2caRegs.I2CCNT=(n<<1)+2;

问题11:

一次读写数据字节数最好不超过16字节。

原因:

其一I2C深度寄存器范围限定,其二,读写数据字节太多会导致I2C总线出错的概率加大。

ST_5bit(0x0000~0x10000)

I2caRegs.I2CFFTX.bit.TXFFIL_5bit

I2caRegs.I2CFFRX.bit.RXFFST_5bit(0x0000~0x10000)

I2caRegs.I2CFFRX.bit.RXFFIL_5bit

I2caRegs.I2CCNT_32bit

问题12:

总是提示总线繁忙=1

总线繁忙,BB=0总线空闲

关键:

总线繁忙这个位只读。

猜想解决办法:

如果是上电第一次读写就出现总线繁忙,就对I2C模块进行复位;

如果不是第一次,且I2C总线上只有一主,则等待一定时间(5ms);

如果是多主,则返回,等待总线空闲吧。

问题13:

CPU写数据给EEPROM时,如果设置断点,就能成功写入数据,但没有断点,数据写不成功。

什么原因呀?

原因:

写保护WP引脚的电平应在接收到停止信号后,应保持低电平一段时间才使能写保护,即加延时语句。

———已测试通过

//所有字节(地址字节+数据字节)都是添加写标志,即低电平,2n+2<=64//

//写EEPROM地址从0开始//

voidEEPROM_Write_call(Uint16address,Uint16n,Uint16s)

{

Uint16i,data_temp;

do{}while(EEPROM_Timer<=20);//20ms

//Checkifbusbusy

if(I2caRegs.I2CSTR.bit.BB!

=0)//总线忙位,不能手动清除

{

return;

}

if(WP!

=0)WP=0;//清除从机EEPROM写保护模式

//Setupslaveaddress-7bit

I2caRegs.I2CSAR=0x50;

I2caRegs.I2CCNT=(n<<1)+2;//Setupnumberofbytestosend

//setupwritemode

I2caRegs.I2CMDR.all=0x6E20;//Sendstartasmastertransmitter

//发起始信号

//主机发送停止信号

//TXmode

if(I2caRegs.I2CSTR.bit.NACK!

=0)return;

//存储器首地址——2字节(14bit)

while(I2caRegs.I2CSTR.bit.XRDY!

=1);

I2caRegs.I2CDXR=(address>>8);

if(I2caRegs.I2CSTR.bit.NACK!

=0)return;

while(I2caRegs.I2CSTR.bit.XRDY!

=1);

I2caRegs.I2CDXR=(address&0x00FF);

if(I2caRegs.I2CSTR.bit.NACK!

=0)return;

//Setupdatatosend

for(i=0;i

{

data_temp=MK_Data[s+i];

while(I2caRegs.I2CSTR.bit.XRDY!

=1);

I2caRegs.I2CDXR=(data_temp&0x00FF);

if(I2caRegs.I2CSTR.bit.NACK!

=0)return;

while(I2caRegs.I2CSTR.bit.XRDY!

=1);

I2caRegs.I2CDXR=data_temp>>8;

if(I2caRegs.I2CSTR.bit.NACK!

=0)return;

}

do{}while(I2caRegs.I2CSTR.bit.SCD!

=1);//是否有停止信号

WP=1;//保护EEPROM,使其只读

EEPROM_Timer=0;

}

问题14:

波形错误——用I2C接口,SCK和SDA都接有4.7K的上拉电阻,用示波器抓SCK和SDA的波形,发现SCK时序正常,SDA异常,见附图(黄为SCK,紫为SDA),请问这个锯齿波形大概是什么原因造成的呢?

——by

猜测原因:

可能是I2C模块时钟频率设置不合理;——未验证

IIC中断作用:

IIC中断和UART中断一样,你可以立刻得到数据,而不需要总是查询。

IIC接收数据只是存到指定的寄存器中,如果你不取走,下次再接收数据就直接冲掉了,所以IIC接收到数据之后给CPU中断,去处理这些收到的数据!

查找中断源是一种保险的做法,要是由于其他的哪几种原因产生了中断,但是此时数据并没有接收完,中断服务子程序去处理数据了,结果就不对了!

如果你自己敢保证不会出现哪几种情况就可以完全不用写!

——by

//I2C(接收)

interruptvoidi2c_int1a_isr(void)//I2C-A

{

Uint16IntSource;//Readinterruptsource

switch(IntSource)

{

caseI2C_NO_ISRC:

break;//=0

caseI2C_ARB_ISRC:

break;//=1

caseI2C_NACK_ISRC:

break;//=2

caseI2C_ARDY_ISRC:

break;//=3

caseI2C_RX_ISRC:

//=4

InData[I2cIndex++]=I2caRegs.I2CDRR;break;

caseI2C_TX_ISRC:

break;//=5

caseI2C_SCD_ISRC:

break;//=6

caseI2C_AAS_ISRC:

break;//=7

default:

//asm("ESTOP0");//Haltoninvalidnumber.asm("RPT#5||NOP");

}//EnablefutureI2C(PIEGroup8)interrupts

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2