打印

大家有没有遇到过PIC内部E2PROM失效啊?

[复制链接]
7138|37
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
程序匠人|  楼主 | 2008-9-1 23:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
兰天白云| | 2008-9-2 08:24 | 只看该作者

有被改写的经历,其他的没有

使用特权

评论回复
板凳
xieyuanbin| | 2008-9-2 10:04 | 只看该作者

有,记得有个家伙做寿命测试.

硬是把E2写坏了.
其他倒是没有,我甚至没碰到过被改写的.

使用特权

评论回复
地板
ijk| | 2008-9-2 10:17 | 只看该作者

做寿命测试

  做寿命测试,硬是把E2写坏了。是在高温下做的试验吗?如果在常温下测试,10ms一次,那要做好几天才到寿命

使用特权

评论回复
5
lanyong| | 2008-9-2 10:29 | 只看该作者

haha兄弟

匠人兄弟,前两天去书店看到你写的书了.哈哈.

不错不错,加油.

使用特权

评论回复
6
yewuyi| | 2008-9-2 12:46 | 只看该作者

嘿嘿,俺也没遇到PIC内部EEPROM出问题。。。

改写也没有。。。

使用特权

评论回复
7
ddb_21ic| | 2008-9-2 13:03 | 只看该作者

侠之大者,当为国为民

lz既是大侠,rp怎会如此
哈哈

使用特权

评论回复
8
jetson001| | 2008-9-2 15:50 | 只看该作者

的确

的确有这种情况
某些时候会写失败(无解)
所以Microchip提供的范例程序,内部EE都是写2次的

使用特权

评论回复
9
ddb_21ic| | 2008-9-2 16:50 | 只看该作者

我是没遇到过,不知道是不是J系列?

使用特权

评论回复
10
zidaozhou| | 2008-9-2 21:40 | 只看该作者

eeprom失效说明它阳寿尽了

eeprom失效说明它阳寿尽了

使用特权

评论回复
11
程序匠人|  楼主 | 2008-9-2 22:06 | 只看该作者

那,大家有没有遇到写E2P失败的情况?

比如,VDD电压波动,等因素,是否会导致写E2PROM失败?

------------------------------------------------
匠人那个旋转时钟,要连续写180个单元(一个一个地写,上一个写完毕后,再写下一个),但是,有几个单元总是写不进去。

匠人现在猜测的原因有:
1、E2PROM坏了
2、VDD电压波动导致写失败
3、程序BUG
4、人长得比较帅,招人妒忌了。

大家分析一下,是那个原因?

使用特权

评论回复
12
ddb_21ic| | 2008-9-2 22:55 | 只看该作者

4、人长得比较帅,招人妒忌了。

我有个877A的板板,7805供电,串口收到一个字节写一个,似乎没遇到过问题
看来我长得很丑啊,MCU都会可怜我了

使用特权

评论回复
13
dcp| | 2008-9-2 23:01 | 只看该作者

象是中断干扰了写动作

使用特权

评论回复
14
yewuyi| | 2008-9-3 08:43 | 只看该作者

就这样就成,没出什么问题

void                 WriteEE(void)
{
uchar    *p=&softwareVersion;
if(writeEE==false){WREN=0;}               //禁止内部EEPROM写操作
else{
    if(WR==ture){}
    else{
        if(fcase<=14){
                     EEADRL=fcase;        //赋EEPROM写入地址
                     EEDATL=*(p+fcase);   //赋EEPROM写入数值
                     EEPGD=0;             //指定访问内部EEPROM数据区
                     WREN=1;              //容许内部EEPROM写操作
                     GIE=false;           //发送写序列码前必须写禁止中断
                     EECON2=0x55;         
                     EECON2=0xaa;
                     WR=1;
                     GIE=ture;
                     fcase++;
                     }
        else{
            writeEE=false;
            }
        }
    }
}

使用特权

评论回复
15
xieyuanbin| | 2008-9-3 08:55 | 只看该作者

推断VDD波动可能性大一点.

或者有什么情况中断了写操作.对于连续写,一般都用循环操作,程序有BUG可能性不大,除非你有另外的中断会打断写操作,但这个中断一般在写EERPOM之前就关断了.我想你不会有这种错误.
你可分段,一次写10--60个,每个段之间隔一段时间试试.可以排除VDD和程序中断的问题.

使用特权

评论回复
16
yewuyi| | 2008-9-3 08:58 | 只看该作者

写数据的请求比较快,写的比较慢

如果没有写缓冲RAM,估计数据要被挤爆掉了把。。。

使用特权

评论回复
17
程序匠人|  楼主 | 2008-9-3 09:31 | 只看该作者

晒一下程序


说明,主程序中先判断上次写操作是否完成,如果完成了则调用“更新eeprom内容”程序。
在“更新eeprom内容”程序中,每次只操作一个单元。先把要修改的单元读出来校验,如果读出数据与待写入数据一致,则切换到下一单元。如果连续N次不一致,代表该单元写失败,跳过。
在执行写操作时,中断已经关闭了。
相关程序如下:
 
 
//--------------------------------------------------------
//主函数
//--------------------------------------------------------
void main(void)
{
    init();                        //====初始化

    //====循环主体
    while (1)
    {
        //......略        
        if ( (EEPROM_NEW_FLAGS!=0) && (WR==0) && (NO_KEY_JSQ>2) ) new_eeprom() ;    //如果EEPROM数据更新标志<>0,且上次的写操作结束,且无按键计数器>2,则更新eeprom内容

    }
}



