当前位置:   article > 正文

STM32F4--FLASH读写demo_stm32f4 flash读写例程

stm32f4 flash读写例程

最近在写机器人的姿态解算,需要把一些数据保存到stm32f4的内部Flash中。于是调了一下午Flash,整理出了下面这个demo程序。发现stm32f4的功能还挺强的,

8位、16位、32位、64位的数据都能读写。而且还能写入负数,虽然库里提供的函数写数据的类型是无符号的,我也不知道这是什么原因。

flash.c

  1. #include "flash.h"
  2. /****************************************************************************
  3. * 功 能: 获取地址Address对应的sector编号
  4. * 入口参数:地址
  5. * 出口参数:sector编号
  6. * 说 明:无
  7. * 调用方法:无
  8. ****************************************************************************/
  9. uint16_t Flash_GetSector(uint32_t Address)
  10. {
  11. uint16_t sector = 0;
  12. if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  13. {
  14. sector = FLASH_Sector_0;
  15. }
  16. else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  17. {
  18. sector = FLASH_Sector_1;
  19. }
  20. else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  21. {
  22. sector = FLASH_Sector_2;
  23. }
  24. else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  25. {
  26. sector = FLASH_Sector_3;
  27. }
  28. else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  29. {
  30. sector = FLASH_Sector_4;
  31. }
  32. else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  33. {
  34. sector = FLASH_Sector_5;
  35. }
  36. else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  37. {
  38. sector = FLASH_Sector_6;
  39. }
  40. else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  41. {
  42. sector = FLASH_Sector_7;
  43. }
  44. else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  45. {
  46. sector = FLASH_Sector_8;
  47. }
  48. else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  49. {
  50. sector = FLASH_Sector_9;
  51. }
  52. else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  53. {
  54. sector = FLASH_Sector_10;
  55. }
  56. else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
  57. {
  58. sector = FLASH_Sector_11;
  59. }
  60. return sector;
  61. }
  62. /****************************************************************************
  63. * 功 能: 擦除指定扇区
  64. * 入口参数:SectorNum 扇区号
  65. * 出口参数:无
  66. * 说 明:无
  67. * 调用方法:无
  68. ****************************************************************************/
  69. void Flash_EraseSector(uint16_t SectorNum)
  70. {
  71. FLASH_Unlock();
  72. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  73. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
  74. if (FLASH_EraseSector(SectorNum, VoltageRange_3) != FLASH_COMPLETE) while (1);
  75. FLASH_Lock();
  76. }
  77. /****************************************************************************
  78. * 功 能: 写入长度为length的32位数据
  79. * 入口参数:address:地址
  80. length: 数据长度
  81. data_32:要写入的数据指针
  82. * 出口参数:无
  83. * 说 明:无
  84. * 调用方法:无
  85. ****************************************************************************/
  86. void Flash_Write32BitDatas(uint32_t address, uint16_t length, int32_t* data_32)
  87. {
  88. uint16_t StartSector, EndSector,i;
  89. FLASH_Unlock(); //解锁FLASH后才能向FLASH中写数据。
  90. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  91. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
  92. StartSector = Flash_GetSector(address); //获取FLASH的Sector编号
  93. EndSector = Flash_GetSector(address+4*length);
  94. for (i = StartSector; i < EndSector; i += 8) //每次FLASH编号增加8,可参考上边FLASH Sector的定义。
  95. {
  96. if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE) while (1);
  97. }
  98. for(i=0; i<length; i++)
  99. {
  100. if (FLASH_ProgramWord(address, data_32[i]) == FLASH_COMPLETE) //将DATA_32写入相应的地址。
  101. {
  102. address = address + 4;
  103. }
  104. else
  105. {
  106. while (1);
  107. }
  108. }
  109. FLASH_Lock(); //读FLASH不需要FLASH处于解锁状态。
  110. }
  111. /****************************************************************************
  112. * 功 能: 读取长度为length的32位数据
  113. * 入口参数:address:地址
  114. length: 数据长度
  115. data_32 指向读出的数据
  116. * 出口参数:无
  117. * 说 明:无
  118. * 调用方法:无
  119. ****************************************************************************/
  120. void Flash_Read32BitDatas(uint32_t address, uint16_t length, int32_t* data_32)
  121. {
  122. uint8_t i;
  123. for(i=0; i<length; i++)
  124. {
  125. data_32[i]=*(__IO int32_t*)address;
  126. address=address + 4;
  127. }
  128. }
  129. /****************************************************************************
  130. * 功 能: 写入长度为length的16位数据
  131. * 入口参数:address:地址
  132. length: 数据长度
  133. data_16:要写入的数据指针
  134. * 出口参数:无
  135. * 说 明:无
  136. * 调用方法:无
  137. ****************************************************************************/
  138. void Flash_Write16BitDatas(uint32_t address, uint16_t length, int16_t* data_16)
  139. {
  140. uint16_t StartSector, EndSector,i;
  141. FLASH_Unlock(); //解锁FLASH后才能向FLASH中写数据。
  142. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  143. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
  144. StartSector = Flash_GetSector(address); //获取FLASH的Sector编号
  145. EndSector = Flash_GetSector(address+2*length);
  146. for (i = StartSector; i < EndSector; i += 8) //每次FLASH编号增加8,可参考上边FLASH Sector的定义。
  147. {
  148. if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE) while (1);
  149. }
  150. for(i=0; i<length; i++)
  151. {
  152. if (FLASH_ProgramHalfWord(address, data_16[i]) == FLASH_COMPLETE)
  153. {
  154. address = address + 2;
  155. }
  156. else
  157. {
  158. while (1);
  159. }
  160. }
  161. FLASH_Lock(); //读FLASH不需要FLASH处于解锁状态。
  162. }
  163. /****************************************************************************
  164. * 功 能: 读取长度为length的16位数据
  165. * 入口参数:address:地址
  166. length: 数据长度
  167. data_16 指向读出的数据
  168. * 出口参数:无
  169. * 说 明:无
  170. * 调用方法:无
  171. ****************************************************************************/
  172. void Flash_Read16BitDatas(uint32_t address, uint16_t length, int16_t* data_16)
  173. {
  174. uint8_t i;
  175. for(i=0; i<length; i++)
  176. {
  177. data_16[i]=*(__IO int16_t*)address;
  178. address=address + 2;
  179. }
  180. }
  181. /****************************************************************************
  182. * 功 能: 写入长度为length的8位数据
  183. * 入口参数:address:地址
  184. length: 数据长度
  185. data_8:要写入的数据指针
  186. * 出口参数:无
  187. * 说 明:无
  188. * 调用方法:无
  189. ****************************************************************************/
  190. void Flash_Write8BitDatas(uint32_t address, uint16_t length, int8_t* data_8)
  191. {
  192. uint16_t StartSector, EndSector,i;
  193. FLASH_Unlock(); //解锁FLASH后才能向FLASH中写数据。
  194. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  195. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
  196. StartSector = Flash_GetSector(address); //获取FLASH的Sector编号
  197. EndSector = Flash_GetSector(address+length);
  198. for (i = StartSector; i < EndSector; i += 8) //每次FLASH编号增加8,可参考上边FLASH Sector的定义。
  199. {
  200. if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE) while (1);
  201. }
  202. for(i=0; i<length; i++)
  203. {
  204. if (FLASH_ProgramByte(address, data_8[i]) == FLASH_COMPLETE)
  205. {
  206. address++;
  207. }
  208. else
  209. {
  210. while (1);
  211. }
  212. }
  213. FLASH_Lock(); //读FLASH不需要FLASH处于解锁状态。
  214. }
  215. /****************************************************************************
  216. * 功 能: 读取长度为length的8位数据
  217. * 入口参数:address:地址
  218. length: 数据长度
  219. data_8 指向读出的数据
  220. * 出口参数:无
  221. * 说 明:无
  222. * 调用方法:无
  223. ****************************************************************************/
  224. void Flash_Read8BitDatas(uint32_t address, uint16_t length, int8_t* data_8)
  225. {
  226. uint8_t i;
  227. for(i=0; i<length; i++)
  228. {
  229. data_8[i]=*(__IO int8_t*)address;
  230. address++;
  231. }
  232. }


