搜索
bottom↓
回复: 4

为什么写EEPROM老是错误呢?

[复制链接]

出0入0汤圆

发表于 2007-9-11 16:54:47 | 显示全部楼层 |阅读模式
1、系统中有定时中断1、USART0接收中断、USART0发送中断
2、当USART0接收到上位机的“预置单个寄存器”指令后,立即发送应答数据,然后开始写EEPROM
  (写预置数据和CRC16校验码)。 
3、写EEPROM时,每次写4个字节。
4、按照马潮老师应用指南上的例子改写的程序,经常出现写EEPROM错误。
5、我稍稍改进之后,基本上没有出现过错误,但是偶而也出现
6、然后我采用如下方法:写完当前字节之后,立即读出,如果不相同重写(最多重写5次)
7、可是偶而还是错误呢?为什么呢?我写EEPROM时,已经关闭了全局中断了呀!

//////////////////////////////////////////////////////////////////////
//EEPROM写子程序(按照马潮老师应用指南上的例子改写)
//////////////////////////////////////////////////////////////////////
void EEPROM_WRITE_BYTE(unsigned int addr,unsigned char bVal)
{
        while (EECR & (1<<EEWE));
        EEAR = addr;
        EEDR = bVal;
        CLI();
        EECR |= (1<<EEMWE);
        EECR |= (1<<EEWE);
        SEI();
}

//////////////////////////////////////////////////////////////////////
//EEPROM写子程序(我稍稍改进后的程序)
//////////////////////////////////////////////////////////////////////
void EEPROM_WRITE_BYTE(unsigned int addr,unsigned char bVal)
{
        EEAR = addr;
        EEDR = bVal;
        CLI();
        EECR |= (1<<EEMWE);
        EECR |= (1<<EEWE);
        while (EECR & (1<<EEWE));
        NOP();
        NOP();
        SEI();
}

//////////////////////////////////////////////////////////////////////
//EEPROM读子程序
//////////////////////////////////////////////////////////////////////
unsigned char EEPROM_READ_BYTE(unsigned int addr)
{
        while (EECR & (1 << EEWE));                                        EEAR = addr;                                                        EECR |= (1 << EERE);                                                return (EEDR);                                       
}


////////////////////////////////////////////////////////////////////////////////////////////采用重写的方式将 堆栈中数据写到EEPROM
//////////////////////////////////////////////////////////////////////////////////////////void STACK_PutChar(void)
{
        unsigned char i;
        unsigned int addr;
        int bVal;
           unsigned char ch;

        while (!STACK_EMPTY())
        {
           STACK_POP(&addr,&bVal);
                 ch = (bVal >>8);
           for (i = 0 ; i < 5 ; i++)
           {
                EEPROM_WRITE_BYTE(addr,ch);
                if (EEPROM_READ_BYTE(addr) == ch)
                        break;
            }
            addr++;
                   ch = (bval&0xFF);
            for (i = 0 ; i < 5 ; i++)
            {
                  EEPROM_WRITE_BYTE(addr,ch);
                  if (EEPROM_READ_BYTE(addr) == ch)
                    break;
                }
        }
}

出0入0汤圆

发表于 2007-9-11 21:44:51 | 显示全部楼层
建议你首先单独测试读写EEPROM的代码,把其它的先拉掉。

如,定义一个4个字节的数组,赋4个字节初值,写入EEPROM,然后将数组清另,读EEPROM数据到数组,检验是否是写入的值。

出0入0汤圆

 楼主| 发表于 2007-9-12 08:35:58 | 显示全部楼层
在无中断源的情况下,这种情况我做过,EEPROM 一直OK。

出0入0汤圆

 楼主| 发表于 2007-9-12 09:21:22 | 显示全部楼层
当发送完MODBUS应答帧最后一个字节后,立即写EEPROM,上位机会收不到数据,
必须要等一会写EEPROM,上位机才能收到应答数据,为什么呢?

  由于已经产生了中断请求,表示最后一个字节已经发送出去了呀!
以下是程序片段:

#pragma interrupt_handler USART0_TX_ISR:iv_USART0_TX
void USART0_TX_ISR(void)
{
   if (USART0_sendPosi < USART0_sendCount)
        UDR0 = USART0_send_buffer[USART0_sendPosi++];
   else //如果最后一个字节已经发送出去
   {
        USART0_receCount = 0;//清除发送指针
     eeprom_write = TRUE; //置写EEPROM标志           
   }
}

出0入0汤圆

发表于 2009-10-23 16:25:49 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 10:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表