在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)中的掉電存儲管理

            單片機(jī)中的掉電存儲管理

            作者: 時間:2016-11-30 來源:網(wǎng)絡(luò) 收藏
            各位單片機(jī)程序猿們,在單片機(jī)程序設(shè)計(jì)的時候,經(jīng)常碰到一些數(shù)據(jù)的掉電存儲問題。往往這些數(shù)據(jù)量又不是很大,但是操作起來特別麻煩。每次變更數(shù)據(jù)都得調(diào)用存儲函數(shù)進(jìn)行讀寫操作。今天總結(jié)一下近幾天的思路,對普通單片機(jī)的的NV變量的管理給出一個較為方便的操作方法。

            一般,我們的數(shù)據(jù)都由8,16,32位組成,因此,在此例中,我給出16長度數(shù)據(jù)的接口函數(shù),旨在表明這種方法的思路。具體讀者可以根據(jù)自己的使用環(huán)境,自己改進(jìn)。

            本文引用地址:http://www.biyoush.com/article/201611/323956.htm

            首先,說明下筆者的編程習(xí)慣,筆者在編寫單片機(jī)C程序的過程中,往往喜歡把程序中涉及的東西封裝成類似于面向?qū)ο笏枷胫械念悺0褦?shù)據(jù)結(jié)構(gòu)假想成類的屬性,把對相應(yīng)數(shù)據(jù)結(jié)構(gòu)操作的函數(shù),假想成類的方法。這種方法在實(shí)際編程過程中,往往給自己帶來很大的便利。不僅思路清晰,而且便于模塊化管理自己的程序。

            現(xiàn)在,我們創(chuàng)建兩個文件,分別為NV.h和NV.C,h文件作為NV管理的模塊。NV.h中我們來定義NV變量的數(shù)據(jù)結(jié)構(gòu)(即筆者所認(rèn)為的類的屬性)和聲明對NV操作的函數(shù)。
            #ifndef _NV_
            #define _NV_

            //NV操作的狀態(tài)定義
            #define NV_Succeed 1

            #defineNV_Failed 0
            //定義16位長度的NV變量數(shù)據(jù)結(jié)構(gòu)

            structNV_Struct16
            {
            u16 Val; //NV16變量的值
            u16 NVAddr; //NV16變量在存儲器中的首地址
            };
            //聲明外部調(diào)用函數(shù)
            extern void NV16_Get(struct NV_Struct16 *temp);
            u8 NV16_Set(struct NV_Struct16 *temp,u16 val);
            #endif

            在NV_Struct16中,我們封裝了一個叫做NV16的變量,其成員中有變量的值和在存儲器中的首地址。在這里,只是給它定義了一個數(shù)據(jù)的結(jié)構(gòu),并沒有定義實(shí)體變量,在C++或C#等面向?qū)ο蟪绦蛟O(shè)計(jì)方法中,這叫類的定義,并沒有創(chuàng)建類的實(shí)體。這樣做的目的,就是做到盡量把我們這個NV操作模塊從我們編寫的其他應(yīng)用程序中抽象出來。

            那么,接下來,我們就來編寫NV16變量的操作函數(shù)。在NV.C中,我們添加兩個函數(shù),一個是獲取NV變量的值,另一個是修改NV變量的值。

            #include"NV.h"
            #include"24CXX.h"
            #defineCheckTimes 4 //寫入時校驗(yàn)次數(shù)
            #defineNV8_Enable 1 //NV8使能開關(guān)
            #defineNV16_Enable 1 //NV16使能開關(guān)
            #defineNV32_Enable 1 //NV32使能開關(guān)

            //以下是NV_Struct16的操作函數(shù)

            #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(cntNVAddr,2)!=temp->Val)
            cnt++;
            if(cnt else return NV_Succeed;
            }

            #endif
            在這個文件中,我們調(diào)用了一個24CXX.h文件中提供的24CXX的讀寫函數(shù),這部分在我們移植的過程中是需要考慮的。下面貼出這個函數(shù)的原型,如果這個都不知道怎么寫出來,那我也無語了。

            //在AT24CXX里面的指定地址開始讀出長度為Len的數(shù)據(jù)
            //該函數(shù)用于讀出16bit或者32bit的數(shù)據(jù).
            //ReadAddr :開始讀出的地址
            //返回值 :數(shù)據(jù)
            //Len :要讀出數(shù)據(jù)的長度2,4
            u32AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
            {
            u8 t;
            u32 temp=0;
            for(t=0;t {
            temp<<=8;
            temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
            }
            return temp;
            }

            //在AT24CXX里面的指定地址開始寫入長度為Len的數(shù)據(jù)
            //該函數(shù)用于寫入16bit或者32bit的數(shù)據(jù).
            //WriteAddr :開始寫入的地址
            //DataToWrite:數(shù)據(jù)數(shù)組首地址
            //Len :要寫入數(shù)據(jù)的長度2,4
            voidAT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)

            {
            u8 t;
            for(t=0;t {
            AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
            }
            }


            用以上方法來管理我們的NV變量,在程序中會大大地減少我們的工作量。下面來舉一個簡單的例子。記錄設(shè)備開機(jī)次數(shù),并從串口打印出來。
            #include “相關(guān)頭文件”
            #include "NV.H"

            #define Flag 0x33 //存儲器初始化標(biāo)志
            #define FlagAddr 0x00
            #define PowerOnTimesAddr 0x10 //將開機(jī)次數(shù)數(shù)據(jù)存儲在0x10位置
            //創(chuàng)建NV16非易失變量實(shí)體
            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",times);
            while(1);
            }
            哈哈,這樣子,你的應(yīng)用程序是不是很簡潔呀。喜歡那就嘗試下吧!



            關(guān)鍵詞: 單片機(jī)掉電存儲管

            評論


            技術(shù)專區(qū)

            關(guān)閉