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

news2024/11/15 5:02:40

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

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"#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2070946.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac 虚拟机PD19运行E-prime实验遇到E-prime unable to set display mode:0*80004001问题解决

作者&#xff1a;50% unable to set display mode问题 总结&#xff1a; 1. 修改该Experiment的Devices中的Dispaly为640*680,或800*600。 2. 右键开始菜单中的E-Studio程序&#xff0c;打开文件所在位置&#xff0c;然后右键该文件&#xff0c;选择属性-兼容性&#xff0c;勾选…

【内网渗透】ICMP隧道技术,ICMP封装穿透防火墙上线MSF/CS

~ 会当凌绝顶&#xff0c;一览众山小 ~ 前言 博客主页&#xff1a;h0ack1r丶羽~ 从0到1~ 渗透测试中&#xff0c;如果攻击者使用各类上层隧道(例如&#xff1a;HTTP隧道、DNS隧道、常规正/反向端口转发等)进行的操作都失败了&#xff0c;常常会通过ping命令访问远程计算机&am…

医疗多模态大模型是什么?医学多模态模型总结:算法其实很简单,拼的就是硬件算力的问题!多模态大模型(医疗影像分析)

概念 医学多模态大模型是指利用多种不同的医学数据源和模型&#xff0c;通过深度学习和人工智能技术&#xff0c;构建一个综合性的大型模型&#xff0c;以实现更加准确和全面的医学数据分析和预测。 这种模型可以同时处理多种医学数据类型&#xff0c;如医学图像、病历文本、…

自动驾驶---各大车企的端到端之旅

1 背景 端到端技术的落地速度确实有些超出预料&#xff0c;随着以ChatGPT为代表的AI大模型的快速发展&#xff0c;使得自动驾驶系统也能够像人一样进行“思考”&#xff0c;推动了自动驾驶技术的迭代升级。 特斯拉端到端技术的落地&#xff0c;自动驾驶在这一技术上的变化使得自…

<C++> 二叉搜索树

目录 二叉搜索树 1. 概念 2. 二叉搜索树操作 2.1 基础结构 2.2 非递归版 1. 查找 2. 插入 3. 删除 2.3 递归版 1. 查找 2. 插入 3. 删除 2.4 拷贝构造函数 2.5 赋值运算符重载 2.6 析构函数 2.7 完整代码 3. 二叉搜索树的应用 4. 二叉搜索树的性能 二叉搜索树 1. 概念 二叉搜索…

机器学习算法那些事 | 这是我见过最通俗易懂的SVD(奇异值分解)算法介绍

本文来源公众号“机器学习算法那些事”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;这是我见过最通俗易懂的SVD&#xff08;奇异值分解&#xff09;算法介绍 线性代数是机器学习领域的基础&#xff0c;其中一个最重要的概念是奇…

手机号归属地查询如何用Java进行调用

一、什么是手机号归属地查询接口&#xff1f; 手机号归属地查询接口又叫手机号归属地、手机号信息查询、手机号查询&#xff0c;通过手机号查询归属地信息、是否虚拟运营商等。该接口可支持三大运营商&#xff0c;移动、电信、联通等。 二、手机号归属地查询接口适用场景有哪…

OpenCV+Python识别机读卡

背景介绍 正常机读卡是通过读卡机读取识别结果的&#xff0c;目前OpenCV已经这么强大了&#xff0c;尝试着用OpenCVPython来识别机读卡。要识别的机读卡长这样&#xff1a; 我们做以下操作&#xff1a; 1.识别答题卡中每题选中项结果。 不做以下操作&#xff1a; 1.不识别准…

【数据分析:RFM客户价值度模型】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;本阶段和大家一起分享和探索大数据技术RFM客户价值度模型&#xff0c;本篇文章主要讲述了&#xff1a;RFM客户价值度模型等等。欢迎大家一起探索讨论&#xff01;&#xff01;&#xff01…

大数据-99 Spark 集群 Spark Streaming DStream 文件数据流、Socket、RDD队列流

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

GATK ReadsPathDataSource类介绍

GATK(Genome Analysis Toolkit)是一个广泛使用的基因组分析工具包,它的核心库之一是htsjdk,用于处理高通量测序数据。在GATK中,ReadsPathDataSource类是负责管理和提供读取高通量测序数据文件(如BAM、SAM、CRAM)的类。 常见使用场景 数据加载:在GATK的基因组分析工具链…

MySQL的MRR(Multi-Range Read)优化原理详解

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

LeetCode:反转区间内的链表

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 反转区间内的链表题目链接方法一&#xff1a;拆开反转…

【TB作品】PIC16F1719单片机,EEPROM,PFM,读写

对于PIC16F1719单片机&#xff0c;没有直接的EEPROM&#xff0c;而是使用高耐久度的程序闪存&#xff08;PFM&#xff09;作为非易失性数据存储区域。这个区域特别适合存储那些需要频繁更新的数据。读写这个内存区域需要操作一些特殊功能寄存器&#xff0c;比如用于地址的PMADR…

2.K8s集群搭建

K8s搭建 搭建方案kubeadm搭建系统初始化操作k8s Master节点初始化将node节点加入集群安装网络插件Calico集群测试 搭建方案 minikube&#xff1a;轻量化的Kubernetes集群&#xff0c;为了能够更好学习和体验k8s功能而推出的&#xff0c;借助个人PC的虚拟化环境就可以实现Kuber…

如何使用ssm实现基于java web的网上书城系统的设计与实现+vue

TOC ssm123基于java web的网上书城系统的设计与实现vue JAVA简介 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterprise JavaBeans&#xff09;的全面支持&#xff0c;java servlet API&#xff0c;JSP&#xff…

【Redis】Redis客户端——Jedis(Java)

Redis Java使用案例 环境配置引入依赖配置端⼝转发连接 Redis Server Java基础代码操作Redisset 和 getexsits 和 del 环境配置 引入依赖 Java 操作 redis 的客⼾端有很多. 其中最知名的是 jedis. 创建 maven 项⽬, 把 jedis 的依赖拷⻉到 pom.xml 中. <!-- https://mvnr…

ssrf--web-ssrfme例题

将web-ssrfme.zip解压缩在Ubuntu下 Docker-compose up -d 更新后的镜像重新启动容器 可以看到已经拉取成功ssrfme镜像 我们使用端口访问文件&#xff0c;可以看到有一个过滤条件&#xff0c;它限制了file&#xff0c;dict协议&#xff0c;127.0.0.1和localhost 也不能用&…

【55-90】结构型模式

目录 一.结构型模式概述 二.代理模式 2.1 概述 2.2 结构 2.3 静态代理 2.4 JDK动态代理 2.5 CGLIB动态代理 2.6 三种代理的对比 2.7 优缺点 三.适配器模式 3.1 概述 3.2 结构 3.3 类适配器模式 3.4 对象适配器模式 3.5 应用场景 四.装饰者模式 4.1 概述 4.2 结…

从并发20到并发120之laravel性能优化

调优成果 遇到问题 单台服务并发20&#xff0c;平均响应时间1124ms&#xff0c;通过htop观察&#xff0c;发现cpu占用率达到100%&#xff08;包括sleep的进程&#xff09;&#xff0c;内存几乎没怎么用。 调优后 单机最大吞吐量达到120 响应时长不超过1000ms 硬件信息 …