单片机中的掉电存储管理

来源:本站
导读:目前正在解读《单片机中的掉电存储管理》的相关信息,《单片机中的掉电存储管理》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《单片机中的掉电存储管理》的详细说明。
简介:各位单片机程序猿们,在单片机程序设计的时候,经常碰到一些数据的掉电存储问题。往往这些数据量又不是很大,但是操作起来特别麻烦。每次变更数据都得调用存储函数进行读写操作。今天总结一下近几天的思路,对普通单片机的的NV变量的管理给出一个较为方便的操作方法。

一般,我们的数据都由8,16,32位组成,因此,在此例中,我给出16长度数据的接口函数,旨在表明这种方法的思路。具体读者可以根据自己的使用环境,自己改进。

首先,说明下笔者的编程习惯,笔者在编写单片机C程序的过程中,往往喜欢把程序中涉及的东西封装成类似于面向对象思想中的类。把数据结构假想成类的属性,把对相应数据结构操作的函数,假想成类的方法。这种方法在实际编程过程中,往往给自己带来很大的便利。不仅思路清晰,而且便于模块化管理自己的程序。

现在,我们创建两个文件,分别为NV.h和NV.C,h文件作为NV管理的模块。NV.h中我们来定义NV变量的数据结构(即笔者所认为的类的属性)和声明对NV操作的函数。

#ifndef _NV_

#define _NV_

//NV操作的状态定义

#define NV_Succeed 1

#defineNV_Failed 0

//定义16位长度的NV变量数据结构

structNV_Struct16

{

u16 Val; //NV16变量的值

u16 NVAddr; //NV16变量在存储器中的首地址

};

//声明外部调用函数

extern void NV16_Get(struct NV_Struct16 *temp);

u8 NV16_Set(struct NV_Struct16 *temp,u16 val);

#endif

在NV_Struct16中,我们封装了一个叫做NV16的变量,其成员中有变量的值和在存储器中的首地址。在这里,只是给它定义了一个数据的结构,并没有定义实体变量,在C++或C#等面向对象程序设计方法中,这叫类的定义,并没有创建类的实体。这样做的目的,就是做到尽量把我们这个NV操作模块从我们编写的其他应用程序中抽象出来。

那么,接下来,我们就来编写NV16变量的操作函数。在NV.C中,我们添加两个函数,一个是获取NV变量的值,另一个是修改NV变量的值。

#include"NV.h"

#include"24CXX.h"

#defineCheckTimes 4 //写入时校验次数

#defineNV8_Enable 1 //NV8使能开关

#defineNV16_Enable 1 //NV16使能开关

#defineNV32_Enable 1 //NV32使能开关

//以下是NV_Struct16的操作函数

#ifNV16_Enable

voidNV16_Get(struct NV_Struct16 *temp)

{

temp->Val=AT24CXX_ReadLenByte(temp->NVAddr,2);

}

u8NV16_Set(struct NV_Struct16 *temp,u16 val)

{

u8 cnt=0;

if(temp->Val==val)returnNV_Succeed;

temp->Val=val;

AT24CXX_WriteLenByte(temp->NVAddr,temp->Val,2);

while(cnt<CheckTimes||AT24CXX_ReadLenByte(temp->NVAddr,2)!=temp->Val)

cnt++;

if(cnt<CheckTimes)return NV_Failed;

else return NV_Succeed;

}

#endif

在这个文件中,我们调用了一个24CXX.h文件中提供的24CXX的读写函数,这部分在我们移植的过程中是需要考虑的。下面贴出这个函数的原型,如果这个都不知道怎么写出来,那我也无语了。

//在AT24CXX里面的指定地址开始读出长度为Len的数据

//该函数用于读出16bit或者32bit的数据.

//ReadAddr :开始读出的地址

//返回值 :数据

//Len :要读出数据的长度2,4

u32AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)

{

u8 t;

u32 temp=0;

for(t=0;t<Len;t++)

{

temp<<=8;

temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);

}

return temp;

}

//在AT24CXX里面的指定地址开始写入长度为Len的数据

//该函数用于写入16bit或者32bit的数据.

//WriteAddr :开始写入的地址

//DataToWrite:数据数组首地址

//Len :要写入数据的长度2,4

voidAT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)

{

u8 t;

for(t=0;t<Len;t++)

{

AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);

}

}

用以上方法来管理我们的NV变量,在程序中会大大地减少我们的工作量。下面来举一个简单的例子。记录设备开机次数,并从串口打印出来。

#include “相关头文件”

#include "NV.H"

#define Flag 0x33 //存储器初始化标志

#define FlagAddr 0x00

#define PowerOnTimesAddr 0x10 //将开机次数数据存储在0x10位置

//创建NV16非易失变量实体

struct NV_Struct16 PowerOnTimes;

struct NV_Struct16 MemFlag;

void NV_Init()

{

//NV地址装入

MemFlag.NVAddr=FlagAddr;

PowerOnTimes.NVAddr=PowerOnTimesAddr;

//检查存储器是否初始化

if(NV16_Get(&MemFlag)!=Flag)

{

NV16_Set(&MemFlag,Flag);

NV16_Set(&PowerOnTimes,0);

}

}

void main()

{

u16 times;

NV_Init();

times=NV16_Get(&PowerOnTimes);

NV16_Set(&PowerOnTimes,times++);

printf("%dn",times);

while(1);

}

哈哈,这样子,你的应用程序是不是很简洁呀。喜欢那就尝试下吧!

提醒:《单片机中的掉电存储管理》最后刷新时间 2024-03-14 01:09:18,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《单片机中的掉电存储管理》该内容的真实性请自行鉴别。