为什么C8051芯片重新上电FLASH内容会变?
最近进行测试发现一个严重的问题,就是当我多个模块(大约10个)同时断电,再同时上电的时候,竟然有其中有一两个会无法再启动,把FLASH内容读出来,头512字节都是0XFF。请DX帮我解释一下这是怎么回事? 你用哪个型号的C8051F?是不是电压侦测功能没有打开?PS,我们已经全面把C8051F换下来了,这东东不行,会出很多想不到的问题,C8051F在我们公司的设计上已经被禁用了。 回复【1楼】z_zt米老鼠
-----------------------------------------------------------------------
我用的是310.
后来我把电压侦测功能打开,试过很多次通断电,到现在也没有再出现过问题。
只是想弄清楚为什么FLASH内容会自动擦除?这种情况还真没见过。 网上找的,转贴
---------------------------------
C8051Fxxx程序丢失问题的分析
2009-05-23 16:01:45 作者:xn123 来源:《单片机与嵌入式系统》2007.12期 浏览次数:0 网友评论 0 条
作者:湖南大学 胡益 苏娟 周海燕
1 c8051fxxx单片机简单介绍和flash结构
c8051fxxx系列器件是silicon labs推出的一个高速单片机系列。这款单片机是完全集成的混合信号片上系统型mcu 芯片。
具有高速、流水线结构的8051 兼容的cip51内核;70%的指令的执行时间为1个或2个系统时钟周期;片上有丰富的片内外设,根据型号的不同,包括adc、dac、uart、捕捉/比较模块的可编程计数器/定时器阵列、spi、smbus等。
c8051fxxx单片机有大容量的flash存储器,用于程序代码和非易失性数据存储,可在系统编程。flash的结构是以扇区为单位组织的 (128 kb系列以1 024字节为1个扇区,64 kb系列以512字节为1个扇区)。非易失性flash可以用来存储系统的参数,如软件版本、生产日期等。flash可以使用编程器擦写,也可以在程序中 使用movx指令来修改,从而使flash 存储器具有在系统重新编程能力,允许现场更新8051 固件程序。flash的写和擦除操作由硬件自动定时,以保证操作正确通过。c8051fxxx的flash保存下载的程序,在系统上电后,单片机从 flash读出代码数据到ram,之后程序开始运行。
2 程序丢失问题的出现和原因
在一些实际应用中,系统重新上电后会出现程序不能正常运行的问题,常表现为“程序丢失”。通常是由于程序代码被损坏或被修改造成的。
造成程序丢失问题的原因很多,可以归结到一个基本原因,即对flash的访问失败而造成flash保存的代码出现错误。对于所有包含有 flash写/擦除子程序的系统,当cpu工作在规定的vdd、温度、系统时钟频率范围之外时,对flash进行写/擦除操作,都有可能出现flash数 据错误的现象。
2.1 flash数据错误的硬件原因
c8051fxxx单片机的flash操作由硬件控制,所以硬件上的不稳定可能造成flash操作错误。硬件原因主要是能影响cpu正常运行的因素,以及能影响flash操作环境的因素。这些因素包括操作电压、温度以及外部干扰脉冲等,具体如下:
① 能影响cpu运行可靠性的参数有系统时钟源。如果系统时钟由外部晶振提供,外部的电磁干扰引起尖脉冲,并耦合到系统时钟上,则会导致不可预知的操作。
② 系统在单片机的工作电压没有稳定(vdd上升时间低于规定的1 ms)时就已经完成复位,由于系统复位时需要从flash读出代码数据,flash电压不稳定会出现不可预测的错误。
③ 在对flash的操作过程中,如果温度、电压不稳定,也可能造成flash数据错误。
2.2 flash数据错误的软件原因
代码设计的缺陷是程序丢失的主要原因,因为单片机的flash是由硬件来控制的,不能由软件来控制操作的细节,所以程序的不完善可能造成 flash的访问出错,从而使flash数据出现错误。 这些操作包括: 在pswe位(psctl.0)置1时cpu执行中断服务程序中的movx写操作,该中断服务程序要使用xdata 或pdata 的易失性存储区单元,这样可能导致向xdata 或pdata存储区写的数据写到flash中了,从而出现问题。另外,如果使用外部晶振作系统时钟,在时钟没有稳定时就对flash进行写操作,也可能造 成程序丢失。
3 程序丢失问题的解决方法
针对以上可能的原因,可以从软硬件两个方面来解决程序丢失问题。在硬件方面,主要是给系统提供稳定的工作环境,并避免外部干扰对cpu运行环境的影响;在软件方面,主要是规范对flash的操作。
3.1 从硬件方面预防程序丢失
注意,以下的方法不是对所有的器件都适用,要根据具体的硬件情况选择相应的方法:
① 在rst引脚安装vdd监测电路,并将vdd监视设置为一个复位源(置rstsrc.1为1)。这样如果系统电压不稳定,系统将自动复位,从而避免在电压不稳时访问flash。
② 对外部晶振时钟2分频,更好的方法是使用内部振荡器,这样能提高系统时钟的抗干扰能力。
③ 如果使用外部晶振提供系统时钟,信号线应尽量靠近单片机的输入端,同时晶振外壳接地。
④ 对于使用外部晶振作时钟源的系统,应尽量增强晶振的驱动能力,这样也能在一定程度上预防程序丢失。
3.2 从软件方面预防程序丢失
程序丢失的主要原因是程序设计的缺陷,所以合理的程序代码设计能极大地预防该问题的出现。在代码中可以用多种方法来预防flash数据丢失:
① 在pswe=1下禁止中断,使得程序中的movx写指令是对flash而不是对xram。
② 在pswe=1下尽可能少地访问变量。在pswe=0下执行地址译码操作,并用间接寻址方式执行movx写操作。例如,向flash写多个字节,间接寻址和写pswe过程如下:
unsigned char xdata * idata pwrite;//使用idata指针指向flash
unsigned char *source;
unsigned char mydata;
for (addr = 0; addr <100; addr++) {
//pswe =0时获取要写入的数据
mydata = *source++;
//pswe =0时修改写入数据的目标地址
pwrite = (unsigned char xdata *) addr;
psctl = 0x01;//pswe=1
//赋值方式写入数据,此时不执行目标地址的修改操作
*pwrite = mydata;
psctl = 0x00;//pswe=0
}
以上代码中,当pswe = 1时只执行写flash操作(*pwrite = mydata);其他操作,如修改addr的值、获取源数据和目的地址,都是在pswe = 0时执行的。
③ 将flash写/擦除指针指向data或idata区。
④ 减少将pswe置1的指令操作。理想的情况是只有两个操作将pswe置1,即写1个flash字节和擦除1个flash字节。
⑤ 在flash写/擦除函数中,使能vdd监视并设置复位源。使能和设置操作必须在实际的写操作发生之前,置pswe=1之后完成。
⑥ 代码中所有的对rstsrc的写操作均用直接赋值方式完成(如rstsrc = 0x02),不能用读/写指令(如orl或anl)来完成。例如,代码“rstsrc |= 0x02”是非法的。
⑦ 对于能用porsf位来设置vdd为复位源的器件,保证在写rstsrc时置porsf=1,即先使能vdd为复位源,再使能其他复位源的操作,如时钟丢失监测(missing clock detector)、比较单元和软件复位。
4 一个实际应用方案
在有的应用场合,由于需要较快的执行速度,不能使用单片机的内部时钟作系统时钟源,所以使用外部晶振来提供时钟。在这种情况下,首先要在硬件上确保系统工作参数正常。
在软件上,由于最常见的flash丢失原因是程序问题,所以可以在代码中用多种方法来预防flash数据丢失。首先,在初始化单片机时,使能 vdd检测,并设置vdd和时钟丢失为复位源。如果程序中有写/擦除flash的代码,则在写/擦除操作前切换系统时钟,将系统时钟切到内部时钟或对外部 时钟2分频;写/擦除操作完成之后,再恢复系统时钟,通过增加flash修改操作时的时间开销来实现系统的稳定[2]。以下以c8051f126为例,给出了系统时钟切换的程序清单:
void sysclkadjust(unsigned char select) {
ea_save=ea;
sfrpage=0x0f;
switch(select) {
case 0x01:
oscicn_save = oscicn;
clksel_save = clksel;
oscicn = 0xc3;//内部时钟,不分频
clksel = 0x00;
break;
case 0x02:
oscxcn_save = oscxcn;
oscxcn |= 0x70;//外部时钟2分频
break;
default://选择内部时钟
oscicn_save = oscicn;
clksel_save = clksel;
oscicn = 0xc3;
clksel = 0x00;
break;
}
}
要恢复系统时钟到flash操作前的状态,只需将clksel_save、oscicn_save、oscxcn_save重新写回到clksel、oscin、oscxcn。
c8051f126的系统时钟(sysclk)可以在内部时钟和外部时钟之间自由切换,切换时的操作要求如下:
① 在切换过程中,先设置所选时钟的属性,再用clksel将其设置为sysclk。
② 在还原过程中,先用clksel选择时钟源,再设置其属性。
③ 如果切换过程中关闭外部晶振,要再恢复外部时钟,启动后至少要等1 ms,再去读xtlvld(oscxcn.7)来判断晶振时钟是否稳定。否则,可能读到错误值。
④ 在外部时钟稳定运行后,再对其分频,不必插入等待周期。
⑤ 在切换过程中,可以保持外部时钟继续运行,这样在还原过程中就不必等待外部时钟稳定,从而节省时间开销,代价是系统功耗有所增加。
5 总结
程序丢失会带来各种不良的后果,最严重时致使程序无法正常运行,从而造成整个系统崩溃,给产品的应用带来麻烦。在系统的硬件设计和代码编写过程 中,通过对以上问题的注意,可以有效地防止程序丢失问题的出现。另外,由于系统时钟的切换只发生在flash的写/擦除过程中,操作结束后又恢复成原来的 设置,因而对系统运行速度的影响很小,从而保证了系统其他功能的实现。 很可能是复位电路的问题.
如果能保证复位电路可靠,就没有丢flash的问题. 记号... 回复【1楼】z_zt 米老鼠
你用哪个型号的c8051f?是不是电压侦测功能没有打开?
ps,我们已经全面把c8051f换下来了,这东东不行,会出很多想不到的问题,c8051f在我们公司的设计上已经被禁用了。
-----------------------------------------------------------------------
个人觉得找出 问题才是关键, 当然在未能找到ROOTCAUSE 之前, 还是慎用! 这事我也遇到过
程序里面有写Flash的函数时尤其容易发生。 回复【3楼】xiaoking
-----------------------------------------------------------------------
非常感谢! mark 3楼说的flash烧写错误的现象吧?
楼主问的是上电数据丢失啊,FLASH应该是非易失存储器,不会上电丢失啊~~
能解释下什么原因么~~ 不太可能吧,俺从来不对FLASH进行操作。
不过俺只用过020和120,也只设计过二款产品,尚且没有发现问题。但是我对它编译器的效率深恶痛绝,于是干掉它。
现在ARM时代的片子,不比8位机贵了。 我还在用,复位就是最简单的一个电阻电容,几百个有了,貌似还不错,我用340和 500 很满意 之前遇到过,也是有一片莫名其妙的会丢失,并且丢失后无法用串口下载
检查下复位电路吧 mark mark一下 m ark 回复【13楼】floydcui
之前遇到过,也是有一片莫名其妙的会丢失,并且丢失后无法用串口下载
检查下复位电路吧
-----------------------------------------------------------------------
我用的复位电路和官方开发板是一样的,应该没有什么问题。
现在基本可以肯定是电压侦测功能没有打开导致的,自从打开以后到现在一个星期,每天都例行通断电数次,都没出现过问题。 MONEN最好直接接到VCC上,并且并联一个退耦电容,这个是推荐的做法,还有复位脚要有5K左右的强上拉才保险。 回复【17楼】cenkey
-----------------------------------------------------------------------
我记得好像是加了颗TPS3808解决的
好贵 mark! cenkey 发表于 2010-11-11 10:12 static/image/common/back.gif
回复【1楼】z_zt米老鼠
-----------------------------------------------------------------------
最近也遇到C8051上电无法运行,上电后按复位键也无法运行程序,
只有使用调试器重新烧写后,才能再次运行,但不不能断电。
在不断电情况下,怎么复位都能正常运行!不知你是如何解决的
谢谢! C8051也有这么多问题么?{:sweat:} 硬件问题,单片机电源要多加电容。 xiaoking 发表于 2010-11-11 10:16 static/image/common/back.gif
网上找的,转贴
---------------------------------
{:handshake:}学习c8051中正好有帮助! cenkey 发表于 2010-11-11 10:12
回复【1楼】z_zt米老鼠
-----------------------------------------------------------------------
再加一个复位芯片,就好一点了。还是换掉吧。
页:
[1]