这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » [讨论]Flash操作问题(老站转)

共1条 1/1 1 跳转至

[讨论]Flash操作问题(老站转)

菜鸟
2002-05-16 21:36:56     打赏
转自老论坛:Flash操作问题 gao 于 2002/04/15 15:49 加贴在 嵌入式系统论坛 设为精华 删除 aqian 高级工程师 来自: 发表总数:113   查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 我用C32对flash进行读写,发现如果向Flash中的地址为Addr的单元写一个数,地址为4000+Addr的单元也会被写入相同的数,还有8000+Addr这个单元也是这种情况,我觉的好生奇怪,请问这可能是什么问题?以前碰到过地址短路的问题,那也大不了出现多个地址对应一个单元的现象,可现在却是多个单元对应一个地址,真是想不明白! 我的Flash是AMD29F400B,AMD公司的,如果大侠用过的话,请看看我的程序有什么问题: /*Write a word-data to the address-specified memory cell*/ unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-22 - 19:45:47 IP: 211.97.*.* amine 版主 来自: 发表总数:517 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我觉得还是地址线短路问题, 按你所说, 应该有两根地址线短路, 导致有3个存储单元对应一个地址 如果推测没错的话, 应该是A14, A15短路拉. Hope this help! -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 14:19:44 IP: 210.53.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 在16KB的位置重复出现同一个东东,前面14根地址线应该没有问题。不知道你是如何确定3个单元的内容相同的?是用别的读写设备还是你的程序运行的那块板子?一般来说,即使地址线短路,对于Flash来说一次写入的东东应该是在一个地方而不是多个地方,但是读取的时候则会从多个地址读出同一个东东。确认一下到底是同时写入了多个地址(?)还是读出的时候由于地址线短路导致高端地址重叠? -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 16:43:16 IP: 211.162.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 我用的Ti的CCS软件调C32的,存储器的内容是可以在线看的,通过JTAG口仿真的;我看到3个内容同时变的!地址我是从0写道0xFF,都是这样!怪!会不会是Flash有问题?我还块板子看看(这次只作了3块板子),地址线我都测过了,没有出现粘的现象,这点不用怀疑了;别的什么原因我也想不到,没法下手 -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 18:19:36 IP: 61.156.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 怪哉,用编程器读读看,再确认一下; 用编程器写一写同样的片子,看看是不是会出现同样的现象。 -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 19:20:12 IP: 211.162.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 你的表述太不清楚,让人理解起来很费力。 对于你说:“我还块板子看看(这次只作了3块板子),地址线我都测过了,没有出现粘的现象,这点不用怀疑了”,到底所指哪块板子? 1。通常我们使用了很多AMD公司的该型号flash,像这种大规模生产的东西出问题几率很少。 2。你所说的情况由短路和虚焊引起的可能性是很大的,特别是读,这是手工焊接不可避免的。你可以查查读写门的打开情况。 3。数据不要太对称,55AA虽然用来检测,但要灵活多变。 4。存储器看到的已经不是正确的了,即存储器里的值!=寄存器里的值。 仅供参考。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 13:03:01 IP: 202.108.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1.你先将flash擦除一下,再向其中写数据。 2.写入数据后要查询一下DQ7,1时完成,0是忙,只有当DQ7为1时才继续下面的写操作。 3.你检查一下你的地址线和有没有和地短上 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 13:53:38 IP: 202.200.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 不好意思,不好意思,由于出现这种怪问题我有点着急,表达起来有点语不达意,各位热心朋友请多多包涵,现在我把问题重新整理一遍如下: 1)我用的这块芯片是AMD公司的Am29F400B,它的容量是4Megabit(4兆位),它可以配置位16位和8位的存储器,这个由管脚BYTE#的电平来决定,我把这个脚拉成高电平以配置16位;两块Am29F400B并起来构成一个32位的Flash,地址线和控制线和C32的链接完全一样,数据线分别接到C32的高16位和低16位上; 2)快板子的地址线没有出现任何短接现象,这个经过测试的;另外我们采用的是贴片机焊接的,一般不会出现虚焊的现象; 3)我对Flash的操作均流程是这样的: a.先插除整个芯片(通过调用函数Erase_WholeChip()来完成的) /*Erase all cells in the whole chip */ unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; *ptr =0x0; /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i0x1FFFF){ i=0; } Flag &= Write_SingleWord_Flash((unsigned int*)i,i); i++; } 发现向地址为i的单元里写数据(由程序可以知道这个数据就是i)的时候,地址为(0x4000+i)、(0x8000+i)、(0xC000+i)的单元也同时被写了数据i;在写到0x4000以前,写函数Write_SingleWord_Flash()返回来的值都是True,写到0x4000的时候就发现返回来的值就不对了,是False;同样,我向地址为i、(0x4000+i)、(0x8000+i)、(0xC000+i)的四个单元中的任何一个单元中写数据的时候,另外3个都发生同样的变化(插除之后)!写的数据完全是随机的,不存在对称不对称的问题; 4)我们公司以前用过Amd公司的flash芯片,不过和这次用的flash芯片的封装不一样,以前的flash没有出现这种情况,我希望这次出现的现象与Amd公司没有关系,否则它们就麻烦罗,呵呵;另外我们开发部以前的工程师都觉得这个现象简直不可思议,呵呵:)顺便说一句,这几片flash都是我们申请的样片,呵呵; -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 18:59:26 IP: 211.97.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 用你的程序写完之后有没有用编程器读出来看一下?AMD的这个片子好像没有BGA封装的,拆起来应该不太困难,试试看先^_^ 不过从你的描述来看,似乎确实是同时写到不同的位置去了,奇怪。 -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 19:13:59 IP: 211.162.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1. unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} 单步执行,停止到这一句试试 RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } 2. unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; 去掉试试 *ptr =0x0; 去掉试试 /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i if(*(ptr+i)==(unsigned int)0xFFFFFFFF) i++; } return(True); } 3.你可以向地址0x10000中写数据看看有没有类似情况。 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 21:15:12 IP: 202.200.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 1. unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} 单步执行,停止到这一句试试 执行到这里问题就出现了 RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } 2. unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; 去掉试试 这两句是为了在flash处于低功耗模式的唤醒它用的, *ptr =0x0; 去掉试试 去掉也可以,不过现象任然存在! /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i if(*(ptr+i)==(unsigned int)0xFFFFFFFF) i++; } return(True); } 3.你可以向地址0x10000中写数据看看有没有类似情况。 有类似的情况发生,即10000h+i、14000h+i、18000h+i、1c000h+i同时被写入数据; Edited by - aqian 重新编辑於 2002-03-26 08:36:05 -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 08:31:45 IP: 211.97.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1。在擦除和写操作命令后加入同步指令,关掉cache。 2。按照zhangsifu所说的加入测试状态位DQ7的指令。 3。用随机数测试,不要对称的测试,看是否有规律。 4。检查设计,看是否读写门同时打开。 5。确认分区大小。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 09:24:40 IP: 202.108.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我重新看了一下你描述的设计,感觉你的命令序列有问题。 data sheet上的设计不能照搬,因为那是一个片子的情况。 你可以将其仔细考虑,对于该片子,A0,A14最重要,由于你的用两块,所以A15也重要,你仔细考虑一下吧! -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 09:51:01 IP: 202.108.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 你现在可以只对一个flash进行操作,看看是不是和同时操作两个flash有关。 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 11:47:08 IP: 202.200.*.* tinyfish 助理工程师 来自: 发表总数:5 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我做过这个片子的驱动,但没有碰到过这样的问题 看完你的代码觉得有些地方处理得不是很妥当 1. 写之前或者写之后最好加上0xF0这样的reset指令 2. 写/擦完成的判断最好用DQ6/7,不要用时间来定时,因为时间并不精确,我印象中看到的AMD的文档上写的时间都是一个不确定数,单位是ms,差别极大 try it! 不过对于这个问题,我感觉硬件上的原因相当大 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 13:51:26 IP: 61.48.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 99%的可能是软件问题,我认为。 对于tinyfish,你所说的只是编程应该注意的,实际上你们都没认真理解。可以再仔细看看手册上的注意事项。尤其是Note4。 不过这应该是BSP或硬件工程师应该给你说清楚的。 你调试完可以告诉大家结果。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 14:52:16 IP: 202.108.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 谢谢大家的热情帮助!!! 现在问题是解决了,可是什么那个原因还是说服不了我!是这样子的,我的DSP的A15,A14,A13这3跟地址线引到altera公司的PLD芯片7128上参与逻辑编码,后来由于A15没有派上用场就悬空在那里,后来我们把它接到一个非门上去了,一切操作都正常了!表面上,可能由于PLD的悬空脚的电平不稳定导致这个结果,但是细究起来还是不明白为什么会出现这个原因! tinyfish,我想请教一个问题,就是写一个字时使用循环等待好还是用查询状态位的办法好呢?我觉得使用固定循环可能会浪费时间(我的CPU是DSP芯片,时间最宝贵了),但是查询我觉得挺麻烦,因为我那部分的说明没看明白就写程序了:),你给我提个意见吧;还有就是你说的:写之前或者写之后最好加上0xF0这样的reset指令,不知是真假延时还是有什么别的用处,请提示; -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 18:36:10 IP: 211.97.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 感觉还是有问题,当然,我没看过你们的硬件连线图,只是妄加揣测. 你将整个两片flash都检查过了么?1000,2000,3000这些地址都试过了? 我去下了一个新版的数据手册,发现新版上应该是Note5,而不是Note4. 直觉是由于恰好有一个非的关系,所以硬件上能这样蒙对,但你可以试试软件上修改. `可是什么那个原因还是说服不了我!`这句话真有意思,哈哈哈 仅供参考. -------------------------------------------------------------------------------- 编辑 发表於:2002-03-30 - 02:08:57 IP: 61.171.*.* tinyfish 助理工程师 来自: 发表总数:5 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- > 写一个字时使用循环等待好还是用查询状态位的办法好呢? 查询状态位时肯定要占用系统BUS,个人认为:最好的办法是循环等待加查询状态位, 也就是查询一次状态位后若不成功就固定等待一定时间(比如10us等),这样循环 的时候让出BUS给其他HW使用 > 我觉得使用固定循环可能会浪费时间(我的CPU是DSP芯片,时间最宝贵了), > 但是查询我觉得挺麻烦,因为我那部分的说明没看明白就写程序了:), 对,由于FLASH操作时间很长,所以对于时间的分配使用是RealTime系统的关键 我也没什么好的办法,一直都是用的查询状态位来做的 再说写一个WORD的时间也不长啊,好象才10-20us,能够忍受 不过如果你使用的OS支持比较好的调度情况,可以使用系统函数来调度其他TASK来跑 > 写之前或者写之后最好加上0xF0这样的reset指令, 印象中有些FLASH要求READ之前需要写入0XF0这样的RESET指令, 否则读操作会不太正常或者出现莫名其妙的问题,所以建议加上这个 > 不知是真假延时还是有什么别的用处 真假延时?啥意思?跟0XF0有关系吗? -------------------------------------------------------------------------------- 编辑 发表於:2002-04-01 - 13:14:28 IP: 61.48.*.* amine 版主 来自: 发表总数:517 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- > >写之前或者写之后最好加上0xF0这样的reset指令, >印象中有些FLASH要求READ之前需要写入0XF0这样的RESET指令, >否则读操作会不太正常或者出现莫名其妙的问题,所以建议加上这个 在Flash内部有个微代码的状态机, 驱动Flash在各个状态之间转换 如read-write-erase-timeout 在write,erase状态的执行过程中不会响应读,复位等命令. 在上电时, flash缺省处于读状态, 可以读而不用复位, 当出现D5_timeout时, flash处于`超时`状态, 不会响应`复位`以外的其他命令, 这时就必须使用`复位`, 才能对flash继续操作, 否则出现Flash死锁, 出现D5_timeout的主要原因: 向未擦除字节写入, 也就是想将0位写为1 -------------------------------------------------------------------------------- 编辑 发表於:2002-04-02 - 04:04:59 aqian 高级工程师 来自: 发表总数:113   查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 我用C32对flash进行读写,发现如果向Flash中的地址为Addr的单元写一个数,地址为4000+Addr的单元也会被写入相同的数,还有8000+Addr这个单元也是这种情况,我觉的好生奇怪,请问这可能是什么问题?以前碰到过地址短路的问题,那也大不了出现多个地址对应一个单元的现象,可现在却是多个单元对应一个地址,真是想不明白! 我的Flash是AMD29F400B,AMD公司的,如果大侠用过的话,请看看我的程序有什么问题: /*Write a word-data to the address-specified memory cell*/ unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-22 - 19:45:47 IP: 211.97.*.* amine 版主 来自: 发表总数:517 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我觉得还是地址线短路问题, 按你所说, 应该有两根地址线短路, 导致有3个存储单元对应一个地址 如果推测没错的话, 应该是A14, A15短路拉. Hope this help! -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 14:19:44 IP: 210.53.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 在16KB的位置重复出现同一个东东,前面14根地址线应该没有问题。不知道你是如何确定3个单元的内容相同的?是用别的读写设备还是你的程序运行的那块板子?一般来说,即使地址线短路,对于Flash来说一次写入的东东应该是在一个地方而不是多个地方,但是读取的时候则会从多个地址读出同一个东东。确认一下到底是同时写入了多个地址(?)还是读出的时候由于地址线短路导致高端地址重叠? -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 16:43:16 IP: 211.162.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 我用的Ti的CCS软件调C32的,存储器的内容是可以在线看的,通过JTAG口仿真的;我看到3个内容同时变的!地址我是从0写道0xFF,都是这样!怪!会不会是Flash有问题?我还块板子看看(这次只作了3块板子),地址线我都测过了,没有出现粘的现象,这点不用怀疑了;别的什么原因我也想不到,没法下手 -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 18:19:36 IP: 61.156.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 怪哉,用编程器读读看,再确认一下; 用编程器写一写同样的片子,看看是不是会出现同样的现象。 -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-24 - 19:20:12 IP: 211.162.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 你的表述太不清楚,让人理解起来很费力。 对于你说:“我还块板子看看(这次只作了3块板子),地址线我都测过了,没有出现粘的现象,这点不用怀疑了”,到底所指哪块板子? 1。通常我们使用了很多AMD公司的该型号flash,像这种大规模生产的东西出问题几率很少。 2。你所说的情况由短路和虚焊引起的可能性是很大的,特别是读,这是手工焊接不可避免的。你可以查查读写门的打开情况。 3。数据不要太对称,55AA虽然用来检测,但要灵活多变。 4。存储器看到的已经不是正确的了,即存储器里的值!=寄存器里的值。 仅供参考。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 13:03:01 IP: 202.108.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1.你先将flash擦除一下,再向其中写数据。 2.写入数据后要查询一下DQ7,1时完成,0是忙,只有当DQ7为1时才继续下面的写操作。 3.你检查一下你的地址线和有没有和地短上 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 13:53:38 IP: 202.200.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 不好意思,不好意思,由于出现这种怪问题我有点着急,表达起来有点语不达意,各位热心朋友请多多包涵,现在我把问题重新整理一遍如下: 1)我用的这块芯片是AMD公司的Am29F400B,它的容量是4Megabit(4兆位),它可以配置位16位和8位的存储器,这个由管脚BYTE#的电平来决定,我把这个脚拉成高电平以配置16位;两块Am29F400B并起来构成一个32位的Flash,地址线和控制线和C32的链接完全一样,数据线分别接到C32的高16位和低16位上; 2)快板子的地址线没有出现任何短接现象,这个经过测试的;另外我们采用的是贴片机焊接的,一般不会出现虚焊的现象; 3)我对Flash的操作均流程是这样的: a.先插除整个芯片(通过调用函数Erase_WholeChip()来完成的) /*Erase all cells in the whole chip */ unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; *ptr =0x0; /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i0x1FFFF){ i=0; } Flag &= Write_SingleWord_Flash((unsigned int*)i,i); i++; } 发现向地址为i的单元里写数据(由程序可以知道这个数据就是i)的时候,地址为(0x4000+i)、(0x8000+i)、(0xC000+i)的单元也同时被写了数据i;在写到0x4000以前,写函数Write_SingleWord_Flash()返回来的值都是True,写到0x4000的时候就发现返回来的值就不对了,是False;同样,我向地址为i、(0x4000+i)、(0x8000+i)、(0xC000+i)的四个单元中的任何一个单元中写数据的时候,另外3个都发生同样的变化(插除之后)!写的数据完全是随机的,不存在对称不对称的问题; 4)我们公司以前用过Amd公司的flash芯片,不过和这次用的flash芯片的封装不一样,以前的flash没有出现这种情况,我希望这次出现的现象与Amd公司没有关系,否则它们就麻烦罗,呵呵;另外我们开发部以前的工程师都觉得这个现象简直不可思议,呵呵:)顺便说一句,这几片flash都是我们申请的样片,呵呵; -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 18:59:26 IP: 211.97.*.* 老猫 工程师 来自: 发表总数:28 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 用你的程序写完之后有没有用编程器读出来看一下?AMD的这个片子好像没有BGA封装的,拆起来应该不太困难,试试看先^_^ 不过从你的描述来看,似乎确实是同时写到不同的位置去了,奇怪。 -------------------------------- 猫眼看天,仅供参考 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 19:13:59 IP: 211.162.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1. unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} 单步执行,停止到这一句试试 RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } 2. unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; 去掉试试 *ptr =0x0; 去掉试试 /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i if(*(ptr+i)==(unsigned int)0xFFFFFFFF) i++; } return(True); } 3.你可以向地址0x10000中写数据看看有没有类似情况。 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-25 - 21:15:12 IP: 202.200.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 1. unsigned int Write_SingleWord_Flash(unsigned int *DestAddr,unsigned int Data) { unsigned int *ptr,i,j,RdData; ptr=(unsigned int *)FlashBaseAddr; /*Write program command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0xA000A0; /*Write the data to the selected memory cell*/ *DestAddr = Data; /*Verify the data writen to flash be right or not*/ for(i=0,j=0;i<50;i++){ j++;} 单步执行,停止到这一句试试 执行到这里问题就出现了 RdData = *DestAddr; if(RdData == Data){ return(True); }else{ return(False); } } 2. unsigned int Erase_WholeChip(void) { unsigned int *ptr,i; ptr=(unsigned int *)FlashBaseAddr; /*Write tow unlock cycles*/ *ptr =0x0; 去掉试试 这两句是为了在flash处于低功耗模式的唤醒它用的, *ptr =0x0; 去掉试试 去掉也可以,不过现象任然存在! /*Write whole chip erase command sequenc*/ *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x800080; *(ptr+0x555) =0xAA00AA; *(ptr+0x2AA) =0x550055; *(ptr+0x555) =0x100010; /*Verify erasing operation be right or not*/ for(i=0;i if(*(ptr+i)==(unsigned int)0xFFFFFFFF) i++; } return(True); } 3.你可以向地址0x10000中写数据看看有没有类似情况。 有类似的情况发生,即10000h+i、14000h+i、18000h+i、1c000h+i同时被写入数据; Edited by - aqian 重新编辑於 2002-03-26 08:36:05 -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 08:31:45 IP: 211.97.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 1。在擦除和写操作命令后加入同步指令,关掉cache。 2。按照zhangsifu所说的加入测试状态位DQ7的指令。 3。用随机数测试,不要对称的测试,看是否有规律。 4。检查设计,看是否读写门同时打开。 5。确认分区大小。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 09:24:40 IP: 202.108.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我重新看了一下你描述的设计,感觉你的命令序列有问题。 data sheet上的设计不能照搬,因为那是一个片子的情况。 你可以将其仔细考虑,对于该片子,A0,A14最重要,由于你的用两块,所以A15也重要,你仔细考虑一下吧! -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 09:51:01 IP: 202.108.*.* zhangsifu 工程师 来自: 发表总数:39 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 你现在可以只对一个flash进行操作,看看是不是和同时操作两个flash有关。 -------------------------------- EMBEDDED -------------------------------------------------------------------------------- 编辑 发表於:2002-03-26 - 11:47:08 IP: 202.200.*.* tinyfish 助理工程师 来自: 发表总数:5 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 我做过这个片子的驱动,但没有碰到过这样的问题 看完你的代码觉得有些地方处理得不是很妥当 1. 写之前或者写之后最好加上0xF0这样的reset指令 2. 写/擦完成的判断最好用DQ6/7,不要用时间来定时,因为时间并不精确,我印象中看到的AMD的文档上写的时间都是一个不确定数,单位是ms,差别极大 try it! 不过对于这个问题,我感觉硬件上的原因相当大 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 13:51:26 IP: 61.48.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 99%的可能是软件问题,我认为。 对于tinyfish,你所说的只是编程应该注意的,实际上你们都没认真理解。可以再仔细看看手册上的注意事项。尤其是Note4。 不过这应该是BSP或硬件工程师应该给你说清楚的。 你调试完可以告诉大家结果。 -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 14:52:16 IP: 202.108.*.* aqian 高级工程师 来自: 发表总数:113 查看   短消息   电子邮件   个人主页   引用   回复 -------------------------------------------------------------------------------- 谢谢大家的热情帮助!!! 现在问题是解决了,可是什么那个原因还是说服不了我!是这样子的,我的DSP的A15,A14,A13这3跟地址线引到altera公司的PLD芯片7128上参与逻辑编码,后来由于A15没有派上用场就悬空在那里,后来我们把它接到一个非门上去了,一切操作都正常了!表面上,可能由于PLD的悬空脚的电平不稳定导致这个结果,但是细究起来还是不明白为什么会出现这个原因! tinyfish,我想请教一个问题,就是写一个字时使用循环等待好还是用查询状态位的办法好呢?我觉得使用固定循环可能会浪费时间(我的CPU是DSP芯片,时间最宝贵了),但是查询我觉得挺麻烦,因为我那部分的说明没看明白就写程序了:),你给我提个意见吧;还有就是你说的:写之前或者写之后最好加上0xF0这样的reset指令,不知是真假延时还是有什么别的用处,请提示; -------------------------------- 天外有天 -没错 山外有山 -没问题 我外有你 -Certainly 你中有我 -哇塞,怎么可能哦? -------------------------------------------------------------------------------- 编辑 发表於:2002-03-29 - 18:36:10 IP: 211.97.*.* wl 工程师 来自: 发表总数:15 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- 感觉还是有问题,当然,我没看过你们的硬件连线图,只是妄加揣测. 你将整个两片flash都检查过了么?1000,2000,3000这些地址都试过了? 我去下了一个新版的数据手册,发现新版上应该是Note5,而不是Note4. 直觉是由于恰好有一个非的关系,所以硬件上能这样蒙对,但你可以试试软件上修改. `可是什么那个原因还是说服不了我!`这句话真有意思,哈哈哈 仅供参考. -------------------------------------------------------------------------------- 编辑 发表於:2002-03-30 - 02:08:57 IP: 61.171.*.* tinyfish 助理工程师 来自: 发表总数:5 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- > 写一个字时使用循环等待好还是用查询状态位的办法好呢? 查询状态位时肯定要占用系统BUS,个人认为:最好的办法是循环等待加查询状态位, 也就是查询一次状态位后若不成功就固定等待一定时间(比如10us等),这样循环 的时候让出BUS给其他HW使用 > 我觉得使用固定循环可能会浪费时间(我的CPU是DSP芯片,时间最宝贵了), > 但是查询我觉得挺麻烦,因为我那部分的说明没看明白就写程序了:), 对,由于FLASH操作时间很长,所以对于时间的分配使用是RealTime系统的关键 我也没什么好的办法,一直都是用的查询状态位来做的 再说写一个WORD的时间也不长啊,好象才10-20us,能够忍受 不过如果你使用的OS支持比较好的调度情况,可以使用系统函数来调度其他TASK来跑 > 写之前或者写之后最好加上0xF0这样的reset指令, 印象中有些FLASH要求READ之前需要写入0XF0这样的RESET指令, 否则读操作会不太正常或者出现莫名其妙的问题,所以建议加上这个 > 不知是真假延时还是有什么别的用处 真假延时?啥意思?跟0XF0有关系吗? -------------------------------------------------------------------------------- 编辑 发表於:2002-04-01 - 13:14:28 IP: 61.48.*.* amine 版主 来自: 发表总数:517 查看   短消息   电子邮件   引用   回复 -------------------------------------------------------------------------------- > >写之前或者写之后最好加上0xF0这样的reset指令, >印象中有些FLASH要求READ之前需要写入0XF0这样的RESET指令, >否则读操作会不太正常或者出现莫名其妙的问题,所以建议加上这个 在Flash内部有个微代码的状态机, 驱动Flash在各个状态之间转换 如read-write-erase-timeout 在write,erase状态的执行过程中不会响应读,复位等命令. 在上电时, flash缺省处于读状态, 可以读而不用复位, 当出现D5_timeout时, flash处于`超时`状态, 不会响应`复位`以外的其他命令, 这时就必须使用`复位`, 才能对flash继续操作, 否则出现Flash死锁, 出现D5_timeout的主要原因: 向未擦除字节写入, 也就是想将0位写为1 -------------------------------------------------------------------------------- 编辑 发表於:2002-04-02 - 04:04:59



关键词: 讨论     Flash     操作     问题     老站转     发表     ---    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]