//--------------------------------------------------------
//更新eeprom内容
//--------------------------------------------------------
void new_eeprom ( void )
{
    //====显示列计数器 角度校正值(0~179) (用于校正盘面角度)
    if ( DISP_LINE_ADJ_FLAG )        
    {
        //......略
    }

        //......略

    //====自定义点阵图片
    else if ( PICTURE_FLAG )
    {
        if ( EEP_SAVE_ID <= 90 )        
        //保存自定义点阵图片上部
        {
            //读出校验
            EEADR = PICTURE1_ADR + EEP_SAVE_ID ;    //地址
            read_eeprom() ;                //EEPROM字节读程序
                    
            if ( EEDATA == DISP_QUEUE1[EEP_SAVE_ID] ) //如果校验一致
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                EEP_SAVE_ID ++ ;            //EEPROM存储指针+1    
            } 
            else if ( ++EEPROM_ERR_JSQ > 3 )    //如果连续n次写入失败
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                EEPROM_ERR_FLAG = 1 ;                      //EPPROM写失败标志=1
                EEP_SAVE_ID ++ ;            //EEPROM存储指针+1    
            }
            else                    //否则,更新数据
            {            
                EEDATA = DISP_QUEUE1[EEP_SAVE_ID] ;    //数据
                write_eeprom() ;            //EEPROM字节写程序
            }
        }
        if ( EEP_SAVE_ID <= 180 )        
        //保存自定义点阵图片下部
        {
            //读出校验
            EEADR = PICTURE2_ADR + EEP_SAVE_ID - 90 ; //地址
            read_eeprom() ;                //EEPROM字节读程序
                    
            if ( EEDATA == DISP_QUEUE2[EEP_SAVE_ID - 90] ) //如果校验一致
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                EEP_SAVE_ID ++ ;            //EEPROM存储指针+1    
            } 
            else if ( ++EEPROM_ERR_JSQ > 3 )    //如果连续n次写入失败
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                EEPROM_ERR_FLAG = 1 ;                      //EPPROM写失败标志=1
                EEP_SAVE_ID ++ ;            //EEPROM存储指针+1    
            }
            else                    //否则,更新数据
            {            
                EEDATA = DISP_QUEUE2[EEP_SAVE_ID - 90] ; //数据
                write_eeprom() ;            //EEPROM字节写程序
            }
        }
        else
        //保存自定义点阵图片有效标志(0X5A=有效,否则=无效)
        {
            //读出校验
            EEADR = PICTURE_EN_ADR ;        //地址
            read_eeprom() ;                //EEPROM字节读程序
                    
            if ( EEDATA == 0X5A ) //如果校验一致
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                PICTURE_FLAG = 0 ;            //自定义点阵图片更新标志=0    
                EEP_SAVE_ID = 0 ;            //EEPROM存储指针=0    
            } 
            else if ( ++EEPROM_ERR_JSQ > 3 )    //如果连续n次写入失败
            {
                EEPROM_ERR_JSQ = 0 ;            //EPPROM写失败计数器=0
                EEPROM_ERR_FLAG = 1 ;                      //EPPROM写失败标志=1
                PICTURE_FLAG = 0 ;            //自定义点阵图片更新标志=0    
                EEP_SAVE_ID = 0 ;            //EEPROM存储指针=0    
            }
            else                    //否则,更新数据
            {            
                EEDATA = 0X5A ;                //数据
                write_eeprom() ;            //EEPROM字节写程序
            }            
        }
    }    

    //====异常处理
    else
    {
        EEPROM_NEW_FLAGS = 0 ;            //EEPROM数据更新标志=0
    }
}

//--------------------------------------------------------
//EEPROM字节写程序
//功能:    写一个字节到内部EEPROM
//入口:    EEADR    =地址
//    EEDATA    =数据
//--------------------------------------------------------
void write_eeprom ( void )
{
    EEPGD = 0 ;                     //设置访问目标为EEPROM
    WREN = 1 ;                    //允许进行写操作
    GIE = 0 ;                       //禁止中断
    EECON2 = 0x55 ;
    EECON2 = 0xAA ;
    WR = 1 ;                        //启动一次写操作
    GIE = 1 ;                       //使能中断
    WREN = 0 ;                    //关闭写操作
}

//--------------------------------------------------------
//EEPROM字节读程序
//功能:    从内部EEPROM读一个字节
//入口:    EEADR    =地址
//出口:    EEDATA    =数据
//--------------------------------------------------------
void read_eeprom( void )
{
    EEPGD = 0 ;                     //设置访问目标为EEPROM
    RD = 1 ;                       //启动一次读操作
}

使用特权

评论回复
18
程序匠人|  楼主 | 2008-9-3 10:08 | 只看该作者

回16楼 yewuyi

 yewuyi 发表于 2008-9-3 08:58 PIC 单片机 ←返回版面    

16楼: 写数据的请求比较快,写的比较慢 

如果没有写缓冲RAM,估计数据要被挤爆掉了把。。。
 
 
---------------------------------
回:有缓冲区DISP_QUEUE1[],和DISP_QUEUE2[],两个数组,共180个单元。不会被挤爆

使用特权

评论回复
19
程序匠人|  楼主 | 2008-9-4 00:09 | 只看该作者

换了一颗芯片,那几个对应的单元好像可以写进去


目前看来,VDD不稳定导致写失效的可能性极大。
 
(顺便秀一下图片):
 

使用特权

评论回复
20
xieyuanbin| | 2008-9-4 08:40 | 只看该作者

问一下匠人电源如何得来?

貌似周期性失败?
不知道你校验失败后如何处理?重写还是跳过?没看到你重写的程序.只写一次遇到写失败的可能性比较大.我一般的处理是写-校验-错-重写-校验-错-报错.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

734

主题

11156

帖子

675

粉丝