读写flash的 .C 和 .h文件
flash.h
#ifndef __FLASH_H
#define __FLASH_H
#include "sys.h"
void FLASH_W(u32 add,u16 dat);
u16 FLASH_R(u32 add);
#endif
flash.c
//操作一定要先擦后写。
//每页是1024个地址,起始地址0x08000000
//擦除操作以页为单位,写操作则必须以16位宽度为单位,允许跨页写入。
//STM32内置FLASH擦或写时,必须打开外部/内部高速振荡器。
//FLASH可多次擦写10万次,不可死循环擦写。
//擦写时要避开用户程序存储区的区域,否则会擦掉用户程序导致错误。
//擦除一页要10ms(对于1k大小的一页),比较慢。而且不能单个字节的擦写
//基本顺序是:解锁->清除标志位(可以不要)->擦除->写半字->清楚标志位(也可以不要)->上锁。
#include "flash.h"
//FLASH写入数据
void FLASH_W(u32 add,u16 dat){ //参数1:32位FLASH地址。参数2:16位数据
// RCC_HSICmd(ENABLE); //打开HSI时钟
FLASH_Unlock(); //解锁FLASH编程擦除控制器
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
/*********************************************************************************
// FLASH_FLAG_BSY FLASH忙标志位
// FLASH_FLAG_EOP FLASH操作结束标志位
// FLASH_FLAG_PGERR FLASH编写错误标志位
// FLASH_FLAG_WRPRTERR FLASH页面写保护错误标净
**********************************************************************************/
FLASH_ErasePage(add); //擦除指定地址页
FLASH_ProgramHalfWord(add,dat); //从指定页的addr地址开始写
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
FLASH_Lock(); //锁定FLASH编程擦除控制器
}
//FLASH读出数据
u16 FLASH_R(u32 add){ //参数1:32位读出FLASH地址。返回值:16位数据
u16 a;
a = *(u16*)(add);//从指定页的addr地址开始读
return a;
}
读写FLASH设置LED的main函数
/*********************************************************************************************
程序名: STM32F103读写FLASH改变LED状态程序
硬件支持: STM32F103C8 外部晶振8MHz RCC函数设置主频72MHz
修改日志:
说明:
# 本模板加载了STM32F103内部的RCC时钟设置,并加入了利用滴答定时器的延时函数。
# 可根据自己的需要增加或删减。
*********************************************************************************************/
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "flash.h"
#define FLASH_START_ADDR 0x0801f000 //写入flash的起始地址
int main (void){//主程序
u16 a; //定义变量
//初始化程序
RCC_Configuration(); //时钟设置
LED_Init();//LED初始化
KEY_Init();//按键初始化
a = FLASH_R(FLASH_START_ADDR);//从指定页的地址读FLASH
GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上)
//主循环
while(1){
//示例4:有锁存
if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
delay_ms(20); //延时20ms去抖动
if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
//在2个LED上显示二进制加法
a++; //变量加1
if(a>3){ //当变量大于3时清0
a=0;
}
GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上)
FLASH_W(FLASH_START_ADDR,a); //从指定页的地址写入FLASH
while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开
}
}
}
}
/*
【变量定义】
u32 a; //定义32位无符号变量a
u16 a; //定义16位无符号变量a
u8 a; //定义8位无符号变量a
vu32 a; //定义易变的32位无符号变量a
vu16 a; //定义易变的 16位无符号变量a
vu8 a; //定义易变的 8位无符号变量a
uc32 a; //定义只读的32位无符号变量a
uc16 a; //定义只读 的16位无符号变量a
uc8 a; //定义只读 的8位无符号变量a
#define ONE 1 //宏定义
delay_us(1); //延时1微秒
delay_ms(1); //延时1毫秒
delay_s(1); //延时1秒
*/