分享

基于STM32 HAL库的flash emulation eeprom

 guitarhua 2018-01-19

本文讨论如何使用flash模拟eeprom(基于STM32 HAL库),本例使用的MCU是STM32F103TB。

IDE平台:IAR EWARM7.60

用到的资源:STM32Cube_FW_F1_V1.4.0库,emulation_ee.c/h,app_eeprom.c/h,main.c;

emulation_ee模块封装了flash模拟eeprom的所有细节,提供了3个用户API,该模块从基于stm32标准外设库的eeprom模块修改而来。

实例工程下载:http://download.csdn.net/detail/qiezhihuai/9593794


一、首先介绍模块使用到的STM32 HAL库API

1、HAL_FLASHEx_Erase()API,可以对flash进行按页或块擦除

原型:HAL_StatusTypeDef  HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError);

所在文件:stm32f1xx_hal_flash_ex.h

使用方法:首先定义一个FLASH_EraseInitTypeDef类型的实例,一个page_error变量,例:

uint32_t page_error = 0;

FLASH_EraseInitTypeDeferase_initstruct =

{

.TypeErase = FLASH_TYPEERASE_PAGES,/* 擦除方式,这里选择按页擦除 */

.NbPages = 1,/* 页数量,模块中只对单页进行操作 */

.PageAddress = PAGE0_BASE_ADDRESS/* 被擦除页的起始地址,默认为PAGE0的地址,使用中需要对此成员进行更新 */

}

现在对PAGE1进行擦除:

erase_initstruct.PageAddress = PAGE1_BASE_ADDRESS;  /* 设定擦除地址 */

HAL_FLASHEx_Erase(&erase_initstruct,&page_error);/* 操作成功,该API返回HAL_OK */


2、HAL_FLASH_Program()API,对flash进行编程

原型:HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);

所在文件:stm32fxx_hal_flash.h

例:HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWOR,PAGE1_BASE_ADDRESS,VALID_PAGE);/* 按半字编程 */


3、HAL_FLASH_Unlock()API,在调用flash编程函数之前调用,用于解锁flash

4、HAL_FLASH_Lock()API,执行完编程API后调用,锁flash,避免误操作

例:

 HAL_FLASH_Unlock();
  ee_readvariable(TEMP_EE_ADDR,&temp_value);
  HAL_FLASH_Lock();


二、emulation_ee.h

  1. #ifndef _EMULATION_EE_H  
  2. #define _EMULATION_EE_H  
  3.   
  4. /* Includes ------------------------------------------------------------------*/  
  5. /* 这里使用的stm32f103tb,所以包含stm32f1xx.h,如果使用的是不是f1系列,则应修改为相应的头文件包含 */  
  6. #include "stm32f1xx.h"  
  7.   
  8. /* Exported constants --------------------------------------------------------*/  
  9. /* low-density(16 to 32k) and medium-density(64 to 128k) device,page size = 1kbyte */  
  10. /* 页大小,根据片上flash大小来设定该值,低中密度的也大小 = 1kbytes */  
  11. #define PAGE_SIZE  (uint16_t)0x400   
  12.   
  13. /* high-density(256 to 512k) and XL-density(512 - 1024k),page size = 2kbyte */  
  14. //#define PAGE_SIZE  (uint16_t)0x800    
  15.   
  16.   
  17. /* EEPROM start address in Flash,对应page63 */  
  18. #define EEPROM_START_ADDRESS    ((uint32_t)0x08010000) /* EEPROM emulation start address:  
  19.                                                   after 64KByte of used Flash memory */  
  20.   
  21. /* Pages 0 and 1 base and end addresses */  
  22. #define PAGE0_BASE_ADDRESS      ((uint32_t)(EEPROM_START_ADDRESS + 0x000))  
  23. #define PAGE0_END_ADDRESS       ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))  
  24.   
  25. #define PAGE1_BASE_ADDRESS      ((uint32_t)(EEPROM_START_ADDRESS + PAGE_SIZE))  
  26. #define PAGE1_END_ADDRESS       ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))  
  27.   
  28. /* Used Flash pages for EEPROM emulation */  
  29. #define PAGE0                   ((uint16_t)0x0000)  
  30. #define PAGE1                   ((uint16_t)0x0001)  
  31.   
  32. /* No valid page define */  
  33. #define NO_VALID_PAGE           ((uint16_t)0x00AB)  
  34.   
  35. /* Page status definitions */  
  36. #define ERASED                  ((uint16_t)0xFFFF)     /* PAGE is empty */  
  37. #define RECEIVE_DATA            ((uint16_t)0xEEEE)     /* PAGE is marked to receive data */  
  38. #define VALID_PAGE              ((uint16_t)0x0000)     /* PAGE containing valid data */  
  39.   
  40. /* Valid pages in read and write defines */  
  41. #define READ_FROM_VALID_PAGE    ((uint8_t)0x00)  
  42. #define WRITE_IN_VALID_PAGE     ((uint8_t)0x01)  
  43.   
  44. /* Page full define */  
  45. #define PAGE_FULL               ((uint8_t)0x80)  
  46.   
  47. /* Variables' number,用户根据要保存的数据量来确定 */  
  48. #define NUMB_OF_VAR             ((uint8_t)0x02)  
  49.   
  50.   
  51. /* 模块初始化API,使用之前用户必须首先调用该函数进行初始化操作 */  
  52. uint16_t ee_init(void);  
  53. /* 从flash读取一个数据 */  
  54. uint16_t ee_readvariable(uint16_t virt_addr, uint16_t* data);  
  55. /* 对flash写入一个数据 */  
  56. uint16_t ee_writevariable(uint16_t virt_addr, uint16_t data);  
  57.   
  58.   
  59.   
  60.   
  61. #endif  

