久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2025|回復: 2
打印 上一主題 下一主題
收起左側

需要大神進行數據保存講解,還有如何修改單片機程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:148486 發表于 2019-5-20 08:55 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*  
        以下已經給出數據存儲的例程。就是把N個用戶數據通過緩存器ram的xdata區(0x8000~0x801f)來把數據存儲到 rom區的指定地址域 block_a和block_a_end之中; (ram就是所謂的“內存”,rom就是所謂的“硬盤”)
        請讀懂函數,并把" //**************** "和” //********************* “之間的代碼,壓縮成一個循環體(主要問題)
        
        思路是:把ROM塊“block_a(block_a~block_a_end)”分成長度為“save_size(即'用戶數據+CRC’的長度)”的若干個區,并標記bank1、bank2。。。。。bank n  ;擦除時,會擦除整個塊"block_a",保存數據時,
        則是先保存在bank1,下次保存在bank2,再次保存,則保存在緊挨著的下個bank;  最后整個block_a塊都滿了,則重新擦除塊“block_a“,再次從bank1(block_a的首地址)開始保存數據。就這樣周而復始;
注:
        一次性最多只能擦除或者寫32byte,所有的數據,必須經過xdata區(0x8000~0x801f)的32byte緩沖區來完成。
擦除數據:1次最少可以擦除1byte的數據,最多一次性可以擦除32byte數據,在xdata區(0x8000~0x801f)把需要擦除的字節清零,接著執行擦除動作就可以了。
數據存儲:對于已經擦除過的扇區,則把要保存的數據發送到在xdata區(0x8000~0x801f),接著執行寫的動作就可以了
先選擇FMCR=0x01;來激活xdata區,并激活其他關于false操作的寄存器。
激活xdata區后,只有對xdata區(0x8000~0x801f)賦值的byte的才會對應的被擦或寫。
在執行擦除和寫動作時,會自動屏蔽中斷,不需要軟件屏蔽。
   以長度為N數據鏈為例,其結構為:前面第0到第(N-2)個數據為用戶數據,最后一個——————第(N-1)為數據鏈的冗余碼。        
*/

  1. #define block_a     ((unsigned char code *)0x3c00)            /*  BLOCK A ADDRESS 首地址*/
  2. #define block_a_end ((unsigned char code *)0x3fff)            /*  BLOCK A end_ADDRESS 末地址*/


  3. #define        pgbuf_size        32                                                        //緩沖區大小
  4. #define pgbuf_start ((unsigned char xdata *)0x8000)        //緩沖區首地址
  5. #define        pgbuf_end        ((unsigned char xdata *)0x801f)        //緩沖區末地址

  6. //==========================================================
  7. //塊擦除
  8. //輸入block首地址(ers_start_addr)和末地址(ers_end_addr)
  9. //擦除輸入的地址段
  10. //芯片支持單個byte的擦除,但是本子程序不支持
  11. //==========================================================
  12. void        fnblock_erase(uchar code *ers_start_addr,uchar code *ers_end_addr);


  13. //===========================================
  14. //                     設置數據的保存
  15. //本子程序允許存儲的數據鏈長度不限
  16. //主要用于掉電記憶
  17. //===========================================
  18. #define        save_size        45                                                                                                //儲存的數據長度
  19. uchar        fntake_crc(uchar        *p,uchar num_size);        //求數據連的CRC
  20. void        fnact_circuit();                        //激活燒錄升壓電路
  21. void        fnact_write();        //執行燒錄

  22. void        fnsave_data()
  23. {
  24.         uchar code *write_addr;
  25.         uchar        i,k,m,n,y;
  26.         k=take_crc(&save[0],(save_size-1));                //求CRC
  27.         save[save_size-1]=k;                                                                        //保存CRC        
  28.         write_addr=block_a;
  29.         
  30.         y=0;
  31.         while(y<100)        //如果換區100個都寫不成功,則認為芯片永久損壞,報廢。
  32.         {
  33.                 while(write_addr<=(block_a_end-save_size))         //確保要寫的數據在block_a區域內
  34.                 {                                //-----------------查空,空時為0 ,當rom區為“空”時,邏輯數據為“0”
  35.                               //在數據保存之前,先檢查需要保存的地址區域連save_size的長度都為“空”
  36.                         for(i=0;i<save_size;i++)
  37.                         {        
  38.                                 if(*(write_addr+i)!=0)        break;
  39.                         }
  40.                         if(i==save_size)        break;                //判斷,如果連續save_size的長度都為“空”,則結束循環并跳出
  41.                         write_addr+=save_size;                        //如果當前的地址域不是連續“空”,則準備查詢下一個區
  42.                         if(write_addr>(block_a_end-save_size))        //如果從block_a到(block_a_end-save_size)的區間都有非零數據(不是“空”),則執行調用擦除函數fnblock_erase()
  43.                         {
  44.                                 block_erase(block_a,block_a_end);                  //擦除數據塊block_a
  45.                                 write_addr=block_a;                                                                                //重置寫數據的區
  46.                                 bflash_erase=true;                                                                                //置1,避免第85行,重復調用fnblock_erase()
  47.                                 break;
  48.                         }
  49.                 }
  50.                 if((write_addr==block_a)&&(bflash_erase==false))
  51.                 {        //第一次存儲時,也需要擦除一次
  52.                         block_erase(block_a,block_a_end);                  //擦除
  53.                         write_addr=block_a;
  54.                 }
  55.                 bflash_erase=false;
  56.                
  57.                         
  58.                 //開始寫入                        
  59.                 //*****************************************************************
  60.                 n=0;                           
  61.                 while(n<8)                                                                                                                //同一個區允許寫8次
  62.                 {
  63.                         //=================寫入一部分數據======================
  64.                         k=(write_addr-block_a)%pgbuf_size;        //計算開始寫的緩沖區相對地址
  65.                         pgbuf=pgbuf_start+k;                                                                //開始寫的緩沖區絕對地址
  66.                                                 
  67.                         fnact_circuit();                        //激活燒錄升壓電路
  68.                         
  69.                         m=pgbuf_size-k;                                                                                        //m=要保存數據的首地址(在緩沖區“0x8000~0x801f”中的首地址)
  70.                         for(i=0;((i<m)&&(i<save_size));i++)
  71.                         {                                                                        //把需要保存的數據移到緩沖區
  72.                                 *(pgbuf+i)=save[i];
  73.                         }
  74.                         
  75.                         if(write_addr>=0x3800)
  76.                         {
  77.                                 FSADRL=(ushort)write_addr;                        //數據要保存在rom中的絕對地址低8位
  78.                                 FSADRM=(ushort)write_addr>>8;          //數據要保存在rom中的絕對地址高8位
  79.                                 FSADRH=0;
  80.                                 
  81.                                 fnact_write();        //執行燒錄
  82.                         }
  83.                         //=================================================
  84.                         //================繼續寫剩下部分====================
  85.                         for(;m<save_size;)
  86.                         {                                                /
  87.                                 pgbuf=pgbuf_start;
  88.                                 
  89.                                 fnact_circuit();                        //激活燒錄升壓電路
  90.                                    
  91.                                 for(i=0;((i<pgbuf_size)&&(i<(save_size-m)));i++)         
  92.                                 {        //把需要保存的數據移到緩沖區
  93.                                         *(pgbuf+i)=save[i+m];
  94.                                 }
  95.                                 
  96.                                 if(write_addr>=0x3800)
  97.                                 {
  98.                                         FSADRL=((ushort)write_addr+m);
  99.                                         FSADRM=((ushort)write_addr+m)>>8;        
  100.                                         FSADRH=0;
  101.                                        
  102.                                         fnact_write();        //執行燒錄
  103.                                 }
  104.                                 m=m+i;
  105.                         }
  106.                         //======================================
  107.                         //**************************************
  108.                         
  109.                         //-----------------------------驗證存儲是否成功
  110.                         for(i=0;i<save_size;i++)
  111.                         {
  112.                                 if(*(write_addr+i)!=save[i])        break;
  113.                         }
  114.                         
  115.                         if(i==save_size)        break;
  116.                         n++;
  117.                 }
  118.                 if(i==save_size)        break;
  119.                 y++;
  120.                 write_addr+=save_size;                                                        //如果同一區寫8次不成功,則換區
  121.                 if(write_addr>(block_a_end-save_size))
  122.                 {
  123.                         block_erase(block_a,block_a_end);                  //擦除
  124.                         write_addr=block_a;
  125.                         bflash_erase=true;
  126.                 }
  127.         }                                                
  128. }        
復制代碼

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:330198 發表于 2019-5-20 09:56 | 只看該作者
你想要怎么改啊
回復

使用道具 舉報

板凳
ID:148486 發表于 2019-5-20 12:23 | 只看該作者
把" //**************** "和” //********************* “之間的代碼,壓縮成一個循環體
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕欧美一区 | 日本一道本| 日韩中文一区二区三区 | 亚洲精品中文字幕中文字幕 | 国产欧美一区二区三区在线看 | 男女网站免费观看 | 91在线一区 | 免费在线观看一区二区 | 草久久| 中文字幕一区在线 | 成人免费区一区二区三区 | 久久久蜜桃 | 成人黄在线观看 | 国产欧美精品一区二区 | 最新日韩av | 日韩免费中文字幕 | 精品一区二区久久久久久久网站 | 黑人巨大精品欧美一区二区免费 | 亚洲自拍一区在线观看 | 免费a国产 | 国产午夜高清 | 久久久国产精品入口麻豆 | 久久久久国产精品一区二区 | 国产午夜精品一区二区三区四区 | 超碰免费观看 | 久久久人成影片免费观看 | 伊人国产精品 | 精品久久久久久亚洲国产800 | 色性av| 亚洲午夜网| 亚洲精品自拍视频 | 91精品久久久久久久久99蜜臂 | 亚洲成人综合网站 | 精品国产欧美一区二区三区不卡 | 成人二区 | 亚洲综合天堂 | 国产一区二区av | 91精品成人久久 | 蜜臀久久99精品久久久久久宅男 | 久久亚洲一区二区 | 91精品久久久 |