stm32的flash操作-HAL库

HAL库手册上都有写

 

 

 

 

 

 把一般会用到的,就那几个函数,上锁,解锁,擦除,读,写

 

uint32_t addr=0x08005000;

确定好读写的地址,注意是32位单片机,变量的类型选对

 

不同单片机有不同的Sector/Page/Bank等概念,这些概念涉及到一次性所能清除区域的大小

 

void FLASH_W(uint32_t addr,uint16_t flash_read){//传入了需要写的flash地址,及写入的内容

       FLASH_EraseInitTypeDef My_Flash;  //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
       HAL_FLASH_Unlock();               //解锁Flash

       My_Flash.TypeErase = FLASH_TYPEERASE_PAGES;  //标明Flash执行页面只做擦除操作
       My_Flash.PageAddress = addr;  //声明要擦除的地址
       My_Flash.NbPages = 1;                        //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值

       uint32_t PageError = 0;                    //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
       HAL_FLASHEx_Erase(&My_Flash, &PageError);  //调用擦除函数擦除

//       uint16_t Write_Flash_Data = my_add;

       HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, flash_read);//这里要注意写入的大小范围,半字?字?双字?


        HAL_FLASH_Lock(); //锁住Flash
}

写的操作涉及到flash的解锁与上锁

 

uint16_t flash_read = *(__IO uint16_t*)( addr );

读的操作就很简单了,直接取值就行。这里取到的值是半字的,2字节的

 

void FLASH_W(uint32_t addr,uint16_t flash_read){
//  uint32_t Robot_Num_Flash_Add = 0x08005000;

       FLASH_EraseInitTypeDef My_Flash;  //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
       HAL_FLASH_Unlock();               //解锁Flash

       My_Flash.TypeErase = FLASH_TYPEERASE_PAGES;  //标明Flash执行页面只做擦除操作
       My_Flash.PageAddress = addr;  //声明要擦除的地址
       My_Flash.NbPages = 1;                        //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值

       uint32_t PageError = 0;                    //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
       HAL_FLASHEx_Erase(&My_Flash, &PageError);  //调用擦除函数擦除

//       uint16_t Write_Flash_Data = my_add;

       HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, flash_read);


        HAL_FLASH_Lock(); //锁住Flash
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    uint32_t addr=0x08005000;
  /* 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();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  uint16_t flash_read = *(__IO uint16_t*)( addr );
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, flash_read);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      //有锁存
      if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){
          HAL_Delay(20);
          if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){
              //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
              flash_read=~flash_read;
              HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, flash_read);
              FLASH_W(addr,flash_read);
              while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0));
          }
      }
  }
  /* USER CODE END 3 */
}

实现功能,每次上电读取特定地址里的值,作为led灯的亮灭取值。且每次按钮按下,将led灯的亮灭状况保存,作为下一次上电使用

posted @ 2021-12-08 14:48  kingzhan  阅读(1009)  评论(0编辑  收藏  举报