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灯的亮灭状况保存,作为下一次上电使用