ba_wang_mao 发表于 2007-9-11 16:54:47

为什么写EEPROM老是错误呢?

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;
                }
        }
}

machao 发表于 2007-9-11 21:44:51

建议你首先单独测试读写EEPROM的代码,把其它的先拉掉。

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

ba_wang_mao 发表于 2007-9-12 08:35:58

在无中断源的情况下,这种情况我做过,EEPROM 一直OK。

ba_wang_mao 发表于 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;
   else //如果最后一个字节已经发送出去
   {
        USART0_receCount = 0;//清除发送指针
     eeprom_write = TRUE; //置写EEPROM标志           
   }
}

wodetianmyday 发表于 2009-10-23 16:25:49

mark
页: [1]
查看完整版本: 为什么写EEPROM老是错误呢?