Fix EEPROM access error for WinAVR
作者:lysoft 日期:2008-05-20
Fix EEPROM access error for WinAVR
the following example is popular use in WinAVR:
uchar EEMEM epmem[8] = {"12345678"};
uchar ram[8];
eeprom_write_block(ram,epmem, 8);
eeprom_read_block(ram,epmem, 8);
but I found there is an bug in it!
In some complex application, it will result in system reset for AV error.
So, do not use "eeprom.h". And use my code to replace it.
#define EEMEM __attribute__((section(".eeprom")))
uchar EEPROMRead(uint addr)
{
uchar c, s;
// wait write completed
while (EECR & (1< s = SREG;
cli();
// set address
EEAR = addr;
// start write
EECR |= (1< // read result
c = EEDR;
SREG = s;
return c;
}
void EEPROMWrite(uint addr, uchar c)
{
uchar s;
// wait write completed
while (EECR & (1< s = SREG;
cli();
// set address
EEAR = addr;
EEDR = c;
/* set EEMWE
EECR |= (1< // start write, but this should be done in 4 CPU cycles, use assembler can avoid this
EECR |= (1< __asm__ __volatile__ (
//* START EEPROM WRITE *
//"in r0, %[__sreg] \n\t"
//"cli \n\t"
"sbi %[__eecr], %[__eemwe] \n\t"
"sbi %[__eecr], %[__eewe] \n\t"
//"out %[__sreg], r0 \n\t"
//* END EEPROM WRITE *
:
: [__eecr] "i" (_SFR_IO_ADDR(EECR)),
// [__sreg] "i" (_SFR_IO_ADDR(SREG)),
[__eemwe] "i" (EEMWE),
[__eewe] "i" (EEWE)
: "r0"
);
SREG = s;
}
WinAVR的eeprom读写有Bug的,用我的代码就可以避免这个问题
很多人都用
EECR |= (1< EECR |= (1< 来写EEPROM,却发现数据没写入,因为置位EEMWE后必须在4个时钟周期内置位EEWE,但WinAVR等编译工具没有如此的优化,故使用嵌入汇编来解决此问题
the following example is popular use in WinAVR:
uchar EEMEM epmem[8] = {"12345678"};
uchar ram[8];
eeprom_write_block(ram,epmem, 8);
eeprom_read_block(ram,epmem, 8);
but I found there is an bug in it!
In some complex application, it will result in system reset for AV error.
So, do not use "eeprom.h". And use my code to replace it.
#define EEMEM __attribute__((section(".eeprom")))
uchar EEPROMRead(uint addr)
{
uchar c, s;
// wait write completed
while (EECR & (1<
cli();
// set address
EEAR = addr;
// start write
EECR |= (1<
c = EEDR;
SREG = s;
return c;
}
void EEPROMWrite(uint addr, uchar c)
{
uchar s;
// wait write completed
while (EECR & (1<
cli();
// set address
EEAR = addr;
EEDR = c;
/* set EEMWE
EECR |= (1<
EECR |= (1<
//* START EEPROM WRITE *
//"in r0, %[__sreg] \n\t"
//"cli \n\t"
"sbi %[__eecr], %[__eemwe] \n\t"
"sbi %[__eecr], %[__eewe] \n\t"
//"out %[__sreg], r0 \n\t"
//* END EEPROM WRITE *
:
: [__eecr] "i" (_SFR_IO_ADDR(EECR)),
// [__sreg] "i" (_SFR_IO_ADDR(SREG)),
[__eemwe] "i" (EEMWE),
[__eewe] "i" (EEWE)
: "r0"
);
SREG = s;
}
WinAVR的eeprom读写有Bug的,用我的代码就可以避免这个问题
很多人都用
EECR |= (1<
[本日志由 lysoft 于 2009-06-21 06:23 PM 编辑]
文章来自: 本站原创
Tags: AVR EEPROM WinAVR
相关日志:
评论: 0 | 引用: 0 | 查看次数: 3264
发表评论
上一篇:
下一篇: 









