STM32L031写Flash不使用HAL库

解锁

void flash_unlock(void)
{
  /* (1) Wait till no operation is on going */
	/* (2) Check if the PELOCK is unlocked */
	/* (3) Perform unlock sequence */
	while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
	{
	/* For robust implementation, add here time-out management */
	}
	if ((FLASH->PECR & FLASH_PECR_PELOCK) != 0) /* (2) */
	{
	 FLASH->OPTKEYR = 0xFBEAD9C8;
	 FLASH->OPTKEYR = 0x24252627;
	 FLASH->PEKEYR = 0x89ABCDEFU;
   FLASH->PEKEYR = 0x02030405U;
	}
	FLASH->PRGKEYR = 0x8C9DAEBF;
  FLASH->PRGKEYR = 0x13141516;
}

擦除,这个芯片每页是128字节,别当成256

void flash_erase(void)
{
 uint32_t addr = 0;
  
  /* 解锁flash */
  __disable_irq();
  flash_unlock();
  
  /* 擦除对应扇区 */
  for(addr = UPDATE_ADDR; addr < END_ADDR; addr += 128)
  {
    FLASH->PECR |= FLASH_PECR_ERASE | FLASH_PECR_PROG; /* (1) */
	 *(__IO uint32_t *)addr = (uint32_t)0; /* (2) */
	 while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (3) */
	 {
	 /* For robust implementation, add here time-out management */
	 }
	 if ((FLASH->SR & FLASH_SR_EOP) != 0) /* (4) */
	 {
	 FLASH->SR = FLASH_SR_EOP; /* (5) */
	 }
	 else
	 {
	 /* Manage the error cases */
	 }
	 FLASH->PECR &= ~(FLASH_PECR_ERASE | FLASH_PECR_PROG); /* (6) */
  }
  
  /* 加锁flash */
  while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
	{
	 /* For robust implementation, add here time-out management */
	}
	FLASH->PECR |= FLASH_PECR_PELOCK; /* (2) */
  __enable_irq();
}

写Flash

void flash_write(uint32_t addr, uint8_t* data, uint16_t len)
{
	uint32_t old_addr = addr;
	uint32_t i = 0;

	__disable_irq();
  flash_unlock();
  
  /* 写数据 */
  while(1)
	{
		/* (1) Perform the data write (32-bit word) at the desired address */
		/* (2) Wait until the BSY bit is reset in the FLASH_SR register */
		/* (3) Check the EOP flag in the FLASH_SR register */
		/* (4) clear it by software by writing it at 1 */
		*(__IO uint32_t*)(addr + UPDATE_ADDR + i) = ((uint32_t)data[i+3]<<24)+((uint32_t)data[i+2]<<16)+((uint32_t)data[i+1]<<8)+((uint32_t)data[0]);
		while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (2) */
		{
		 /* For robust implementation, add here time-out management */
		}
		if ((FLASH->SR & FLASH_SR_EOP) != 0) /* (3) */
		{
		 FLASH->SR = FLASH_SR_EOP; /* (4) */
		}
		LL_mDelay(1);
		i+=4;
		if(i>=len)
		{
			break;
		}
	}
  /* 加锁flash */
  while ((FLASH->SR & FLASH_SR_BSY) != 0) /* (1) */
	{
	 /* For robust implementation, add here time-out management */
	}
	FLASH->PECR |= FLASH_PECR_PELOCK; /* (2) */
	
	flash_test_read(old_addr);
	__enable_irq();
}

 

以下是使用HAL库STM32L431微控制器上读内部Flash的详细步骤和完整代码案例: 步骤1:打开STM32CubeMX并选择STM32L431微控制器。然后在“Pinout & Configuration”选项卡中配置Flash的引脚和时钟。 步骤2:在“Project Manager”选项卡中选择“Generate Code”按钮以生成代码。 步骤3:在生成的代码中打开“main.c”文件。 步骤4:在“main.c”文件中添加以下代码以初始化Flash: ```c HAL_FLASH_Unlock(); FLASH_Erase_Sector(FLASH_SECTOR_2, VOLTAGE_RANGE_3); HAL_FLASH_Lock(); ``` 这将解锁Flash并擦除扇区2。 步骤5:使用以下代码向Flash入数据: ```c uint32_t Address = 0x08008000; uint32_t Data = 0x12345678; HAL_FLASH_Unlock(); if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, Data) == HAL_OK) { // Data has been successfully written to Flash } HAL_FLASH_Lock(); ``` 这将在Flash的地址0x08008000处入数据0x12345678。 步骤6:使用以下代码从Flash中读取数据: ```c uint32_t Address = 0x08008000; uint32_t Data; Data = *(uint32_t*)Address; ``` 这将从Flash的地址0x08008000处读取数据并将其存储在变量Data中。 完整代码示例: ```c #include "main.h" #include "stm32l4xx_hal.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); uint32_t Address = 0x08008000; uint32_t Data = 0x12345678; HAL_FLASH_Unlock(); if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, Data) == HAL_OK) { // Data has been successfully written to Flash } HAL_FLASH_Lock(); uint32_t ReadData = *(uint32_t*)Address; while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); } ``` 请注意,此示例代码仅入和读取了一个32位数据。您可以根据自己的需求修改代码以读更多数据。此外,还应该添加错误处理程序以在出现错误时通知用户。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花开花落的个人博客

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值