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

目录

一、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 函数

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint32_t count[3] = {0};	// 定义一个数组用于存储读取的地址
	uint32_t *whole_addr;	// 定义地址指针
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	/* EEPROM 读部分 */
	HAL_FLASHEx_DATAEEPROM_Unlock();	// 解锁
	whole_addr = (uint32_t *)(DATA_EEPROM_BASE + 8);	//DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
	*count = *whole_addr; 	
	HAL_FLASHEx_DATAEEPROM_Lock();	//锁定
	count[0]++;
	/* EEPROM 写部分 */
	HAL_FLASHEx_DATAEEPROM_Unlock();	// 解锁
	HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, DATA_EEPROM_BASE + 8, count[0]);
	printf("count[0] = %d\r\n", count[0]);
	while(count[0]--)
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
		HAL_Delay(500);
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
		HAL_Delay(500);
	}
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

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

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

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

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

(5)实验现象

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

二、EEPROM 接口函数封装

🟡️EEPROM 写函数

/**
  * @brief  EEPROM Write Function EEPROM写函数
  *	@param	addr	EEPROM 地址
					  @arg	地址范围为0-512,地址必须是4的整数倍,因为主函数中是按照'字'写入的
					buf		写入数据的地址
					len		写入数据长度
  * @retval None
  */
void EEPROM_Write(uint32_t addr, uint32_t *buf, uint32_t len)
{
	uint32_t whole_addr;	// 定义地址指针
	HAL_FLASHEx_DATAEEPROM_Unlock();	// 解锁
	whole_addr = (addr + DATA_EEPROM_BASE);
	//DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
	while(len--)
	{
		HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_WORD, whole_addr, *buf++);
		whole_addr += 4;
	}
	HAL_FLASHEx_DATAEEPROM_Lock();	//锁定
}

🟡️EEPROM 读函数

/**
  * @brief  EEPROM Read Function EEPROM读函数
  *	@param	addr	EEPROM 地址
					  @arg	地址范围为0-512,地址必须是4的整数倍,因为主函数中是按照'字'写入的
					buf		写入地址
					len		读取数据长度
  * @retval None
  */
void EEPROM_Read(uint32_t addr, uint32_t *buf, uint32_t len)
{
	uint32_t *whole_addr;	// 定义地址指针
	HAL_FLASHEx_DATAEEPROM_Unlock();	// 解锁
	whole_addr = (uint32_t *)(addr + DATA_EEPROM_BASE);
	//DATA_EEPROM_BASE(0x08080000UL)是FLASHEx_DATAEEPROM的起始地址
	while(len--)
	{
		*buf++ = *whole_addr++; 
	}
	HAL_FLASHEx_DATAEEPROM_Lock();	//锁定
}

🔴EEPROM 接口函数调用实例

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint32_t count[3] = {0};	// 定义一个数组用于存储读取的地址
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	EEPROM_Read(8, count, 2);	// 在EEPROM地址4上读取数据
	count[0]++;
	count[1]++;
	EEPROM_Write(8, count, 2);
	printf("count[0] = %d\r\n", count[0]);
	printf("count[1] = %d\r\n", count[1]);
	while(count[0]--)
	{
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);
		HAL_Delay(500);
		HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);
		HAL_Delay(500);
	}
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

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


三、踩坑日记

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

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

图7        地址

  • 31
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逝灮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值