STM32 | STM32 FLASH第十二天(实现代码STM32CUBEMX)

点击上方"蓝字"关注我们

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"#
  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qt历险记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值