STM32F7xx —— 内部flash

                          STM32F7xx —— 内部flash

 

 

这个就没什么好说的了,直接上代码了,主要封装了三个函数,擦除,写flash,读flash。

// STM32F767IGT6: 1M flash
// STM32F767ZIT6: 2M flash
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */
#ifdef STM32F767ZIT6
#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08100000) /* Base @ of Sector 8, 256 Kbytes */
#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x08140000) /* Base @ of Sector 9, 256 Kbytes */
#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x08180000) /* Base @ of Sector 10, 256 Kbytes */
#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x081C0000) /* Base @ of Sector 11, 256 Kbytes */
#endif
// 获取要擦除扇区编号
static uint32_t flash_sector_number(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;}
#ifdef STM32F767ZIT6else if((address < ADDR_FLASH_SECTOR_8) && (address >= ADDR_FLASH_SECTOR_7)){sector = FLASH_SECTOR_7;}else if((address < ADDR_FLASH_SECTOR_9) && (address >= ADDR_FLASH_SECTOR_8)){sector = FLASH_SECTOR_8;}else if((address < ADDR_FLASH_SECTOR_10) && (address >= ADDR_FLASH_SECTOR_9)){sector = FLASH_SECTOR_9;}else if((address < ADDR_FLASH_SECTOR_11) && (address >= ADDR_FLASH_SECTOR_10)){sector = FLASH_SECTOR_10;}else if((address < 0x081C0000) && (address >= ADDR_FLASH_SECTOR_11)){sector = FLASH_SECTOR_11;}
#elseelse if(address >= ADDR_FLASH_SECTOR_7){sector = FLASH_SECTOR_6;}
#endifreturn sector;
}// 擦除指定扇区数据 仔细的朋友会发现count没有用到,这里可以任意更改,我是为了兼容F1的命名。
void SocFlashErase(uint32_t addr, uint8_t count)
{FLASH_EraseInitTypeDef flash_erase;uint32_t flash_error;HAL_FLASH_Unlock();flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;  // 擦除类型,扇区擦除flash_erase.Sector = flash_sector_number(addr);   // 要擦除的扇区flash_erase.NbSectors = 1;                        // 一次只擦除一个扇区 这里可以使用参数的count 为了防止错误操作这里写成1flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围,VCC=2.7~3.6V之间!!__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);HAL_FLASHEx_Erase(&flash_erase, &flash_error);FLASH_WaitForLastOperation(50000);HAL_FLASH_Lock();
}uint8_t SocFlashWrite(uint32_t addr, uint8_t *buffer, uint32_t length)
{uint32_t i;uint16_t data = 0;if (length == 0){return 0;}HAL_FLASH_Unlock();__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_BSY);// 按半字编程for (i = 0; i < length; i += 2){data = (*(buffer + i + 1) << 8) + (*(buffer + i));HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)(addr + i), data);}HAL_FLASH_Lock();return 0;
}uint32_t SocFlashRead(uint32_t addr, uint8_t *buffer, uint32_t length)
{memcpy(buffer, (void *)addr, length);return length;
}

 

F1内部flash

 

 

 

 

 

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

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

相关文章

深入理解 Vue Computed 计算属性

Computed 计算属性是 Vue 中常用的一个功能&#xff0c;我们今天来说一下他的执行过长 拿官网简单的例子来看一下&#xff1a; <div id"example"><p>Original message: "{{ message }}"</p><p>Computed reversed message: "{…

vscode 使用 ssh 登录

// 执行 // 使用你自己的服务器IP与登录账户 export USER_AT_HOST"服务器账户名服务器IP" // PUBKEYPATH是你公钥的路径 export PUBKEYPATH"$HOME/.ssh/id_rsa.pub"ssh-copy-id -i "$PUBKEYPATH" "$USER_AT_HOST"

SNMP4J的一点缺陷

最近在使用SNMP4J的过程中发现一个缺陷&#xff0c;不知道应不应该算是个bug&#xff0c;但我想终究算是一个不完善的地方。 问题描述如下&#xff1a; 在通过SNMP4J去获取某些交换机上的MAC地址转发表(dot1dTpFdbTable, OID为1.3.6.1.2.1.17.4.3&#xff09;时&#xff0c;发现…

3-3 数数字

算法入门经典 P57 把前n&#xff08;n<100000&#xff09;个整数顺序写在一起&#xff0c;123456789...数一数0-9各出现多少次。 #include<stdio.h>#include<string.h>#include "stdafx.h"#include "iostream" #include <string&…

如何用示波器测量串口波特率

这是前段时间遇到的问题&#xff0c;刚好这里找到了答案&#xff0c;记录下分享给大家。如何确定时基假如要测量的波特率为9600, 则每一比特位的时间为&#xff1a;1/9600 ≈ 104 μs&#xff0c;一般示波器横向上每个大格子里5个小格子&#xff0c;要想看清一比特位一般需要一…

STM32F7xx —— ADC

STM32F7xx —— ADC 基础知识参考&#xff1a;ADC /***************************************************************************** * ADC1 ADC2 ADC3 * 通道0 PA0 PA0 PA0 * 通道1 PA1 PA1 PA1 * 通道2 PA2 PA2 …

