点击上方"蓝字"关注我们
01、FLASH
>>>1、STM32 FLASH
Flash内部存储器,内存器件的一种,是一种非易失性( Non-Volatile )内存。
flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。
粤嵌开发板STM32F407ZET6的flash大小:512KB
程序固化到FLASH,需要对BOOT0与BOOT1进行设置
02、嵌入式Flash接口
>>>主要特性
● Flash 读操作
● Flash 编程/擦除操作
● 读/写保护
● I-Code 上的预取操作
● I-Code 上的 64 个缓存( 128 位宽)
● D-Code 上的 8 个缓存( 128 位宽)
03、嵌入式Flash
>>>Flash 具有以下主要特性:
● 对于 STM32F40x 和 STM32F41x,容量高达 1 MB;对于 STM32F42x 和 STM32F43x,
容量高达 2 MB
● 128 位宽数据读取
● 字节、半字(两个字节)、字(四个字节)和双字数据写入
● 扇区擦除与全部擦除
● 存储器组织结构
Flash 结构如下:
— ,分为 4 个 16 KB 扇区、 1 个 64 KB 扇区和 7 个 128 KB 扇区
— 系统存主存储器块储器,器件在系统存储器自举模式下从该存储器启动
— 512 字节 OTP(一次性可编程),用于存储用户数据
OTP 区域还有 16 个额外字节,用于锁定对应的 OTP 数据块。
— 选项字节,用于配置读写保护、 BOR 级别、软件/硬件看门狗以及器件处于待机或
停止模式下的复位。
FLASH读写可参考官方固件库进行编写
FLASH写入数据函数
//写双字(8个字节)
FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data);
//写字(4个字节)
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
//写半字(2个字节)
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
//写字节(1个字节)
FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data);
04、STM32cubemx
>>>1、HAL库
HAL是Hardware Abstraction Layer的缩写,中文名:硬件抽象层。HAL库是ST为STM32最新推出的抽象层嵌入式软件,可以更好的确保跨STM32产品的最大可移植性。该库提供了一整套一致的中间件组件,如RTOS,USB,TCP / IP和图形等。
HAL库是基于一个非限制性的BSD许可协议(Berkeley Software Distribution)而发布的开源代码。ST制作的中间件堆栈(USB主机和设备库,STemWin)带有允许轻松重用的许可模式, 只要是在ST公司的MCU 芯片上使用,库中的中间件(USB 主机/设备库,STemWin)协议栈即被允许随便修改,并可以反复使用。至于基于其它著名的开源解决方案商的中间件(FreeRTOS,FatFs,LwIP和PolarSSL)也都具有友好的用户许可条款。
可以说HAL库就是用来取代之前的标准外设库的。相比标准外设库,STM32Cube HAL库表现出更高的抽象整合水平,HAL API集中关注各外设的公共函数功能,这样便于定义一套通用的用户友好的API函数接口,从而可以轻松实现从一个STM32产品移植到另一个不同的STM32系列产品。HAL库是ST未来主推的库,从前年开始ST新出的芯片已经没有STD库了,比如F7系列。目前,HAL库已经支持STM32全线产品。ST提供库函数:标准库、LL库、HAL
图形开发方法:STM32CUBEMX+KEIL STM32CUBEIDE(STM32CUBEMX+KEIL)
05、安装
>>>1、安装并破解keil软件
2、双击安装HAL库:Keil.STM32F4xx_DFP.2.14.0.pack
STM32全部系列最新HAL库下载地址
链接:https://pan.baidu.com/s/1flM8-FRjGUmMWTY90GnxxA
提取码:upoq
3、安装STM32CUBEMX,请参考博客:https://blog.csdn.net/wwwqqq2014/article/details/116292865
06、开发步骤
>>>1、从芯片建立工程
2、设置时钟
3、引脚设置
4、代码生成设置
1、生成代码
07、练习
>>>1、参考下面代码,请完成FLASH读数据代码(读数据不需要解锁)
uwAddress = FLASH_USER_START_ADDR;
while (uwAddress < FLASH_USER_END_ADDR)
{
uwData32 = *(__IO uint32_t*)uwAddress;
if (uwData32 != DATA_32)
{
}
uwAddress = uwAddress + 4;
}
2、通过STM32CUBEMX,完成流水灯实验
08、flash
// 头文件
#ifndef __FLASH_H
#define __FLASH_H
#include "stm32f4xx.h"
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */
void Flash_Write(u32 addr, u8* write_buff, u32 len);
void Flash_Read(u32 addr, u8* read_buff, u32 len);
#endif
// 源文件
#include "flash.h"
static uint32_t GetSector(uint32_t Address)
{
uint32_t sector = 0;
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_Sector_0;
}
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_Sector_1;
}
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_Sector_2;
}
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_Sector_3;
}
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_Sector_4;
}
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_Sector_5;
}
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_Sector_6;
}
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_Sector_7;
}
return sector;
}
void Flash_Write(u32 addr, u8* write_buff, u32 len)
{
u32 FLASH_USER_START_ADDR, FLASH_USER_END_ADDR, uwAddress;
u32 uwStartSector, uwEndSector, uwSectorCounter;
//FLASH解锁
FLASH_Unlock();
//清空相关标志位
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
//计算开始地址
FLASH_USER_START_ADDR = addr;
//计算结束地址
FLASH_USER_END_ADDR = FLASH_USER_START_ADDR+len;
//获取开始与结束扇区
uwStartSector = GetSector(FLASH_USER_START_ADDR);
uwEndSector = GetSector(FLASH_USER_END_ADDR);
//开始擦除操作
uwSectorCounter = uwStartSector; //开始扇区赋值给uwSectorCounter
while (uwSectorCounter <= uwEndSector)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
//擦除扇区
if (FLASH_EraseSector(uwSectorCounter, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while sector erase.
User can add here some code to deal with this error */
printf("erase failure\r\n");
return ;
}
uwSectorCounter += 8;
}
/* Program the user Flash area word by word ********************************/
/* area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */
//起始地址赋值给uwAddress
uwAddress = FLASH_USER_START_ADDR;
while (uwAddress < FLASH_USER_END_ADDR)
{
if (FLASH_ProgramByte(uwAddress, *write_buff) == FLASH_COMPLETE)
{
uwAddress = uwAddress + 1; //FLASH要加1
write_buff++; //数据地址空间加1
}
else
{
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error */
printf("erase failure\r\n");
return ;
}
}
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) */
//上锁
FLASH_Lock();
}
void Flash_Read(u32 addr, u8* read_buff, u32 len)
{
u32 FLASH_USER_START_ADDR, FLASH_USER_END_ADDR, uwAddress;
//计算开始地址
FLASH_USER_START_ADDR = addr;
//计算结束地址
FLASH_USER_END_ADDR = FLASH_USER_START_ADDR+len;
uwAddress = FLASH_USER_START_ADDR;
while (uwAddress < FLASH_USER_END_ADDR)
{
*read_buff = *(__IO uint8_t*)uwAddress;
read_buff++;
uwAddress = uwAddress + 1;
}
}
09、main.c
#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "delay.h"
#include "tim.h"
#include "pwm.h"
#include "usart.h"
#include "string.h"
#include "sr04.h"
#include "dht11.h"
#include "iwdg.h"
#include "rtc.h"
#