Flash闪存的使用
杜洋工作室 www.DoYoung.net
洋桃电子 www.DoYoung.net/YT
- 在此声明一下所有代码均为 杜洋工作室 的不允许复制,转发等,本人只是在此程序上进行理解和注释。
上一次的笔记是在洋桃开发板上进行用OLED0561 显示器的使用,实现小时钟功能。对OLED屏幕有兴趣可以去看看:
https://blog.csdn.net/qq_40546576/article/details/99071244
本次主要讲的是Flash闪存的使用。由于本次特殊,需要截取部分图片进行讲解,可能造成了观看不适,请大家谅解!谢谢。
一、基本功能理解
存储器,一般存储器分为RAM,ROM,也就是运行内存(ram)和程序存储器(rom)。
运行内存(ram):是存放cpu时时刻刻运算的结果等等,速度快,一旦掉电就没有信息了。
程序存储器(rom):是存放程序,和大型的数据,相对与ram速度会慢些,但是掉电不失去信息。
Flash是属于程序存储器(rom)一类,在stm32中Flash还分有NOR Flash和NAND Flash。二者的区别简单说,就是NOR Flash一般存取代码,如CPU内的ROM等等,NAND Flash一般存放大数据,如:U盘,移动硬盘。
Stm32f103采用的是NAND Flash,这个存储器读取慢,擦除信息,只能整页整页擦除
在洋桃开发板中没有外接Flash,而秉火的开发板用SPI进行外部Flash读写,外部的为8M的Flash。
为了理解方便,我们先学会用stm32内部的Flash,才能为以后外部外接Flash做好准备。
二、了解相关《参考手册》
请大家阅读《参考手册》的28页 2.3 存储器映像,这一章的内容。
我们截取其中一部分
由于stm32分有各种大小的型号,洋桃开发板用的是48个管脚的,属于中等容量的产品。不同的容量的stm32对应着不同内存区域,可以去《参考手册》看看。
我们的一般把程序放在主存储器中,程序存放从0页往后存放,而我们像存储一些简单的数据就可以把数据存在后面的几页,预防万一存放的数据破坏自己原先存放的程序。每一页有1024个地址。
三、主要代码
我们主要用到:
FLASH_Unlock(); //解锁FLASH编程擦除控制器
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);//清除标志位
FLASH_ErasePage(add); //擦除指定地址页
FLASH_ProgramHalfWord(add,dat); //从指定页的addr地址开始写
FLASH_Lock(); //锁定FLASH编程擦除控制器
下面编写程序开始:
一、接下来就是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程序,用设定函数功能
#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_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;
}
三、接下来就是主函数main.c
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "flash.h" //导入Flash的头文件
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址
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)); //等待按键松开
}
}
}
}
注意事项!
下一节内容:
探索每一个地址存放16位无符号的数据有多大,并且我们用单片机的oled屏幕来显示自己存取的数据。对于不懂oled屏幕的使用可以看我的笔记四:https://blog.csdn.net/qq_40546576/article/details/99071244
参考来源:
- Google搜寻引擎等等
- 杜洋工作室 www.DoYoung.net
- 洋桃电子 www.DoYoung.net/YT
- STM32库开发实战指南 基于STM32F103(第二版)
- 《stm32f1xx 参考手册》