三、emulation_ee.c

  1. #include "emulation_ee.h"  
  2.   
  3.   
  4. uint16_t data_var = 0;  
  5. uint32_t cur_wr_address;   /* current W/R address */  
  6.   
  7. uint32_t page_error = 0;  
  8. FLASH_EraseInitTypeDef erase_initstruct =   
  9. {  
  10.     .TypeErase = FLASH_TYPEERASE_PAGES,  
  11.     .NbPages = 1,  
  12.     .PageAddress = PAGE0_BASE_ADDRESS  
  13. };  
  14.   
  15. extern uint16_t virt_add_var_tab[NUMB_OF_VAR];      /* 在app_eeprom.c中定义 */  
  16.   
  17. static uint16_t __ee_init(void);  
  18. static HAL_StatusTypeDef ee_format(void);  
  19. static uint16_t ee_findvalidpage(uint8_t operation);  
  20. static uint16_t ee_verifypagefullwritevariable(uint16_t virt_addr,uint16_t data);  
  21. static uint16_t ee_pagetransfer(uint16_t virt_addr,uint16_t data);  
  22. static uint16_t init_cur_wr_address(void);  
  23.   
  24.   
  25.   
  26. /* init emulation_ee moudle */  
  27. uint16_t ee_init(void)  
  28. {  
  29.     uint16_t flash_status;  
  30.     flash_status = __ee_init();  
  31.     init_cur_wr_address();  
  32.     return flash_status;  
  33. }  
  34.   
  35.   
  36. /**  
  37.   * @brief  Restore the pages to a known good state in case of page's status  
  38.   *   corruption after a power loss.  
  39.   * @param  None.  
  40.   * @retval - Flash error code: on write Flash error  
  41.   *         - FLASH_COMPLETE: on success  
  42.   */  
  43. uint16_t __ee_init(void)  
  44. {  
  45.     uint16_t page_status0 = 6,page_status1 = 6;  
  46.     uint16_t var_idx = 0;  
  47.     uint16_t eeprom_status = 0, read_status = 0;  
  48.     int16_t  x = -1;  
  49.     uint16_t flash_status;  
  50.   
  51.     /* get page0 actual status */  
  52.     page_status0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);  
  53.       
  54.     /* get page1 actual status */  
  55.     page_status1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);  
  56.       
  57.     switch(page_status0)  
  58.     {  
  59.     case ERASED:  
  60.         if(page_status1 == VALID_PAGE)  /* Page0 erased, Page1 valid */  
  61.         {  
  62.             erase_initstruct.PageAddress = PAGE0_BASE_ADDRESS;  
  63.             flash_status = HAL_FLASHEx_Erase(&erase_initstruct,&page_error);  
  64.             if(flash_status != HAL_OK)  
  65.                 return flash_status;  
  66.         }  
  67.         else if(page_status1 == RECEIVE_DATA)  
  68.         {  
  69.             erase_initstruct.PageAddress = PAGE0_BASE_ADDRESS;  
  70.             flash_status = HAL_FLASHEx_Erase(&erase_initstruct,&page_error);  
  71.             if(flash_status != HAL_OK)  
  72.                 return flash_status;  
  73.               
  74.             flash_status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,  
  75.                                              PAGE1_BASE_ADDRESS,  
  76.                                              VALID_PAGE);  
  77.             if(flash_status != HAL_OK)  
  78.                 return flash_status;  
  79.         }  
  80.         else  
  81.         {  
  82.             flash_status = ee_format();  
  83.             if(flash_status != HAL_OK)  
  84.                 return flash_status;  
  85.         }  
  86.         break;  
  87.           
  88.     case RECEIVE_DATA:  
  89.         if(page_status1 == VALID_PAGE)  
  90.         {  
  91.             for(var_idx =0;var_idx<numb_of_var;var_idx++) {="" if((*(__io="" uint16_t*)(page0_base_address+6))="=" virt_add_var_tab[var_idx])="" x="var_idx;" if(var_idx="" !="x)" read_status="ee_readvariable(virt_add_var_tab[var_idx],&data_var);" if(read_status="" eeprom_status="ee_verifypagefullwritevariable(virt_add_var_tab[var_idx],data_var);" if(eeprom_status="" return="" eeprom_status;="" }="" flash_status="HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD," page0_base_address,="" valid_page);="" if(flash_status="" flash_status;="" *erase="" page1="" *="" erase_initstruct.pageaddress="PAGE1_BASE_ADDRESS;" else="" if(page_status1="=" erased)="" erase="" mark="" page0="" as="" valid="" break;="" case="" valid_page:="" valid_page)="" invalid="" state="" -=""> format eeprom */  
  92.         {  
  93.             flash_status = ee_format();  
  94.             if(flash_status != HAL_OK)  
  95.                 return flash_status;  
  96.         }  
  97.         else if(page_status1 == ERASED)  
  98.         {  
  99.             /* ERASE PAGE1 */  
  100.             erase_initstruct.PageAddress = PAGE1_BASE_ADDRESS;  
  101.             flash_status = HAL_FLASHEx_Erase(&erase_initstruct,&page_error);  
  102.             if(flash_status != HAL_OK)  
  103.                 return flash_status;  
  104.         }  
  105.         else  
  106.         {  
  107.             for(var_idx=0;var_idx<numb_of_var;var_idx++) {="" if((*(__io="" uint16_t*)(page1_base_address="" +="" 6))="=" virt_add_var_tab[var_idx])="" x="var_idx;" }="" if(var_idx="" !="x)" *read="" the="" last="" variables'="" updates="" *="" read_status="ee_readvariable(virt_add_var_tab[var_idx],&data_var);" if(read_status="" eeprom_status="ee_verifypagefullwritevariable(virt_add_var_tab[var_idx],data_var);" if(eeprom_status="" return="" eeprom_status;="" mark="" page1="" as="" valid="" flash_status="HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD," page1_base_address,="" valid_page);="" if(flash_status="" flash_status;="" erase="" page0="" erase_initstruct.pageaddress="PAGE0_BASE_ADDRESS;" break;="" default:="" hal_ok;="" hal_statustypedef="" ee_format(void)="" status="HAL_OK;" if(status="" status;="" set="" page:="" write="" valid_page="" at="" base="" address="" page0_base_address,="" **="" @brief="" writes="" upadtes="" variable="" data="" in="" eeprom.="" @param="" virtaddress:="" virtual="" data:="" 16="" bit="" to="" be="" written="" @retval="" success="" or="" error="" status:="" -="" flash_complete:="" on="" page_full:="" if="" page="" is="" full="" no_valid_page:="" no="" was="" found="" flash="" code:="" uint16_t="" ee_writevariable(uint16_t="" virt_addr,uint16_t="" data)="" page_full)="" returns="" stored="" data,="" found,="" which="" correspond="" passed="" global="" contains="" read="" value="" 0:="" 1:="" not="" found.="" ee_readvariable(uint16_t="" virt_addr,="" uint16_t*="" validpage="PAGE0;" address_value="0x5555,read_status=1;" uint32_t="" =="" 0x08010000;="" if(validpage="=" no_valid_page)="" no_valid_page;="" page_start_address="(uint32_t)(EEPROM_START_ADDRESS" (uint32_t)(validpage*page_size));="" while(address=""> (page_start_address +2))  
  108.     {  
  109.         address_value = (*(__IO uint16_t*)address);  
  110.           
  111.         if(address_value == virt_addr)  
  112.         {  
  113.             *data = (*(__IO uint16_t*)(address-2));  
  114.               
  115.             read_status = 0;  
  116.             break;  
  117.         }else{  
  118.             address = address - 4;  
  119.         }  
  120.     }  
  121.       
  122.     return read_status;  
  123. }  
  124.   
  125.   
  126. /**  
  127.   * @brief  Verify if active page is full and Writes variable in EEPROM.  
  128.   * @param  VirtAddress: 16 bit virtual address of the variable  
  129.   * @param  Data: 16 bit data to be written as variable value  
  130.   * @retval Success or error status:  
  131.   *           - FLASH_COMPLETE: on success  
  132.   *           - PAGE_FULL: if valid page is full  
  133.   *           - NO_VALID_PAGE: if no valid page was found  
  134.   *           - Flash error code: on write Flash error  
  135.   */  
  136. static uint16_t ee_verifypagefullwritevariable(uint16_t virt_addr,uint16_t data)  
  137. {  
  138.     uint16_t status = HAL_OK;  
  139.     uint16_t validpage = PAGE0;  
  140.     uint32_t page_end_address = 0x080107FF;  
  141.       
  142.     /* get valid page for write operation */  
  143.     validpage = ee_findvalidpage(WRITE_IN_VALID_PAGE);  
  144.       
  145.     if(validpage == NO_VALID_PAGE)  
  146.         return NO_VALID_PAGE;  
  147.       
  148.     /* get the valid page end address */  
  149.     page_end_address = (uint32_t)((EEPROM_START_ADDRESS-2) + (uint32_t)((1+validpage)*PAGE_SIZE));  
  150.     /* GET the active page address starting from begining */  
  151.     while(cur_wr_address < page_end_address){  
  152.         if((*(__IO uint32_t*)cur_wr_address) == 0xFFFFFFFF)  
  153.         {  
  154.             status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,  
  155.                                        cur_wr_address,  
  156.                                        data);  
  157.             if(status != HAL_OK)  
  158.                 return status;  
  159.               
  160.             status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,  
  161.                                        cur_wr_address +2,  
  162.                                        virt_addr);  
  163.             cur_wr_address = cur_wr_address + 4;  
  164.             return status;  
  165.         }else  
  166.         {  
  167.             cur_wr_address += 4;  
  168.         }  
  169.     }  
  170.       
  171.     return PAGE_FULL;  
  172. }  
  173.   
  174. /**  
  175.   * @brief  Find valid Page for write or read operation  
  176.   * @param  Operation: operation to achieve on the valid page.  
  177.   *   This parameter can be one of the following values:  
  178.   *     @arg READ_FROM_VALID_PAGE: read operation from valid page  
  179.   *     @arg WRITE_IN_VALID_PAGE: write operation from valid page  
  180.   * @retval Valid page number (PAGE0 or PAGE1) or NO_VALID_PAGE in case  
  181.   *   of no valid page was found  
  182.   */  
  183. uint16_t ee_findvalidpage(uint8_t operation)  
  184. {  
  185.     uint16_t page_status0 = 6,page_status1 = 6;  
  186.       
  187.     /* get page0 actual status */  
  188.     page_status0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);  
  189.       
  190.     /* get page1 actual status */  
  191.     page_status1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);  
  192.       
  193.     /* write or read operation */    
  194.     switch(operation)  
  195.     {  
  196.     case WRITE_IN_VALID_PAGE:  
  197.         if(page_status1 == VALID_PAGE)  
  198.         {  
  199.             if(page_status0 == RECEIVE_DATA){  
  200.                 return PAGE0;  
  201.             }else{  
  202.                 return PAGE1;  
  203.             }  
  204.         }  
  205.         else if(page_status0 == VALID_PAGE)  
  206.         {  
  207.             if(page_status1 == RECEIVE_DATA){  
  208.                 return PAGE1;  
  209.             }else{  
  210.                 return PAGE0;  
  211.             }  
  212.         }  
  213.         else  
  214.         {  
  215.             return NO_VALID_PAGE;  
  216.         }  
  217.           
  218.     case READ_FROM_VALID_PAGE:  
  219.         if(page_status0 == VALID_PAGE)  
  220.         {  
  221.             return PAGE0;  
  222.         }  
  223.         else if(page_status1 == VALID_PAGE)  
  224.         {  
  225.             return PAGE1;  
  226.         }  
  227.         else  
  228.         {  
  229.             return NO_VALID_PAGE;  
  230.         }  
  231.           
  232.     default:  
  233.         return PAGE0;  
  234.     }  
  235. }  
  236.   
  237.   
  238. uint16_t init_cur_wr_address(void)  
  239. {  
  240.     uint16_t validpage = PAGE0;  
  241.     uint32_t page_endaddress;  
  242.       
  243.     /* get valid page for write opteration */  
  244.     validpage = ee_findvalidpage(WRITE_IN_VALID_PAGE);  
  245.       
  246.     /* check if there is no valid page */  
  247.     if(validpage == NO_VALID_PAGE)  
  248.     {  
  249.         cur_wr_address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage*PAGE_SIZE));  
  250.         return NO_VALID_PAGE;  
  251.     }  
  252.       
  253.     cur_wr_address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage*PAGE_SIZE));  
  254.     page_endaddress = (uint32_t)((EEPROM_START_ADDRESS-2) + (uint32_t)((1+validpage)*PAGE_SIZE));  
  255.       
  256.     while(cur_wr_address < page_endaddress)  
  257.     {  
  258.         if((*(__IO uint32_t*)cur_wr_address) == 0xFFFFFFFF){  
  259.             return HAL_OK;  
  260.         }else{  
  261.             cur_wr_address = cur_wr_address + 4;  
  262.         }  
  263.     }  
  264.       
  265.     return PAGE_FULL;  
  266. }  
  267.   
  268.   
  269. /**  
  270.   * @brief  Transfers last updated variables data from the full Page to  
  271.   *   an empty one.  
  272.   * @param  VirtAddress: 16 bit virtual address of the variable  
  273.   * @param  Data: 16 bit data to be written as variable value  
  274.   * @retval Success or error status:  
  275.   *           - FLASH_COMPLETE: on success  
  276.   *           - PAGE_FULL: if valid page is full  
  277.   *           - NO_VALID_PAGE: if no valid page was found  
  278.   *           - Flash error code: on write Flash error  
  279.   */  
  280. uint16_t ee_pagetransfer(uint16_t virt_addr,uint16_t data)  
  281. {  
  282.     uint16_t status = HAL_OK;  
  283.     uint32_t new_page_address = 0x080103FF,old_page_address = 0x08010000;  
  284.     uint16_t validpage = PAGE0,varidx = 0;  
  285.     uint16_t ee_status = 0,read_status = 0;  
  286.       
  287.     validpage = ee_findvalidpage(READ_FROM_VALID_PAGE);  
  288.     if(validpage == PAGE1)  
  289.     {  
  290.         new_page_address = PAGE0_BASE_ADDRESS;  
  291.         old_page_address = PAGE1_BASE_ADDRESS;  
  292.     }  
  293.     else if(validpage == PAGE0)  
  294.     {  
  295.         new_page_address = PAGE1_BASE_ADDRESS;  
  296.         old_page_address = PAGE0_BASE_ADDRESS;          
  297.     }  
  298.     else  
  299.     {  
  300.         return NO_VALID_PAGE;  
  301.     }  
  302.       
  303.     status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,  
  304.                                new_page_address,  
  305.                                RECEIVE_DATA);  
  306.     if(status != HAL_OK)  
  307.         return status;  
  308.       
  309.     init_cur_wr_address();  
  310.     ee_status = ee_verifypagefullwritevariable(virt_addr,data);  
  311.     if(ee_status != HAL_OK)  
  312.         return ee_status;  
  313.       
  314.     for(varidx = 0;varidx<numb_of_var;varidx++) {="" if(virt_add_var_tab[varidx]="" !="virt_addr)" read_status="ee_readvariable(virt_add_var_tab[varidx],&data_var);" if(read_status="" ee_status="ee_verifypagefullwritevariable(virt_add_var_tab[varidx],data_var);" if(ee_status="" return="" ee_status;;="" }="" *="" erase="" the="" old="" page:="" set="" oldpage="" status="" to="" erased="" erase_initstruct.pageaddress="old_page_address;" if(status="" status;="" new_page_address,="" valid_page);="" *************************="" end="" file="" of="" emulation_ee***************************="" <="" pre=""></numb_of_var;varidx++)></numb_of_var;var_idx++)></numb_of_var;var_idx++)>  