flash.h
  1. #ifndef __FLASH_H__
  2. #define __FLASH_H__
  3. #include "stm32f4xx.h"
  4. /* Base address of the Flash sectors */
  5. #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
  6. #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
  7. #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
  8. #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
  9. #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
  10. #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
  11. #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
  12. #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
  13. #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
  14. #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
  15. #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
  16. #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
  17. #define FLASH_USER_START_ADDR ADDR_FLASH_SECTOR_9 //用户起始地址,暂定为第十个扇区的起始地址
  18. //API
  19. uint16_t Flash_GetSector(uint32_t Address);
  20. void Flash_EraseSector(uint16_t SectorNum);
  21. void Flash_Write32BitDatas(uint32_t address, uint16_t length, int32_t* data_32);
  22. void Flash_Read32BitDatas(uint32_t address, uint16_t length, int32_t* data_32);
  23. void Flash_Write16BitDatas(uint32_t address, uint16_t length, int16_t* data_16);
  24. void Flash_Read16BitDatas(uint32_t address, uint16_t length, int16_t* data_16);
  25. void Flash_Write8BitDatas(uint32_t address, uint16_t length, int8_t* data_8);
  26. void Flash_Read8BitDatas(uint32_t address, uint16_t length, int8_t* data_8);
  27. #endif

