首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【蓝桥杯——物联网设计与开发】基础模块5 - EEPROM读写

  • 25-03-06 11:26
  • 2113
  • 12509
blog.csdn.net

目录

一、EEPROM

(1)板载 EEPROM

(2)接口函数

(3)STM32CubeMX 软件配置

(4)代码编写

(5)实验现象

二、EEPROM 接口函数封装

三、踩坑日记


一、EEPROM

(1)板载 EEPROM

        EEPROM(Electrically Erasable Programmable read only memory)是指带电可擦可编程只读存储器,掉电后数据不丢失,使用方便,可重复擦写,电擦除。

        STM32L071 系列提供了高达6千字节的 EEPROM,对 EEPROM 进行编程时采用在按字、半字或字节,可以页执行擦除操作。

图1        板载存储资源

(2)接口函数

        ?EEPROM 解锁函数

HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void)

        解锁数据存储器和 FLASH_PECR 寄存器访问;

  • 启用数据EEPROM访问和闪存程序擦除控制寄存器访问;
  • 在读写 EEPROM 之前都需要调用该函数;

        ?EEPROM 锁定函数

HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void)

        锁定数据存储器和​​​​​​​ FLASH_PECR 寄存器访问;

  • 禁用数据 EEPROM 访问和闪存程序擦除控制寄存器访问;
  • 推荐在读写操作后使用以保护 DATA_EEPROM 免受可能的意外操作;

        ?EEPROM 写函数

HAL_StatusTypeDef   HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)

参数说明:

  • TypeProgram:用于区分要写入的数据类型,取值有:

                - FLASH_TYPEPROGRAMDATA_BYTE (字节:8位)

                - FLASH_TYPEPROGRAMDATA_HALFWORD(字节:16位)

                - FLASH_TYPEPROGRAMDATA_WORD(字节:32位)

  • Address:用于设置要写入数据 FLASHEx_DATAEEPROM地址;
  • Data:写入的数据;


(3)STM32CubeMX 软件配置

?“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出  一文中有讲解,这里不再赘述❗️

1️⃣点击引脚 PC15 → 选择 GPIO_Output 模式(此处默认为推挽输出);

图2        LD5 引脚配置

2️⃣点击 "GPIO" → 点击引脚 PC15 → 将 "GPIO output level" 栏修改为 "High",即将 PC15 引脚初始化为高电平;

⚠️此处修改不是必须的,应当根据题意要求进行配置,这里默认为上电熄灭;

图3        LD5 初始化配置

3️⃣点击左侧 "Connectivity" → 选择 "USART2"  → 模式选择 "Asynchronous" (异步通信模式),不使能硬件流控制;

图4        USART2 模式配置

4️⃣在 "Parameter Settings" 中对串口参数进行修改(具体请根据题目要求修改);

  • 波特率9600Bit/s
  • 8位数据位
  • 无奇偶校验
  • 1位停止位
  • 使能接收和发送
  • 16倍过采样
图5        USART2 参数配置


5️⃣生成代码即可;

(4)代码编写

?️main 函数

  1. /**
  2. * @brief The application entry point.
  3. * @retval int
  4. */
  5. int main(void)
  6. {
  7. /* USER CODE BEGIN 1 */
  8. uint32_t count[3] = {0}; // 定义一个数组用于存储读取的地址
  9. uint32_t *whole_addr; // 定义地址指针
  10. /* USER CODE END 1 */
  11. /* MCU Configuration--------------------------------------------------------*/
  12. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  13. HAL_Init();
  14. /* USER CODE BEGIN Init */
  15. /* USER CODE END Init */
  16. /* Configure the system clock */
  17. SystemClock_Config();
  18. /* USER CODE BEGIN SysInit */
  19. /* USER CODE END SysInit */
  20. /* Initialize all configured peripherals */
  21. MX_GPIO_Init();
  22. MX_USART2_UART_Init();
  23. /* USER CODE BEGIN 2 */
  24. /* EEPROM 读部分 */
  25. HAL_FLASHEx_DATAEEPROM_Unlock(); // 解锁
  26. whole_addr = (uint32_t *)(DATA_EEPROM_BASE + 8); //DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
  27. *count = *whole_addr;
  28. HAL_FLASHEx_DATAEEPROM_Lock(); //锁定
  29. count[0]++;
  30. /* EEPROM 写部分 */
  31. HAL_FLASHEx_DATAEEPROM_Unlock(); // 解锁
  32. HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, DATA_EEPROM_BASE + 8, count[0]);
  33. printf("count[0] = %d\r\n", count[0]);
  34. while(count[0]--)
  35. {
  36. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
  37. HAL_Delay(500);
  38. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
  39. HAL_Delay(500);
  40. }
  41. /* USER CODE END 2 */
  42. /* Infinite loop */
  43. /* USER CODE BEGIN WHILE */
  44. while (1)
  45. {
  46. /* USER CODE END WHILE */
  47. /* USER CODE BEGIN 3 */
  48. }
  49. /* USER CODE END 3 */
  50. }

