找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1136|回復(fù): 1
收起左側(cè)

51單片機(jī)關(guān)于EEPROM的讀寫

[復(fù)制鏈接]
ID:1111967 發(fā)表于 2024-3-2 14:08 | 顯示全部樓層 |閱讀模式
首先我們要知道什么是EEPROM

這里要看自己的單片機(jī)EEPROM地址大小和起始地址

主要要用到的寄存器并不多,一個(gè)是IAP_CMD(C5H),還有的就是IAP_CONTR(C7H)

然后以下就是通過(guò)代碼寫命令到寄存器最后進(jìn)行數(shù)據(jù)操作即可

單片機(jī)源程序如下:
  1. #include "STC15F2kxx.h"
  2. #include "stceeprom.h"
  3. #include <intrins.h>
  4. #include <string.h>
  5. #include  "delay.h"


  6. //關(guān)閉IAP功能
  7. void IapIdle()         
  8. {
  9.     IAP_CONTR = 0;                 
  10.     IAP_CMD = 0;                  
  11.     IAP_TRIG = 0;                  
  12.     IAP_ADDRH = 0x80;              
  13.     IAP_ADDRL = 0;
  14. }


  15. //擦除指定地址的扇區(qū)
  16. void IapEraseSector(WORD addr)
  17. {
  18.     IAP_CONTR = ENABLE_IAP;//使能IAP      
  19.     IAP_CMD = CMD_ERASE; //擦除命令         
  20.     IAP_ADDRL = addr;   //指定地址         
  21.     IAP_ADDRH = addr >> 8;        
  22.     IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效           
  23.                 _nop_();        //等待
  24.     IAP_TRIG = 0xa5;              
  25.     _nop_();                     
  26.     IapIdle();//關(guān)閉IAP功能
  27. }


  28. //往指定地址中寫入一個(gè)字節(jié)字符數(shù)據(jù)
  29. void IapWritecChar(WORD addr, BYTE dat)
  30. {
  31.     IAP_CONTR = ENABLE_IAP;  //使能IAP      
  32.     IAP_CMD = CMD_PROGRAM;  //寫命令      
  33.     IAP_ADDRL = addr;     //指定地址         
  34.     IAP_ADDRH = addr >> 8;        
  35.     IAP_DATA = dat;               
  36.     IAP_TRIG = 0x5a;  //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效            
  37.           _nop_();
  38.     IAP_TRIG = 0xa5;              
  39.     _nop_();                     
  40.     IapIdle();
  41. }


  42. //往指定地址寫入兩個(gè)字節(jié)數(shù)據(jù)
  43. void IapWriteInt(WORD addr,unsigned int dat)
  44. {
  45.         unsigned char i;
  46.         typedef union  //設(shè)置共用體,用char分?jǐn)?字節(jié)
  47.         {
  48.                 unsigned int dat1;
  49.                 char mchar[2];
  50.         }NEW_DATA;
  51.         NEW_DATA data1;
  52.         data1.dat1 = dat;
  53.         IAP_CONTR = ENABLE_IAP; //使能IAP        
  54.         IAP_CMD = CMD_PROGRAM;   //寫命令     
  55.         for(i = 0; i < 2; i++)
  56.         {
  57.     IAP_ADDRL = addr;    //指定地址         
  58.     IAP_ADDRH = addr >> 8;
  59.                 IAP_DATA = data1.mchar[i];
  60.                 IAP_TRIG = 0x5a;  //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效            
  61.           _nop_();
  62.     IAP_TRIG = 0xa5;              
  63.     _nop_();   
  64.                 addr++;
  65.         }
  66.          IapIdle();  //關(guān)閉IAP功能                  
  67. }

  68. //往指定地址寫入四個(gè)字節(jié)數(shù)據(jù)
  69. void IapWriteI32(WORD addr, unsigned long dat)  
  70. {
  71.         unsigned char i;
  72.         typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
  73.         {
  74.                 unsigned long dat1;
  75.                 char mchar[4];
  76.         }NEW_DATA;
  77.         NEW_DATA data1;
  78.         data1.dat1 = dat;
  79.         
  80.         IAP_CONTR = ENABLE_IAP;  //使能IAP      
  81.         IAP_CMD = CMD_PROGRAM;   //寫命令   

  82.         for(i = 0; i < 4; i++)
  83.         {
  84.     IAP_ADDRL = addr;   //指定地址         
  85.     IAP_ADDRH = addr >> 8;
  86.                 IAP_DATA = data1.mchar[i];
  87.                 IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效         
  88.           _nop_();
  89.     IAP_TRIG = 0xa5;            
  90.     _nop_();               
  91.                 addr++;
  92.         }
  93.         IapIdle(); //關(guān)閉IAP功能                  
  94. }

  95. /*******************************************************************************
  96. * 函數(shù)名  :        Powerlost_data
  97. * 描述    : 斷電中斷數(shù)據(jù)寫入函數(shù)
  98. * 輸入    : addr  地址  dat  寫入數(shù)據(jù)
  99. * 輸出    : 無(wú)
  100. * 返回值  : 無(wú)
  101. * 說(shuō)明    : 為了應(yīng)對(duì)中斷函數(shù)與主函數(shù)循環(huán)使用IapWriteI32函數(shù)沖突
  102. *******************************************************************************/
  103. void Powerlost_data(WORD addr ,unsigned long dat)
  104. {
  105.         unsigned char i;
  106.         typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
  107.         {
  108.                 unsigned long dat1;
  109.                 char mchar[4];
  110.         }NEW_DATA;
  111.         NEW_DATA data1;
  112.         data1.dat1 = dat;
  113.         
  114.         IAP_CONTR = ENABLE_IAP;  //使能IAP      
  115.         IAP_CMD = CMD_PROGRAM;   //寫命令   

  116.         for(i = 0; i < 4; i++)
  117.         {
  118.     IAP_ADDRL = addr;   //指定地址         
  119.     IAP_ADDRH = addr >> 8;
  120.                 IAP_DATA = data1.mchar[i];
  121.                 IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效         
  122.           _nop_();
  123.     IAP_TRIG = 0xa5;            
  124.     _nop_();               
  125.                 addr++;
  126.         }
  127.         IapIdle(); //關(guān)閉IAP功能
  128. }

  129. //往指定起始地址寫入不固定長(zhǎng)度的字符串?dāng)?shù)據(jù)
  130. void IapWriteString(WORD addr,BYTE *mString,BYTE n)
  131. {
  132.    unsigned char i;
  133.                 IAP_CONTR = ENABLE_IAP;   //使能IAP        
  134.                 IAP_CMD = CMD_PROGRAM;   //寫命令   
  135.    for(i=0; i<n ;i++)
  136.          {
  137.                 IAP_ADDRL = addr; //指定地址      
  138.                 IAP_ADDRH = addr >> 8;
  139.                 IAP_DATA = mString[i];
  140.                 IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效           
  141.                 _nop_();
  142.                 IAP_TRIG = 0xa5;              
  143.                 _nop_();
  144.                 addr++;                 
  145.           }
  146.          IapIdle();   //關(guān)閉IAP功能                  
  147. }

  148. //向指定地址讀取一個(gè)字節(jié)的字符數(shù)據(jù)
  149. char IapReadChar(WORD addr)
  150. {
  151.                 BYTE dat;
  152.     IAP_CONTR = ENABLE_IAP;  //使能IAP         
  153.     IAP_CMD = CMD_READ;    //讀命令         
  154.     IAP_ADDRL = addr;  //指定地址              
  155.     IAP_ADDRH = addr >> 8;         
  156.     IAP_TRIG = 0x5a; //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效               
  157.                 _nop_();
  158.     IAP_TRIG = 0xa5;               
  159.     _nop_();                        
  160.     dat = IAP_DATA;               
  161.     IapIdle();  //關(guān)閉IAP功能                    

  162.     return dat;                    
  163. }
  164. //向指定地址讀取兩個(gè)字節(jié)的數(shù)字?jǐn)?shù)據(jù)
  165. unsigned int IapReadInt(WORD addr)
  166. {
  167.         unsigned int dat;
  168.         unsigned char i;
  169.         typedef union        //設(shè)置共用體,用char分?jǐn)?字節(jié)
  170.         {
  171.                 unsigned int dat1;
  172.                 char mchar[2];
  173.         }NEW_DATA;        
  174.         NEW_DATA data1;  
  175.         IAP_CONTR = ENABLE_IAP;  //使能IAP         
  176.         IAP_CMD = CMD_READ;      //讀命令         
  177.         for(i = 0; i < 2; i++)
  178.         {
  179.     IAP_ADDRL = (addr + i);  //指定地址      
  180.     IAP_ADDRH = ((addr + i) >> 8);
  181.     IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效           
  182.                 _nop_();
  183.     IAP_TRIG = 0xa5;              
  184.     _nop_();                     
  185.     data1.mchar[i]= IAP_DATA;
  186.         }
  187.         IapIdle();   //關(guān)閉IAP功能
  188.         dat = data1.dat1;
  189.         return dat;
  190. }


  191. //向指定地址讀取四個(gè)字節(jié)的數(shù)字?jǐn)?shù)據(jù)
  192. unsigned long IapReadI32(WORD addr)
  193. {
  194.         unsigned long dat;
  195.         unsigned char i;
  196.         typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
  197.         {
  198.                 unsigned long dat1;
  199.                 char mchar[4];
  200.         }NEW_DATA;
  201.         NEW_DATA data1;
  202.         IAP_CONTR = ENABLE_IAP;  //使能IAP         
  203.         IAP_CMD = CMD_READ;      //讀命令

  204.                      
  205.         for(i = 0; i < 4; i++)
  206.         {
  207.     IAP_ADDRL = (addr + i); //指定地址      
  208.     IAP_ADDRH = ((addr + i) >> 8);
  209.     IAP_TRIG = 0x5a;  //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效            
  210.                 _nop_();
  211.     IAP_TRIG = 0xa5;              
  212.     _nop_();                     
  213.     data1.mchar[i] = IAP_DATA;   
  214.         }
  215.         IapIdle();//關(guān)閉IAP功能
  216.         dat = data1.dat1;
  217.         return dat;
  218. }


  219. //向指定地址讀取不定長(zhǎng)度的字符串?dāng)?shù)據(jù)
  220. void IapReadString(WORD addr,BYTE *mString, BYTE n)
  221. {
  222.   unsigned char i;
  223.         memset(mString,0,strlen(mString));
  224.         IAP_CONTR = ENABLE_IAP;   //使能IAP               
  225.   IAP_CMD = CMD_READ;      //讀命令                              
  226.   for(i = 0; i < n; i++)
  227.         {
  228.     IAP_ADDRL = (addr + i);  //指定地址        
  229.     IAP_ADDRH = ((addr + i) >> 8);  
  230.     IAP_TRIG = 0x5a;   //命令觸發(fā)器先寫5ah,再寫a5h命令才能生效            
  231.                 _nop_();
  232.     IAP_TRIG = 0xa5;               
  233.     _nop_();                              
  234.     mString[i] = IAP_DATA;         
  235.         }
  236.         IapIdle();//關(guān)閉IAP功能
  237. }
復(fù)制代碼


回復(fù)

使用道具 舉報(bào)

ID:41656 發(fā)表于 2024-3-9 11:49 | 顯示全部樓層
小數(shù)據(jù)可以這樣寫分開幾個(gè)字節(jié)幾個(gè)字節(jié)的寫,不過(guò)建議寫數(shù)據(jù)可以使用一個(gè)結(jié)構(gòu)體把數(shù)據(jù)和校驗(yàn)數(shù)據(jù)都寫進(jìn)去,使用指針,存儲(chǔ)根據(jù)結(jié)構(gòu)體數(shù)據(jù)sizeof結(jié)果直接寫入,讀取時(shí)通過(guò)結(jié)構(gòu)體數(shù)據(jù)大小一次性讀取并做校驗(yàn),我現(xiàn)在數(shù)據(jù)量小CRC8做校驗(yàn),要是數(shù)據(jù)量大可以考慮CRC16或32
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表