分类: C/C++
2013-03-23 09:43:26
近来在项目中,要在EEPROM中存储最近48小数的数据,使用的MCU为兼容的8052芯片(V9001,电能计量SOC),考虑到使用的是模拟I2C和52的处理能力,使用一个循环队列来控制数据存储的位置.
一.队列构建
struct Queue
{
uint16 xdata *DataID;
uint8 Size;
uint8
front; //头指针
uint8 rear;//尾指针
};
//================================
//初始化队列
//==================================
void
InitQueue(struct Queue *p,uint8 DataNum,uint16 *dataID)
{
p->DataID=dataID;
p->front=1;
p->rear=0;
p->Size=DataNum;
}
//==================================
//队列满判断
//==================================
int
IsFull(struct Queue *p)
{
return
(p->rear+2)%(p->Size)==p->front;
}
//========================
//队列空判断
//=========================
int
IsEmpty(struct Queue *p)
{
return
(p->rear+1)%(p->Size)==p->front;
}
//========================
//队列插入
//=========================
int
Insert(struct Queue *p,uint16 DataID)
{
if(IsFull( p))
return
0;
else
{
p->rear=(p->rear+1)%(p->Size);
*(p->DataID+p->rear)=DataID;
return 1 ;
}
}
//==========================================
//队列删除
//==========================================
int
Delete(struct Queue *p)
{
if(IsEmpty(p))
return 0;
else
{
p->front=(p->front+1)%(p->Size);
return 1;
}
}
队列采用空出一个位置来判断队空和队满的问题.
二.如何在再次上电后回复队列状态
每次进行队列操作,都会在EEPROM中保存队列首指针和尾指针的值,同时保存首指针所指的数组中的值.因为所要存储的是一个连续的值,只要恢复了这三个数据,就能得到上次系统运行时的队列状态.
以7个数据项(0xc160~0XC167)为例子
recover the front and rear pointer
DataFront=EEPROM[Frontaddress]
if(rear>front)
index=front:rear
if(DataFront>0xc167)
DataFront=0xc160
Data[index]=DataFront
loop
else
index=front:7
if(DataFront>0xc167)
DataFront=0xc160
Data[index]=DataFront
loop
index=0:rear
if(DataFront>0xc167)
DataFront=0xc160
Data[index]=DataFront
loop
三、数据存储和队列修改
当需要存储当前小时电量数据的时候,只要调用队列的插入和删除方法,同时将队列信息写入EEPROM中,以防系统突然当机等问题。