?“串口重定向” 在【蓝桥杯——物联网设计与开发】基础模块4 - 串行通信  一文中有讲解,这里不再赘述❗️

  1. 在初始化时,在 EEPROM 地址8中读出一个字的数据存入 count,并将该数据 +1 后写会该地址;
  2. 通过串口将该数据打印出来;
  3. 并且根据数值闪烁 LD5;

⚠️注意:DATA_EEPROM_BASE(0x08080000UL) 是FLASHEx_DATAEEPROM的起始地址,所以我们写入 EEPROM 的地址需要添加该基地址❗️

        由于库函数中没有提供专用的读函数,这次采用指针的方式,读取目标地址上的值即可;

(5)实验现象

图6        实验现象
  • 每一次板子上电后,串口打印出 EEPROM 中的值,并将该值进行 +1 处理;
  • LD5 根据数值进行间隔 1s 的亮灭闪烁;

二、EEPROM 接口函数封装

?️EEPROM 写函数

  1. /**
  2. * @brief EEPROM Write Function EEPROM写函数
  3. * @param addr EEPROM 地址
  4. @arg 地址范围为0-512,地址必须是4的整数倍,因为主函数中是按照'字'写入的
  5. buf 写入数据的地址
  6. len 写入数据长度
  7. * @retval None
  8. */
  9. void EEPROM_Write(uint32_t addr, uint32_t *buf, uint32_t len)
  10. {
  11. uint32_t whole_addr; // 定义地址指针
  12. HAL_FLASHEx_DATAEEPROM_Unlock(); // 解锁
  13. whole_addr = (addr + DATA_EEPROM_BASE);
  14. //DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
  15. while(len--)
  16. {
  17. HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, whole_addr, *buf++);
  18. whole_addr += 4;
  19. }
  20. HAL_FLASHEx_DATAEEPROM_Lock(); //锁定
  21. }

?️EEPROM 读函数

  1. /**
  2. * @brief EEPROM Read Function EEPROM读函数
  3. * @param addr EEPROM 地址
  4. @arg 地址范围为0-512,地址必须是4的整数倍,因为主函数中是按照'字'写入的
  5. buf 写入地址
  6. len 读取数据长度
  7. * @retval None
  8. */
  9. void EEPROM_Read(uint32_t addr, uint32_t *buf, uint32_t len)
  10. {
  11. uint32_t *whole_addr; // 定义地址指针
  12. HAL_FLASHEx_DATAEEPROM_Unlock(); // 解锁
  13. whole_addr = (uint32_t *)(addr + DATA_EEPROM_BASE);
  14. //DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
  15. while(len--)
  16. {
  17. *buf++ = *whole_addr++;
  18. }
  19. HAL_FLASHEx_DATAEEPROM_Lock(); //锁定
  20. }

?EEPROM 接口函数调用实例

  1. /**
  2. * @brief The application entry point.
  3. * @retval int
  4. */
  5. int main(void)
  6. {
  7. /* USER CODE BEGIN 1 */
  8. uint32_t count[3] = {0}; // 定义一个数组用于存储读取的地址
  9. /* USER CODE END 1 */
  10. /* MCU Configuration--------------------------------------------------------*/
  11. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  12. HAL_Init();
  13. /* USER CODE BEGIN Init */
  14. /* USER CODE END Init */
  15. /* Configure the system clock */
  16. SystemClock_Config();
  17. /* USER CODE BEGIN SysInit */
  18. /* USER CODE END SysInit */
  19. /* Initialize all configured peripherals */
  20. MX_GPIO_Init();
  21. MX_USART2_UART_Init();
  22. /* USER CODE BEGIN 2 */
  23. EEPROM_Read(8, count, 2); // 在EEPROM地址4上读取数据
  24. count[0]++;
  25. count[1]++;
  26. EEPROM_Write(8, count, 2);
  27. printf("count[0] = %d\r\n", count[0]);
  28. printf("count[1] = %d\r\n", count[1]);
  29. while(count[0]--)
  30. {
  31. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
  32. HAL_Delay(500);
  33. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
  34. HAL_Delay(500);
  35. }
  36. /* USER CODE END 2 */
  37. /* Infinite loop */
  38. /* USER CODE BEGIN WHILE */
  39. while (1)
  40. {
  41. /* USER CODE END WHILE */
  42. /* USER CODE BEGIN 3 */
  43. }
  44. /* USER CODE END 3 */
  45. }

此处测试写两个数据,实验现象正常;


三、踩坑日记

        ?写函数中地址参数需为4的整数倍,因为主函数中是按照'字'写入的,否则系统会卡死在 HAL_FLASHEx_DATAEEPROM_Program 函数中;

        ⭐在多数据写入时,传入函数 HAL_FLASHEx_DATAEEPROM_Program 的地址参数应该➕4;

图7        地址

注:本文转载自blog.csdn.net的逝灮的文章"https://blog.csdn.net/m0_63116406/article/details/135699706"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top