四、app_eeprom.h
定义地址宏,及1个初始化API, app_ee_init()

  1. /*  
  2. ********************************************************************************  
  3. * Filename      : app_eeprom.h  
  4. * Version       : V1.00  
  5. * Programmer(s) : qiezhihuai  
  6. ********************************************************************************  
  7. */  
  8.   
  9. #ifndef _APP_EEPROM_H  
  10. #define _APP_EEPROM_H  
  11.   
  12. #ifdef __cplusplus  
  13.     extern "C"{  
  14. #endif  
  15.   
  16.   
  17.           
  18. #include "emulation_ee.h"  
  19.   
  20.   
  21. /* 虚拟地址宏 */  
  22. /* ee init flag,if value = 0 or 0xffff do init virtAddVarTab,else if don't init */  
  23. #define EE_READ_STATUS_VIRT_ADDR        virt_add_var_tab[0]         /* 第一次上电初始化标识,0表示成功初始化完成,1表示没有进行过初始化 */  
  24. #define TEMP_EE_ADDR                    virt_add_var_tab[1]         /* 虚拟地址1中存储的是 温度数据 */  
  25.   
  26. /* 初始化API */  
  27. void app_ee_init(void);  
  28.   
  29.   
  30.   
  31. #ifdef __cplusplus  
  32.     }  
  33. #endif  
  34.       
  35. #endif  


