#ifndef __FLASH_H__
#define __FLASH_H__
#include <stdio.h>
#include <stdint.h>
#include "main.h"
#include "stm32f1xx_hal_flash.h"
// 注:Stm32f103ret6 芯片RAM 64K, ROM 512K,每页大小2K
#define FLASH_STARTADDR 0x08000000
#define FLASH_SIZE 0x80000 // ROM 512K
#define FLASH_TIMEOUT 5000
#if (FLASH_SIZE >= 0x40000)
#define FLASH_PAGESIZE 0x800
#define FLASH_PAGENUM (FLASH_SIZE / FLASH_PAGESIZE) // 共xx页
#define FLASH_ENDADDR (FLASH_STARTADDR | FLASH_PAGENUM * FLASH_PAGESIZE)
#else
#define FLASH_PAGESIZE 0x400
#define FLASH_PAGENUM (FLASH_SIZE / FLASH_PAGESIZE) // 共xx页
#define FLASH_ENDADDR (FLASH_STARTADDR | FLASH_PAGENUM * FLASH_PAGESIZE)
#endif
#define FLASH_SAVEADDR (FLASH_STARTADDR | ((FLASH_PAGENUM - 1) * FLASH_PAGESIZE))
/*
* 函数名:FlashInit
* 功 能 :初始化Flash
* 参 数 :
* @:
* 返回值:
*/
extern void FlashInit(void);
/*
* 函数名:FlashReadHalfWord
* 功 能 :读半字
* 参 数 :
* @:
* 返回值:
*/
extern int16_t FlashReadHalfWord(uint32_t addr);
/*
* 函数名:FlashReadHalfWords
* 功 能 :从addr开始读取,按半字读取,读取长度为len
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashReadHalfWords(uint32_t addr, uint16_t *data, uint16_t len);
/*
* 函数名:FlashReadWord
* 功 能 :读整字
* 参 数 :
* @:
* 返回值:
*/
extern int32_t FlashReadWord(uint32_t addr);
/*
* 函数名:FlashReadWords
* 功 能 :读整字
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashReadWords(uint32_t addr, uint32_t *data, uint16_t len);
/*
* 函数名:FlashWriteHalfWord
* 功 能 :向addr中写半字
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashWriteHalfWord(uint32_t addr, uint16_t data);
/*
* 函数名:FlashWriteHalfWords
* 功 能 :向addr中按半字无校验的写入长度len的数据
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashWriteHalfWords(uint32_t addr, uint16_t *data, uint16_t len);
/*
* 函数名:FlashWriteWord
* 功 能 :向addr中写一字
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashWriteWord(uint32_t addr, uint32_t data);
/*
* 函数名:FlashWriteWords
* 功 能 :向addr中按半字无校验的写入长度len的数据
* 参 数 :
* @:
* 返回值:
*/
extern int8_t FlashWriteWords(uint32_t addr, uint32_t *data, uint16_t len);
#endif
#include "Flash.h"
/*
* 函数名:FlashInit
* 功 能 :初始化Flash
* 参 数 :
* @:
* 返回值:
*/
void FlashInit(void){
HAL_FLASH_Unlock();
/* 清除flash状态标志位: */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
HAL_FLASH_Lock();
}
/*
* 函数名:FlashReadHalfWord
* 功 能 :读半字
* 参 数 :
* @:
* 返回值:
*/
int16_t FlashReadHalfWord(uint32_t addr){
return *(uint16_t *)addr;
}
/*
* 函数名:FlashReadHalfWords
* 功 能 :从addr开始读取,按半字读取,读取长度为len
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashReadHalfWords(uint32_t addr, uint16_t *data, uint16_t len) {
uint16_t i = 0;
if (NULL == data || 0x00 == len)
return -1;
for (i = 0; i < len; i++) {
data[i] = FlashReadHalfWord(addr);
addr += 2;
}
return 0;
}
/*
* 函数名:FlashReadWord
* 功 能 :读整字
* 参 数 :
* @:
* 返回值:
*/
int32_t FlashReadWord(uint32_t addr){
return *(uint32_t *)addr;
}
/*
* 函数名:FlashReadWords
* 功 能 :读整字
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashReadWords(uint32_t addr, uint32_t *data, uint16_t len){
uint16_t i = 0;
if (NULL == data || 0x00 == len)
return -1;
for (i = 0; i < len; i++) {
data[i] = FlashReadWord(addr);
addr += 4;
}
return 0;
}
/*
* 函数名:FlashWriteHalfWord
* 功 能 :向addr中写半字
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashWriteHalfWord(uint32_t addr, uint16_t data){
if (addr < FLASH_STARTADDR || addr > FLASH_ENDADDR)
return -1;
FLASH_WaitForLastOperation(FLASH_TIMEOUT);
if(HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr, data))
{
printf("Program Half Word Error\n");
return -1;
}
return 0;
}
/*
* 函数名:FlashWriteHalfWords
* 功 能 :向addr中按半字无校验的写入长度len的数据
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashWriteHalfWords(uint32_t addr, uint16_t *data, uint16_t len)
{
uint16_t i = 0;
uint32_t pageerr = 0;
FLASH_EraseInitTypeDef era_flash = {0};
if (addr < FLASH_STARTADDR || addr > FLASH_ENDADDR || NULL == data || 0x00 == len)
return -1;
era_flash.PageAddress = addr;
era_flash.NbPages = 1;
era_flash.TypeErase = FLASH_TYPEERASE_PAGES;
HAL_FLASH_Unlock();
FLASH_WaitForLastOperation(FLASH_TIMEOUT);
if(HAL_OK != HAL_FLASHEx_Erase(&era_flash, &pageerr)){
printf("Half Word Erase Error\n");
return -1;
}
for ( i = 0; i < len; i++)
FlashWriteHalfWord(addr + i * 2, data[i]);
HAL_FLASH_Lock();
return 0;
}
/*
* 函数名:FlashWriteWord
* 功 能 :向addr中写一字
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashWriteWord(uint32_t addr, uint32_t data)
{
if (addr < FLASH_STARTADDR || addr > FLASH_ENDADDR)
return -1;
FLASH_WaitForLastOperation(FLASH_TIMEOUT);
if(HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, data))
{
printf("Program Word Error\n");
return -1;
}
return 0;
}
/*
* 函数名:FlashWriteWords
* 功 能 :向addr中按半字无校验的写入长度len的数据
* 参 数 :
* @:
* 返回值:
*/
int8_t FlashWriteWords(uint32_t addr, uint32_t *data, uint16_t len)
{
uint16_t i = 0;
uint32_t pageerr = 0;
FLASH_EraseInitTypeDef era_flash = {0};
if (addr < FLASH_STARTADDR || addr > FLASH_ENDADDR || NULL == data || 0x00 == len)
return -1;
era_flash.PageAddress = addr;
era_flash.NbPages = 1;
era_flash.TypeErase = FLASH_TYPEERASE_PAGES;
HAL_FLASH_Unlock();
FLASH_WaitForLastOperation(FLASH_TIMEOUT);
if(HAL_OK != HAL_FLASHEx_Erase(&era_flash, &pageerr)){
printf("Word Erase Error\n");
return -1;
}
for ( i = 0; i < len; i++)
FlashWriteWord(addr + i * 4, data[i]);
HAL_FLASH_Lock();
return 0;
}