|
发表于 2010-11-29 10:25:34
|
显示全部楼层
LZ的方法太麻烦....直接设一个寄存器变量(只用其中一位)f_EEPROM_W,
在EEMWE和EEWE置位之间判断下f_EEPROM_W是否为0
不为0的话才写EEWE位...
这样就没问题了,在写eeprom前,先置位f_EEPROM_W就可以了,写完了就清零f_EEPROM_W
由于写EEMWE和写EEWE之间有时间要求...所以必须用寄存器变量来做...
时间超了,eeprom写入是不会成功的....
我就是这样做的,一直没问题,其实最简单的方法就是开BOD,开了BOD就没事,不过有的产品有功耗要求,就只有软件方法解决了...
以下是部分代码
====================
#ifndef _H_EEPROM
#define _H_EEPROM
#include "main.h"
#define EEPROM_SIZE 256
#if EEPROM_SIZE>256
#define EEPROM_INIT()
#define EEP_TYPE u16
#else
#define EEP_TYPE u8
#define EEPROM_INIT() ( EEARH = 0 )
#undef EEAR
#define EEAR EEARL
#endif
typedef struct
{
u8 Tick;
u8 Data;
EEP_TYPE Address;
} EEP_T;
extern EEP_T EEP;
extern void EEPROM_DoEvent(void);
extern u8 EEPROM_ReadByte(EEP_TYPE address);
extern void EEPROM_ReadBytes(EEP_TYPE address, u8* dest, EEP_TYPE count);
extern void EEPROM_WriteBytes(EEP_TYPE address, u8* source, EEP_TYPE count);
//extern void EEPROM_Destroy(EEP_TYPE address, u16 count);
#define EEPROM_WRITE(address,data) \
{\
FLAG_SET(f_EEPROM_W);\
EEP.Address = address;\
EEP.Data = data;\
}
#endif
====================
#include "EEPROM.h"
EEP_T EEP = {0};
#define EEPROM_WAIT() { while( EECR&BIT(EEWE) ); }
#define EEPROM_CHK_BUSY() { if(EECR&BIT(EEWE)) return; }
#define EEPROM_SET_ADDR(a) { EEAR = a; }
#define EEPROM_SET_DATA(d) { EEDR = d; }
#define EEPROM_DO_WRITE() { EECR|=BIT(EEMWE); if(FLAG_CHK(f_EEPROM_W)!=0) EECR|=BIT(EEWE); else return; }
/*
void EEPROM_ReadBytes(EEP_TYPE address, u8* dest, EEP_TYPE count)
{
EEPROM_INIT();
EEPROM_WAIT();
for(;;)
{
EEAR = address;
EECR |= BIT(EERE);
*dest++ = EEDR;
address++;
count--;
if( count==0 )
{
break;
}
}
}
void EEPROM_WriteBytes(EEP_TYPE address, u8* source, EEP_TYPE count)
{
EEPROM_INIT();
for(;;)
{
EEPROM_WAIT();
EEAR = address;
EEDR = *source++;
Interrupt_ALL_Disabled();
EEPROM_DO_WRITE();
Interrupt_ALL_Enabled();
address++;
count--;
if( count==0 )
{
break;
}
}
}
void EEPROM_WriteByte(EEP_TYPE address, u8 data)
{
EEPROM_INIT();
EEPROM_WAIT();
EEAR = address;
EEDR = data;
Interrupt_ALL_Disabled();
EEPROM_DO_WRITE();
Interrupt_ALL_Enabled()
}
*/
u8 EEPROM_ReadByte(EEP_TYPE address)
{
EEPROM_INIT();
EEPROM_WAIT();
EEAR = address;
EECR |= BIT(EERE);
return EEDR;
}
void EEPROM_DoEvent(void)
{
if( EEP.Tick>0 )
{
EEP.Tick--;
return;
}
//
if( FLAG_CHK(f_EEPROM_W) )
{
EEPROM_INIT();
EEPROM_CHK_BUSY();
EEPROM_SET_ADDR(EEP.Address);
EEPROM_SET_DATA(EEP.Data);
//
Interrupt_ALL_Disabled();
EEPROM_DO_WRITE();
Interrupt_ALL_Enabled();
//
FLAG_CLR(f_EEPROM_W);
EEP.Tick = MS(1000);
}
} |
|