使用的是STM32F0单片机
使用cubemx 4.1.0.0版本
keil5 5.32.00
stm32 hal库+EasyFlash数据库完成片内FLASH的读写工作
STM32 实现内部Flash的读写(HAL库版)
1、写入flash数据之前需要对flash进行解锁操作,写完之后还要锁住:
HAL_FLASH_Unlock(); //解锁Flash
HAL_FLASH_Lock(); //锁住Flash
2、 对指定的页进行擦除,才写入数据
uint32_t PageError = 0; // 设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
HAL_FLASHEx_Erase(My_Flash, &PageError); // 调用擦除函数擦除
3、写入flash操作
uint32_t Write_Flash_Data = 0;
Write_Flash_Data = buf[i]; //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address+bass_address+add, Write_Flash_Data);
4、读取flash
uint32_t flash_data = 0xf;
flash_data = *(__IO uint32_t*)( address+bass_address ); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数据,一次读取两个字节,*(__IO uint32_t *)就一次读4个字节
return flash_data;
onchipflash.h:
#ifndef ONCHIPFLASH_H
#define ONCHIPFLASH_H
#include "main.h"
#define biggest_address 64
uint32_t wirte_flash(uint32_t *buf, int32_t buf_len, uint32_t bass_address, uint32_t address);
uint32_t read_flash(uint32_t *buf, int32_t buf_len, uint32_t bass_address, uint32_t address);
void test_fun(void);
#endif
onchipflash.c:
#include "onchipflash.h"
#include "main.h"
#include "stm32f0xx_hal.h"
#include "stdio.h"
void unlock_flash()
{
HAL_FLASH_Unlock(); //解锁Flash
}
void lock_flash()
{
HAL_FLASH_Lock(); //锁住Flash
}
uint32_t erase_flash(FLASH_EraseInitTypeDef *My_Flash)
{
uint32_t PageError = 0; //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址
if(HAL_OK != HAL_FLASHEx_Erase(My_Flash, &PageError)) //调用擦除函数擦除
{
return PageError;
}
else
{
return HAL_OK;
}
}
void wirte_flash_16bit(uint32_t bass_address, uint32_t address, uint16_t data)
{
FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
My_Flash.PageAddress = bass_address; //声明要擦除的地址
My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
unlock_flash();
erase_flash(&My_Flash);
uint16_t Write_Flash_Data = data; //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address+bass_address, Write_Flash_Data);
lock_flash();
}
uint16_t read_flash_16bit(uint32_t bass_address, uint32_t address)
{
uint16_t flash_data = 0xf;
flash_data = *(__IO uint16_t*)( address+bass_address ); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数据,一次读取两个字节,*(__IO uint32_t *)就一次读4个字节
return flash_data;
}
void wirte_flash_32bit(uint32_t bass_address, uint32_t address, uint32_t data)
{
FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
My_Flash.PageAddress = bass_address; //声明要擦除的地址
My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
unlock_flash();
erase_flash(&My_Flash);
uint32_t Write_Flash_Data = data; //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address+bass_address, Write_Flash_Data);
lock_flash();
}
uint32_t read_flash_32bit(uint32_t bass_address, uint32_t address)
{
uint32_t flash_data = 0xf;
flash_data = *(__IO uint32_t*)( address+bass_address ); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数据,一次读取两个字节,*(__IO uint32_t *)就一次读4个字节
return flash_data;
}
uint32_t wirte_flash(uint32_t *buf, int32_t buf_len, uint32_t bass_address, uint32_t address)
{
uint32_t add=0;
uint32_t Write_Flash_Data = 0;
FLASH_EraseInitTypeDef My_Flash; //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash
My_Flash.TypeErase = FLASH_TYPEERASE_PAGES; //标明Flash执行页面只做擦除操作
My_Flash.PageAddress = bass_address; //声明要擦除的地址
My_Flash.NbPages = 1; //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值
if(buf_len>biggest_address)
{
return HAL_ERROR;
}
unlock_flash();
erase_flash(&My_Flash);
for(int i =0; i<buf_len; i++)
{
Write_Flash_Data = buf[i]; //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address+bass_address+add, Write_Flash_Data);
add = add + 0x04;
if(add>=0x0f)
{
add = 0x00;
}
}
lock_flash();
return HAL_OK;
}
uint32_t read_flash(uint32_t *buf, int32_t buf_len, uint32_t bass_address, uint32_t address)
{
uint32_t add=0;
for(int i =0; i<buf_len; i++)
{
buf[i] = read_flash_32bit(bass_address, address+add);
add = add + 0x04;
if(add>=0x0f)
{
add = 0x00;
}
}
return HAL_OK;
}
void test_fun()
{
uint32_t buf[4] = {0x1234567a, 0x2234567b, 0x3234567c, 0x4234567d};
wirte_flash(buf, 4 , 0x08005000, 0x00);
read_flash(buf, 4 , 0x08005000, 0x00);
printf("0x%x 0x%x 0x%x 0x%x\r\n", buf[0], buf[1], buf[2], buf[3]);
//wirte_flash_32bit(0x08005000, 0x00, 0x12345678);
//printf("%d ID_num:0x%x\r\n", 0x00, read_flash_32bit(0x08005000, 0x0c));
}