#include "stm32f10x.h"
#include
/* STM32 内部 FLASH 配置 */
#define STM32_FLASH_SIZE 512 /* 所选STM32的FLASH容量大小(单位为K) */
#if STM32_FLASH_SIZE < 256
#define STM_SECTOR_SIZE 1024 /* < 256为1K字节页, >=256 为2K页 */
#else
#define STM_SECTOR_SIZE 2048
#endif
/* 应用程序区域 */
#define APP_REGION (0x8000000 + 0x80000 - STM_SECTOR_SIZE)
/* RCC时钟配置 */
void RCC_config()
{
ErrorStatus HSEStartUpStatus;
/* RCC寄存器设置为默认配置 */
RCC_DeInit();
/* 打开外部高速时钟 */
RCC_HSEConfig(RCC_HSE_ON);
/* 等待外部高速时钟稳定 */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* 设置HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* 设置PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* 设置PCLK1 = HCLK / 2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* 设置FLASH代码延时 */
FLASH_SetLatency(FLASH_Latency_2);
/* 使能预取址缓存 */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* 设置PLL时钟源为HSE倍频9 72MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* 使能PLL */
RCC_PLLCmd(ENABLE);
/* 等待PLL稳定 */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
/* 设置PLL为系统时钟源 */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* 等待系统时钟源切换到PLL */
while(RCC_GetSYSCLKSource() != 0x08);
}
}
/* 扇区缓冲区 */
static uint8_t flash_buf[STM_SECTOR_SIZE];
/* 读flash */
void read_flash(uint32_t addr, uint8_t *buf, uint16_t size)
{
uint16_t i;
for(i = 0; i < size; i++)
{
buf[i] = *(__IO uint8_t *)(addr + i);
}
}
/* 写flash */
void write_flash(uint32_t addr, uint8_t *buf, uint16_t size)
{
uint32_t addr_base;
uint16_t len;
uint16_t i;
/* 检查地址合法性 */
if(addr < FLASH_BASE ||(addr >= (FLASH_BASE + 1024 * STM32_FLASH_SIZE)))
assert_param(0);
/* 将数据循环写入flash */
while(size)
{
/* 扇区基地址 */
addr_base = (addr / STM_SECTOR_SIZE) * STM_SECTOR_SIZE;
/* 读出整个扇区内容 */
read_flash(addr_base, flash_buf, STM_SECTOR_SIZE);
/* 需要写入的长度 */
len = ((addr + size) > (addr_base + STM_SECTOR_SIZE)) ? (addr_base + STM_SECTOR_SIZE - addr) : size;
/* 将需要改变的内容替换掉 */
memcpy(flash_buf + addr - addr_base, buf, len);
/* 解锁 */
FLASH_Unlock();
/* 擦除整片扇区 */
FLASH_ErasePage(addr_base);
/* 写使能 */
FLASH->CR &= FLASH_CR_OPTWRE;
/* 重新将内容写入扇区 */
for(i = 0; i < STM_SECTOR_SIZE / 2; i++, addr_base += 2) /* 从头写到尾 */
FLASH_ProgramHalfWord(addr_base, *((uint16_t *)flash_buf + i));
/* 锁定 */
FLASH_Lock();
/* 将数据偏移len */
addr += len;
buf += len;
size -= len;
}
}
int main()
{
uint8_t buf[5] = {1, 2, 3, 4, 5};
uint8_t test[5];
/* 时钟配置 */
RCC_config();
write_flash(APP_REGION, buf, 5);
read_flash(APP_REGION, test, 5);
while(1)
{
}
}
上一篇:STM32之SDIO例程
下一篇:STM32之内部FLASH原理
推荐阅读最新更新时间:2024-03-16 16:25