五、app_eeprom.c


定义了虚拟地址表 virt_add_var_tab ,地址值由用户随意定义,有效范围0x0000 ~ 0x7FFF,代码如下:

  1. /*  
  2. ********************************************************************************  
  3. *  
  4. *  
  5. * Filename      : app_eeprom.c  
  6. * Version       : V1.00  
  7. * Programmer(s) : qiezhihuai  
  8. ********************************************************************************  
  9. */  
  10.   
  11.   
  12. #include "app_eeprom.h"  
  13.   
  14.   
  15.   
  16.   
  17.   
  18. /* Virtual address defined by the user: 0xFFFF value is prohibited */  
  19. uint16_t virt_add_var_tab[NUMB_OF_VAR] = {0x0001, 0x0002};  /* 1个数据对应1个虚拟地址 */  
  20.   
  21.   
  22. /* 第一次上电初始化函数 */  
  23. static void virt_add_tab_init(void)  
  24. {  
  25.     uint16_t  read_status;  
  26.     uint16_t  init_flag = 0;  
  27.       
  28.     read_status = ee_readvariable(EE_READ_STATUS_VIRT_ADDR,&init_flag);  
  29.       
  30.     if(read_status == 0)            /* 找到了此地址,说明已经初始化过了 */  
  31.         return;  
  32.   
  33.     /* 没有找到 EE_INIT_FLAG_EE_ADDR 这个地址,说明之前没有执行过初始化操作,执行第一次写入操作*/  
  34.     ee_writevariable(EE_READ_STATUS_VIRT_ADDR,0);           /* write 0 to virture addr EE_INIT_FLAG_EE_ADDR */  
  35.     ee_readvariable(EE_READ_STATUS_VIRT_ADDR,&init_flag);  
  36.       
  37.     if(init_flag == 1)                                      /* 对其他虚拟地址已经写入过数据 */  
  38.         return;  
  39.       
  40.     /* 没有对其他的虚拟地址写入过数据,执行初始化 */  
  41.     ee_writevariable(EE_READ_STATUS_VIRT_ADDR,1);           /* set init_flag = 1 */  
  42.       
  43.     /* 初始化temp_val */  
  44.     ee_writevariable(TEMP_EE_ADDR,32000);                     
  45. }  
  46.   
  47.   
  48. void app_ee_init(void)  
  49. {  
  50.     HAL_FLASH_Unlock();             /* 对flash编程前,必须解锁flash */  
  51.     ee_init();  
  52.     virt_add_tab_init();  
  53.     HAL_FLASH_Lock();               /* 编程结束后,必须锁定flash */  
  54. }  
  55.   
  56. /********************** END OF FILE ******************************************/  


