在操作铁电存储器的过程中,发现一个BUG,那就是连续写入的时候,结果正确,单个写入的时候结果不正确,而且都是第一个正确,紧跟着的就不正确。后来怀疑是每个写的程序后面延时不够,但是不管延时长,均是一样的结果。开始怀疑铁电操作方面的原因,又重新看了几遍PDF,依然没有发现问题所在。经过周老师的指点,把分析的焦点重新放在读的程序上,试一试分开读,结果发现,分开单个读同样出现一样的问题,观察了一下两个程序的共同点,就是那个
Fram_WR_ready();,但是后来经周老师的质疑,从新看PDF,读的程序并不需要这个
Fram_WR_ready();(里面是WREN的打开)。
char
Dirc1[7]={0xCC,0xDD,0xFF,0xAA,0xBB,0x11,0xff};
char
read[7]={0};
Fram_write(2005,Dirc1,1);
Fram_write(2006,Dirc1+1,1);
Fram_write(2007,Dirc1+2,1);
Fram_write(2008,Dirc1+3,1);
Fram_write(2009,Dirc1+4,1);
Fram_write(2010,Dirc1+5,1);
Fram_write(2011,Dirc1+6,1);
Fram_read(2005,read,6);
大体找不到原因,我就分块来进行分析,我就把最原始的程序代码,直接拿出了,包括(地址的转换程序)也不要,直接用最原始的发地址代码:
UCB2TXBUF =0x00;
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF =0x07;
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF=0xD5;
while (!(UCB2IFG&UCTXIFG));
在最后发现,地址的这个地方有问题,再仔细一看,原来地址转换代码犯了一个低级错误,那就是(红字部分):
char *Fram_read(long ADDR,char *RBUFF,int DLETH)
{
FM_CS_0;//选中铁电
UCB2TXBUF = 0x03;//读取命令
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF =
(ADDR&0x00110000)>>16;//高位
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF
=(ADDR&0x00001100)>>8;
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF=(ADDR&0x00000011);
while
(!(UCB2IFG&UCTXIFG));
//发送时钟信号,读取内容
for(i=0;i
{
UCB2TXBUF=0x00;
while((UCB2STAT&UCBUSY)==1);//等SPI不忙
*RBUFF=dat;
RBUFF++;
}
//__delay_cycles(40000);
FM_CS_1;
//不选中铁电
__delay_cycles(2000);
return RBUFF;
}
我的本意是要与出 long的最后3个字节的地址,我大意将0x11当成八位的1111 1111 了,其实0x11 仅是0000
0011,所以与出来的地址并不是原来的地址2005
而是其他的地址,2006转换之后,不仅不是原来的地址,而且也不是紧随在2005后面,单个写入就出现了问题。 单个读取同样是。
经过更正,问题得以解决。
UCB2TXBUF =
(ADDR&0x00FF0000)>>16;//高位
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF
=(ADDR&0x0000FF00)>>8;
while
(!(UCB2IFG&UCTXIFG));
UCB2TXBUF=(ADDR&0x000000FF);
while
(!(UCB2IFG&UCTXIFG));
MARK:
教训就是:做事情千万大意不得,另外周老师的提点,让我关注问题的焦点更加的准确,也加快了问题解决的速度,所以合作和请教对进步有极大的帮助。
现象:
char Dirc1[7]={0xff,0xaa,0xee,0xcc,0x99,0x10};
Fram_write(2006,Dirc1,1);//将初始化的数据记录到铁电,&表示取地址
Fram_read(2006,read,3);//读取记录值,&表示取地址
结果:read={0xff,0xBB,0x66,00,00,00,00}
char Dirc1[7]={0xff,0xaa,0xee,0xcc,0x99,0x10};
Fram_write(2006,Dirc1,1);//将初始化的数据记录到铁电,&表示取地址
Fram_read(
2004,read,3);//读取记录值,&表示取地址
结果:read={0xff,0xBB,0x66,00,00,00,00}
char Dirc1[7]={0xff,0xaa,0xee,0xcc,0x99,0x10};
Fram_write(2006,Dirc1,1);//将初始化的数据记录到铁电,&表示取地址
Fram_read(
2005,read,3);//读取记录值,&表示取地址
结果:read={0xBB,0x66,0x88,00,00,00,00}
char Dirc1[7]={0xff,0xaa,0xee,0xcc,0x99,0x10};
Fram_write(2007,Dirc1,1);//将初始化的数据记录到铁电,&表示取地址
Fram_read(
2005,read,3);//读取记录值,&表示取地址
结果:read={0xff,0x66,0x88,00,00,00,00}
分析:第一个读的,存在里面的char 可能读丢了。以下分析又发现此分析不对。
char
Dirc1[7]={0xee,0xaa,0xff,0xcc,0x99,0x10};
char read[7]={0},read2[1]={0};
Fram_write(2005,Dirc1,6);//将初始化的数据记录到铁电,&表示取地址
Fram_read(2005,read,3);//读取记录值,&表示取地址
结果:read={0xee,0xaa,0xff,00,00,00,00}