你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32L0x2自带EEPROM读写分享

[复制链接]
power568 发布时间:2018-1-9 15:24
本帖最后由 creep 于 2018-1-9 16:18 编辑

       STM32L的EEPROM支持字、半字和字节的读写操作。写操作之前自动擦除,如果写的数据为0,则只执行擦除操作。

       使用STM32Cube库对自带的EEPROM进行操作,代码如下:

  1. #define                EPROM_WR_TYPE_BYTE                                ((UNS8)0x00)
  2. #define                EPROM_WR_TYPE_HALF_WORD                ((UNS8)0x01)
  3. #define                EPROM_WR_TYPE_WORD                                ((UNS8)0x02)

  4. #define                EPROM_TEST_ADDR                                (STM_EPROM_ADDR_BASE + 12)
  5. #define                EPROM_TESTE_ADDR                                (STM_EPROM_ADDR_BASE + 32)
  6. #define                EPROM_TESTEE_ADDR                                (STM_EPROM_ADDR_BASE + 61)

  7. //// Unlocks the data memory and FLASH_PECR register access
  8. //// ret :
  9. ////   OK       = 0x00U,
  10. ////   ERROR    = 0x01U,
  11. ////   BUSY     = 0x02U,
  12. ////   TIMEOUT  = 0x03U
  13. UNS8 StmL0xxEpromUnlock(void)
  14. {
  15.         UNS8                ret=0;
  16.         
  17.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Unlock();
  18.         
  19.         return ret;
  20. }

  21. //// Locks the Data memory and FLASH_PECR register access
  22. //// ret :
  23. ////   OK       = 0x00U,
  24. ////   ERROR    = 0x01U,
  25. ////   BUSY     = 0x02U,
  26. ////   TIMEOUT  = 0x03U
  27. UNS8 StmL0xxEpromLock(void)
  28. {
  29.         UNS8                ret=0;
  30.         
  31.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Lock();
  32.         
  33.         return ret;
  34. }

  35. //// Erase a word in data memory.
  36. //// To correctly run this function, the @ref StmL0xxEpromUnlock() function
  37. //// must be called before.
  38. //// addr -- specifies the address to be erased.
  39. //// ret :
  40. ////   OK       = 0x00U,
  41. ////   ERROR    = 0x01U,
  42. ////   BUSY     = 0x02U,
  43. ////   TIMEOUT  = 0x03U
  44. UNS8 StmL0xxEpromWordErase(UNS32 addr)
  45. {
  46.         UNS8                ret=0;
  47.         
  48.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
  49.         {
  50.                 return ret;
  51.         }
  52.         
  53.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Erase(addr);
  54.         
  55.         return ret;
  56. }

  57. //// Program data at a specified address
  58. //// type :
  59. ////   Byte -- 0x00
  60. ////   HalfWord -- 0x01
  61. ////   Word -- 0x02
  62. //// addr -- specifies the address to be erased.
  63. //// ret :
  64. ////   OK       = 0x00U,
  65. ////   ERROR    = 0x01U,
  66. ////   BUSY     = 0x02U,
  67. ////   TIMEOUT  = 0x03U
  68. UNS8 StmL0xxEpromSingleWrite(UNS8 type, UNS32 addr, UNS32 data)
  69. {
  70.         UNS8                ret=0;
  71.         
  72.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
  73.         {
  74.                 return ret;
  75.         }
  76.         
  77.         StmL0xxEpromUnlock();
  78.         ret = (UNS8)HAL_FLASHEx_DATAEEPROM_Program((UNS32)type, addr, data); //// 库函数
  79.         StmL0xxEpromLock();
  80.         
  81.         return ret;
  82. }

  83. //// read a byte at a specified address
  84. //// addr -- specifies the address to be erased.
  85. //// ret :
  86. ////   OK       = 0x00U,
  87. ////   ERROR    = 0x01U,
  88. ////   BUSY     = 0x02U,
  89. ////   TIMEOUT  = 0x03U
  90. void StmL0xxEpromSingleByteRead(UNS32 addr, UNS8 *data)
  91. {
  92.         
  93.         if ( (STM_EPROM_ADDR_BASE>addr) || (STM_EPROM_ADDR_END<addr) )
  94.         {
  95.                 return ;
  96.         }
  97.         
  98.         StmL0xxEpromUnlock();
  99.         *data = *(volatile uint8_t *)(addr);
  100.         StmL0xxEpromLock();
  101. }
复制代码
    测试代码如下:
  1. void EpromTest(void)
  2. {
  3.         UNS8        tmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};
  4.         UNS8        read[8] = {0}, num=0, time=1;
  5.         
  6.         while(5>time)
  7.         {
  8.                 for (num=0; num<8; num++)
  9.                 {
  10.                         tmp[num] *= time;
  11.                         StmL0xxEpromSingleWrite(EPROM_WR_TYPE_BYTE, EPROM_TEST_ADDR+num, (uint32_t)tmp[num]);
  12.                 }
  13.                
  14.                 for (num=0; num<8; num++)
  15.                 {
  16.                         StmL0xxEpromSingleByteRead(EPROM_TEST_ADDR+num, &read[num]);
  17.                         if (tmp[num]!=read[num])
  18.                         {
  19.                                 time = 10;
  20.                         }
  21.                 }
  22.         
  23. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_HALF_WORD, EPROM_TESTEE_ADDR, *(uint16_t *)(&tmp[0])); //// 进入异常中断
  24. ////                StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTEE_ADDR, *(uint32_t *)(&tmp[0]));//// 进入异常中断
  25.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR, *(uint32_t *)(&tmp[0]));
  26.                 StmL0xxEpromSingleWrite(EPROM_WR_TYPE_WORD, EPROM_TESTE_ADDR+4, *(uint32_t *)(&tmp[4]));
  27.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+0, (UNS32*)(&read[0]));
  28.                 StmL0xxEpromSingleByteRead(EPROM_TESTE_ADDR+4, (UNS32*)(&read[4]));
  29.                
  30.                 time ++;
  31.         }
  32. }
复制代码
  






总结:
     1. 字节操作时,传入任何地址参数都可以,读写操作正常;
     2. 但是当半字操作时,如果地址不是2对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
     3. 但是当字操作时,如果地址不是4对齐的,则调用函数StmL0xxEpromSingleWrite时进入HardFault中断;
                 
     调试发现调用HAL_FLASHEx_DATAEEPROM_Program函数时进入异常中断。
     原因是EEPROM在内存结构上实际是以字为单位的:

      Eprom.png      虽然可以进行字节、半字的参数,但是必须保证地址的对其方式——半字操作以2对齐,字操作以4对齐,否则会出错。

     !!!!这个代码的对其方式怎么跟贴代码之前不一样呢,完全左对齐了!!!


收藏 2 评论1 发布时间:2018-1-9 15:24

举报

1个回答
zero99 回答时间:2018-2-1 09:30:02
来晚了,感谢支持,已汇总到1月技术原创
https://www.stmcu.org.cn/module/forum/thread-614550-1-1.html

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版