六、main.c
在main函数中调用 app_ee_init()初始化eeprom,然后调用ee_readvariable() 读取地址0x0002的温度数据。当串口收到上位机发送的温度数据时调用ee_writevariable()

函数保存数据。

  1. /* Includes ------------------------------------------------------------------*/  
  2. #include "stm32f1xx.h"  
  3. #include "iwdg.h"  
  4. #include "spi.h"  
  5. #include "usart.h"  
  6. #include "gpio.h"  
  7.   
  8.   
  9.   
  10.   
  11. /* Private function prototypes -----------------------------------------------*/  
  12. void SystemClock_Config(void);  
  13.   
  14. extern uint16_t virt_add_var_tab[NUMB_OF_VAR];      /* 引用app_eeprom.c 中的变量 */  
  15.   
  16.   
  17. int main(void)  
  18. {  
  19.   
  20.   
  21.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  
  22.   HAL_Init();  
  23.   
  24.   /* Configure the system clock */  
  25.   SystemClock_Config();  
  26.   
  27.   /* Initialize all configured peripherals */  
  28.   MX_GPIO_Init();  
  29.  // MX_IWDG_Init();  
  30.   MX_SPI1_Init();  
  31.   MX_USART1_UART_Init();  
  32.     
  33.   /* init eeprom */  
  34.   app_ee_init();  
  35.     
  36.   /* read temp_value from eeprom */  
  37.   HAL_FLASH_Unlock();  
  38.   ee_readvariable(TEMP_EE_ADDR,&temp_value);  
  39.   HAL_FLASH_Lock();  
  40.     
  41.   /* update DAC */  
  42.     START_SPI1();  
  43.     HAL_SPI_Transmit(&hspi1,(uint8_t *)&temp_value,1,5000);  
  44.     STOP_SPI1();   
  45.   
  46.   
  47.   while (1)  
  48.   {  
  49.     if(uart1_ready == SET)  
  50.     {  
  51.         uart1_ready = RESET;  
  52.         uart1_parser();  
  53.     }  
  54.       
  55.     if(t_flag == SET)  
  56.     {  
  57.         t_flag = RESET;  
  58.           
  59.         /* Update DAC out */  
  60.         START_SPI1();  
  61.         HAL_SPI_Transmit(&hspi1,(uint8_t *)&temp_value,1,5000);  
  62.         STOP_SPI1();  
  63.     }  
  64.   }  
  65. }  
  66.   
  67. /** System Clock Configuration  
  68. */  
  69. void SystemClock_Config(void)  
  70. {  
  71.   
  72.   RCC_OscInitTypeDef RCC_OscInitStruct;  
  73.   RCC_ClkInitTypeDef RCC_ClkInitStruct;  
  74.   
  75.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;  
  76.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;  
  77.   RCC_OscInitStruct.HSICalibrationValue = 16;  
  78.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;  
  79.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;  
  80.   HAL_RCC_OscConfig(&RCC_OscInitStruct);  
  81.   
  82.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK  
  83.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;  
  84.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;  
  85.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;  
  86.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  87.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  88.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);  
  89.   
  90.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  
  91.   
  92.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);  
  93.   
  94.   /* SysTick_IRQn interrupt configuration */  
  95.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);  
  96. }  
  97.   
  98.   
  99.   
  100. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/  

谢谢您的观看!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多