usart.c

  1. #include "usart.h"
  2. /****************************************************************************
  3. * 名 称:void USART_Configuration(void)
  4. * 功 能: UART4配置
  5. * 入口参数:无
  6. * 出口参数:无
  7. * 说 明:无
  8. * 调用方法:无
  9. ****************************************************************************/
  10. void USART_Configuration(void)
  11. {
  12. GPIO_InitTypeDef GPIO_InitStructure;
  13. USART_InitTypeDef USART_InitStructure;
  14. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  16. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17. GPIO_Init(GPIOC, &GPIO_InitStructure);
  18. GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_UART4);
  19. GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_UART4);
  20. USART_InitStructure.USART_BaudRate = 19200;
  21. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  22. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  23. USART_InitStructure.USART_Parity = USART_Parity_No;
  24. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  25. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  26. USART_Init(UART4,&USART_InitStructure);
  27. USART_Cmd(UART4,ENABLE);
  28. }
  29. /****************************************************************************
  30. * 名 称:int fputc(int ch, FILE *f)
  31. * 功 能: 重定向printf到串口
  32. * 入口参数: 略
  33. * 出口参数:略
  34. * 说 明:无
  35. * 调用方法:无
  36. ****************************************************************************/
  37. int fputc(int ch, FILE *f)
  38. {
  39. while (USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);
  40. USART_SendData(UART4, (uint8_t) ch);
  41. while (USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);
  42. return ch;
  43. }
  44. /****************************************************************************
  45. * 名 称:int fgetc(FILE *f)
  46. * 功 能: 重定向scanf到串口
  47. * 入口参数:略
  48. * 出口参数:略
  49. * 说 明:无
  50. * 调用方法:无
  51. ****************************************************************************/
  52. int fgetc(FILE *f)
  53. {
  54. int ch;
  55. while (USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET);
  56. ch = USART_ReceiveData(UART4);
  57. while (USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);
  58. USART_SendData(UART4, (uint8_t) ch);
  59. return ch;
  60. }

usart.h

  1. #ifndef __PRINTF_H__
  2. #define __PRINTF_H__
  3. #include <stdio.h>
  4. #include "stm32f4xx.h"
  5. //供调用的API
  6. void USART_Configuration(void);
  7. #endif


