在此声明一下所有代码均为 杜洋工作室 的不允许复制,转发等,本人只是在此程序上进行理解和注释。
上一次的笔记是在洋桃开发板上进行用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 存储器映像,这一章的内容。
我们截取其中一部分
我们主要用到:
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 参考手册》
联系客服