为什么写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;
}
}
} 建议你首先单独测试读写EEPROM的代码,把其它的先拉掉。
如,定义一个4个字节的数组,赋4个字节初值,写入EEPROM,然后将数组清另,读EEPROM数据到数组,检验是否是写入的值。 在无中断源的情况下,这种情况我做过,EEPROM 一直OK。 当发送完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标志
}
} mark
页:
[1]