main.c

  1. #include "stm32f4xx.h"
  2. #include "flash.h"
  3. #include "usart.h"
  4. void RCC_Configuration(void)
  5. {
  6. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); /* Enable GPIO clock */
  7. RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); /* Enable USART clock */
  8. }
  9. int32_t data_32_1[]={-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
  10. int32_t data_32_2[10];
  11. int16_t data_16_1[]={1,2,3,4,5,6,7,8,9,10};
  12. int16_t data_16_2[]={0,0,0,0,0,0,0,0,0,0};
  13. int8_t data_8_1[]={1,2,3,4,5,6,7,8,9,10};
  14. int8_t data_8_2[]={0,0,0,0,0,0,0,0,0,0};
  15. int main()
  16. {
  17. uint8_t j;
  18. RCC_Configuration();
  19. USART_Configuration();
  20. printf("\r\n32位数据:");
  21. printf("\r\n擦除前:");
  22. Flash_Read32BitDatas(FLASH_USER_START_ADDR,10,data_32_2);
  23. for(j=0; j<10; j++)
  24. {
  25. printf("%d ",data_32_2[j]);
  26. }
  27. Flash_EraseSector(FLASH_Sector_9);
  28. printf("\r\n擦除后:");
  29. Flash_Read32BitDatas(FLASH_USER_START_ADDR,10,data_32_2);
  30. for(j=0; j<10; j++)
  31. {
  32. printf("%d ",data_32_2[j]);
  33. }
  34. printf("\r\n读写Flash后:");
  35. Flash_Write32BitDatas(FLASH_USER_START_ADDR, 10, data_32_1);
  36. Flash_Read32BitDatas(FLASH_USER_START_ADDR,10,data_32_2);
  37. for(j=0; j<10; j++)
  38. {
  39. printf("%d ",data_32_2[j]);
  40. }
  41. printf("\r\n16位数据:");
  42. printf("\r\n擦除前:");
  43. Flash_Read16BitDatas(FLASH_USER_START_ADDR,10,data_16_2);
  44. for(j=0; j<10; j++)
  45. {
  46. printf("%d ",data_16_2[j]);
  47. }
  48. Flash_EraseSector(FLASH_Sector_9);
  49. printf("\r\n擦除后:");
  50. Flash_Read16BitDatas(FLASH_USER_START_ADDR,10,data_16_2);
  51. for(j=0; j<10; j++)
  52. {
  53. printf("%d ",data_16_2[j]);
  54. }
  55. printf("\r\n读写Flash后:");
  56. Flash_Write16BitDatas(FLASH_USER_START_ADDR, 10, data_16_1);
  57. Flash_Read16BitDatas(FLASH_USER_START_ADDR,10,data_16_2);
  58. for(j=0; j<10; j++)
  59. {
  60. printf("%d ",data_16_2[j]);
  61. }
  62. printf("\r\n8位数据:");
  63. printf("\r\n擦除前:");
  64. Flash_Read8BitDatas(FLASH_USER_START_ADDR,10,data_8_2);
  65. for(j=0; j<10; j++)
  66. {
  67. printf("%d ",data_8_2[j]);
  68. }
  69. Flash_EraseSector(FLASH_Sector_9);
  70. printf("\r\n擦除后:");
  71. Flash_Read8BitDatas(FLASH_USER_START_ADDR,10,data_8_2);
  72. for(j=0; j<10; j++)
  73. {
  74. printf("%d ",data_8_2[j]);
  75. }
  76. printf("\r\n读写Flash后:");
  77. Flash_Write8BitDatas(FLASH_USER_START_ADDR, 10, data_8_1);
  78. Flash_Read8BitDatas(FLASH_USER_START_ADDR,10,data_8_2);
  79. for(j=0; j<10; j++)
  80. {
  81. printf("%d ",data_8_2[j]);
  82. }
  83. while(1);
  84. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50675
推荐阅读
  

闽ICP备14008679号