09.01_FLASH-MAIN区域读写和擦除
测试步骤
通过调用FLASH_Write()和FLASH_Erase()函数,实现了对Flash存储器的读写和擦除操作。 向flash存储器写入256字节的数据,然后擦除flash存储器,最后再写入数据。 数据为0~255,然后读取flash存储器,最后比较写入和读取的数据是否一致。
实测数据
芯片上电
REG(0x8000) = ffffffff ffffffff ffffffff ffffffff
写入flash
REG(0x8000) = 03020100 07060504 0b0a0908 0f0e0d0c
擦除flash
REG(0x8000) = ffffffff ffffffff ffffffff ffffffff
写入flash
REG(0x8000) = 03020100 07060504 0b0a0908 0f0e0d0c
擦除flash
REG(0x8000) = ffffffff ffffffff ffffffff ffffffff
参考代码
09.01_FLASH_ReadWrite.c
/**
* @brief FLASH-MAIN区域读写和擦除
* @details
* 通过调用FLASH_Write()和FLASH_Erase()函数,实现了对Flash存储器的读写和擦除操作。
* 向flash存储器写入256字节的数据,然后擦除flash存储器,最后再写入数据。
* 数据为0~255,然后读取flash存储器,最后比较写入和读取的数据是否一致。
*/
#include "lks32mc09x_flash.h"
#include "lks32mc09x_sys.h"
uint32_t address = 0x8000;
uint8_t testdata[256];
uint8_t buffer[256];
volatile uint32_t write_flg = 0;
/**
* @brief 主函数
*/
int main(void)
{
SYS_SetPowerFailureDetection(SYS_PVDSEL_OFF);
for (int i = 0; i < 256; i++)
{
testdata[i] = i;
}
// 主循环,防止程序退出
while (1)
{
switch (write_flg)
{
case 0:
break;
case 1:
write_flg = 0;
FLASH_Write(address, testdata, 256); // 写入flash
break;
case 2:
FLASH_Erase(address); // 擦除flash
write_flg = 0;
break;
case 3:
FLASH_Read(address, buffer, 256); // 读取flash
write_flg = 0;
break;
default:
break;
}
}
}
使用到的库函数
库函数部分代码
#define FLASH FLASH0
#define REG_WRITE(reg,mask) reg = (mask)
#define REG_WRITE_BIT(reg,mask,val) reg = ((reg) & ~(mask)) | (val)
#define SYS0 ((SYS_TypeDef *)(SYS_BASE))
/**
* @brief 从指定地址读取数据
*
* @param adr 目标地址
* @param buf 数据缓冲区指针
* @param len 数据长度
*/
void FLASH_Read(uint32_t adr, uint8_t *data, uint32_t len)
{
uint32_t i;
for (i = 0; i < len; i++)
{
data[i] = REG8(adr + i);
}
}
/**
* @brief 向指定地址写入数据
* @param adr 目标地址
* @param data 数据缓冲区指针
* @param len 数据长度
* @note 触发掉电检测后,对flash的操作无效,掉电检测的配置参考SYS_SetPowerFailureDetection
*/
void FLASH_Write(uint32_t adr, uint8_t *data, uint32_t len)
{
uint8_t *p = data;
uint32_t flg = __get_PRIMASK();
__disable_irq();
SYS_WR_PROTECT = 0x7a83;
SYS_FLSP = 0x8f35;
FLASH->CFG |= BIT27 | BIT23;
FLASH->ADDR = adr;
len &= ~3; // 低两位值忽略
for (; len > 0; len -= 4)
{
FLASH->WDATA = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
p += 4;
}
SYS_FLSP = 0;
FLASH->CFG &= ~(BIT27 | BIT23);
SYS_WR_PROTECT = 0;
__set_PRIMASK(flg);
}
/**
* @brief 掉电检测配置
* @param SYS_PVDSEL_x 掉电检测配置值
*/
void SYS_SetPowerFailureDetection(uint32_t SYS_PVDSEL_x)
{
REG_WRITE(SYS0->PROTECT, 0x7a83);
REG_WRITE_BIT(SYS0->AFE_REG0, (BIT11 | BIT12 | BIT13 | BIT14), SYS_PVDSEL_x);
REG_WRITE(SYS0->PROTECT, 0);
}
/**
* @brief 擦除指定扇区
*
* @param adr 目标地址
* @note 触发掉电检测后,对flash的操作无效,掉电检测的配置参考SYS_SetPowerFailureDetection
*/
void FLASH_Erase(uint32_t adr)
{
uint32_t flg = __get_PRIMASK();
__disable_irq();
SYS_WR_PROTECT = 0x7a83;
SYS_FLSE = 0x8fca;
FLASH->CFG |= BIT31;
FLASH->CFG &= ~BIT15;
FLASH->ADDR = adr;
FLASH->ERASE = 0x7654DCBA;
SYS_FLSE = 0;
FLASH->CFG &= ~BIT31;
__set_PRIMASK(flg);
}