<meta name="keywords" content="必胜时时彩开户,keywords" /> 单片机中的掉落电存储治理
(玩电子) 电子手艺学习与研究

单片机中的掉落落电存储治理

作者:佚名   泉源:本站原创   点击数:x  更新时间:2013年11月06日   【字体:年夜

列位单片机法式模范模范猿们,在单片机法式模范模范设计的时间,经常碰着一些数据的掉落落电存储效果。经常这些数据量又不是很年夜,但是操作起来特殊费事。每次厘革数据都得挪用存储函数阻拦读写操作。明天总结一下近几天的思绪,对浅易单片机的的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("%d\n",times);
    while(1);
}
        哈哈,这样子,你的应用法式模范模范能否是很精练呀。喜欢那就考试考试下吧!

文章议论

相关文章