一键了结CUP100%问题

1、dllhost进程造成CPU使用率占用100%<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />服务器正常CPU消耗应该在75%以下&#xff0c;而且CPU消耗应该是上下起伏的&#xff0c;出现这种问题的服务器&#xff0c;CPU会突然一直处10…

Linux内核工程师是怎么步入内核殿堂的?

上图是公众号冠名参加的篮球赛对我来说&#xff0c;要搞好Linux内核&#xff0c;首先要做的就是买一块Linux开发板&#xff0c;然后就使劲捣鼓。下面是一位大神对于入门Linux内核的看法。以下的「我」不是公众号作者作者&#xff1a;Coly Lihttps://www.zhihu.com/question/304…

Newtonsoft.Json 获取匿名类数据

很简单。 1 using System;2 using System.Collections.Generic;3 4 namespace Test5 {6 class Program7 {8 9 static string Message "{\"Result\":0,\"ErrMsg\":\"执行失败。索引超出范围。必须为非负值并小于集合大小。\r\n参…

STM32F7xx —— Timer

STM32F7xx —— Timer 目录 STM32F7xx —— Timer 一、基础定时器配置 二、带回调定时器 作用&#xff1a;输出PWM&#xff0c;测量脉冲长度&#xff0c;定时等。 一、基础定时器配置 // 基本定时器 #define TIMER_CHANNEL TIM3 #define TIMER_PREEMPT_PRIO…

jquery-autocomplete学习(转)

jquery-autocomplete学习 一、用前必备官方网站&#xff1a;http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/当前版本&#xff1a;1.0.2需要JQuery版本&#xff1a;1.2.6 二、使用<script src"./jquery-1.3.2.js" type"text/javascript&q…

时间同步绝对是一个大问题

上图是加班看到的夜景假设A电脑时间和B电脑时间不同&#xff0c;当他们两个电脑的用户在使用电脑的时候就会存在问题&#xff0c;比如A电脑的用户说&#xff0c;我们下午5&#xff1a;00 去打球&#xff0c;然后A电脑到了5&#xff1a;00就去打球了&#xff0c;但是可能这个时候…

Window10彻底卸载应用商店

Window10如何彻底卸载应用商店&#xff1f;Window10应用商店就是一个应用下载平台&#xff0c;我们可以在应用商店中下载各种应用&#xff0c;但是很多用户并不喜欢在Window10应用商店中下载应用&#xff0c;觉得应用商店浪费内存&#xff0c;因此想将应用商店卸载掉&#xff0…

STM32F7xx —— QSPI

STM32F7xx —— QSPI 目录 STM32F7xx —— QSPI 一、QSPI 二、几个重要的函数 三、几个重要的结构 四、QSPI接口设计&#xff08;仅供参考&#xff09; 五、QSPI驱动W25Q256 一、QSPI SPI 是 Queued SPI 的简写&#xff0c;是 Motorola公司推出的 SPI 接口的扩展&#xf…

嵌入式、物联网常见通信协议

本文介绍一些常见的嵌入式、物联网通信协议&#xff0c;它们具有不同的性能、通信速率、覆盖范围、功率和内存&#xff0c;而且每一种协议都有各自的优点和或多或少的缺点。其中一些通信协议只适合小型家用电器&#xff0c;而其他一些通信协议则可以用于大型智慧城市项目。物联…

解决T400死机的问题!

终于解决这几天突然出现的t400 vista假死问题! 原来罪魁祸首是 ThinkPad -- Intel Matrix Storage Manager驱动程序(Windows XP/vista 32bit) 此更新在su自动更新里也有 千万别更新 如果不小心更新并出现偶尔假死(现象&#xff1a;鼠标能动&#xff0c;但是不能打开程序所有应用…

cas-client登录后报INVALID_PROXY_CALLBACK

服务器部署cas&#xff0c;登录后页面提示INVALID_PROXY_CALLBACK 然后查看cas的日志&#xff0c;日志报以下错误&#xff1a; 2018-06-29 11:36:06,251 ERROR [org.jasig.cas.util.http.SimpleHttpClient] - java.lang.RuntimeException: Unexpected error: java.security.Inv…

OpenNMS全接触-事件及通知(九)

在上一篇文章OpenNMS全接触-事件及通知&#xff08;八&#xff09;中&#xff0c;介绍了OpenNMS在收到受管设备发出的SNMP Trap之后&#xff0c;如何将收到的SNMP Trap与eventconf.xml文件中定义的事件(event)进行匹配&#xff0c;从而触发该事件的发生。主要是引入了<mask&…

STM32F7xx —— 看门狗

STM32F7xx —— 看门狗 看门狗&#xff1a;指定时间内不喂狗&#xff0c;就重启系统。 最简单的看门狗设计&#xff08;喂狗就是指定时间内给寄存器写一个固定值&#xff09; // 初始化独立看门狗 // prer:分频数:0~7(只有低 3 位有效!) // rlr:自动重装载值,0~0XFFF. // 分频…

网络中路由器的工作原理

大家好&#xff0c;我是情报小哥&#xff01;01路由器