当前位置: 首页 > news >正文

Air32 | 合宙Air001单片机内部FLASH读写示例

Air32 | 合宙Air001单片机内部FLASH读写示例


代码已经通过测试,开发环境KEIL-MDK 5.36。

测试代码

void FLASH_RdWrTest(void)
{uint32_t Address;uint32_t PageReadBuffer[FLASH_PAGE_SIZE >> 2];uint32_t PageWriteBuffer[FLASH_PAGE_SIZE >> 2];memset(PageWriteBuffer, 0XAA, sizeof(PageWriteBuffer));for(Address = 0x08003000; Address < 0x08008000; Address += FLASH_PAGE_SIZE)  // 16K~32K{FLASH_Write(Address, PageWriteBuffer, sizeof(PageReadBuffer) >> 2);memset(PageReadBuffer, 0, sizeof(PageReadBuffer));FLASH_Read(Address, PageReadBuffer, sizeof(PageReadBuffer) >> 2);if(memcmp(PageReadBuffer, PageWriteBuffer, sizeof(PageReadBuffer)) == 0){printf("page[%04d]  0x%08X read & write %s \r\n", (Address - FLASH_BASE) / FLASH_PAGE_SIZE, Address, "ok");}else{printf("page[%04d]  0x%08X read & write %s \r\n", (Address - FLASH_BASE) / FLASH_PAGE_SIZE, Address, "failed");}}
}

头文件


/*** @brief Create by AnKun on 2019/10/10*/#ifndef FLASH_H__
#define FLASH_H__#include "air001xx_hal.h"/// 导出函数声明 
void FLASH_Init(void);
void FLASH_Read(uint32_t Address, uint32_t *Buffer, uint32_t NumToRead);
void FLASH_Write(uint32_t Address, const uint32_t *Buffer, uint32_t NumToWrite);
void FLASH_WritePage_NoCheck(uint32_t Address, const uint32_t* Buffer);
void FLASH_ErasePage(uint32_t Address);
void FLASH_SetReadProtectionState(int state);#endif // !__FLASH_H

源文件


/*** @file  flash.c** @brief Create by AnKun on 2023/7/20**/#include "flash.h"
#include <string.h>static uint32_t FlashBuffer[FLASH_PAGE_SIZE >> 2];void FLASH_Init(void)
{HAL_FLASH_Unlock();__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);  /* Clear SR register */HAL_FLASH_Lock();
}void FLASH_Read(uint32_t Address, uint32_t *Buffer, uint32_t NumToRead)
{while(NumToRead--){*Buffer++ = (*((volatile unsigned int *)Address));Address += 4;}
}void FLASH_WritePage_NoCheck(uint32_t Address, const uint32_t* Buffer)
{HAL_FLASH_Lock();    //解锁HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, Address, (uint32_t *)Buffer);HAL_FLASH_Unlock();  //上锁
}void FLASH_ErasePage(uint32_t Address)
{uint32_t PageError = 0;FLASH_EraseInitTypeDef EraseInitStruct = {0};HAL_FLASH_Unlock();EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGEERASE;EraseInitStruct.PageAddress = Address;EraseInitStruct.NbPages     = 1;  /* erase nums pages. */if(HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK){printf("%s\r\n", __FUNCTION__);}HAL_FLASH_Lock();
}void FLASH_Write(uint32_t Address, const uint32_t *Buffer, uint32_t NumToWrite)
{uint32_t secpos;	   //页地址uint32_t secoff;	   //页内偏移地址(16位字计算)uint32_t secremain;    //页内剩余地址(16位字计算)uint32_t i;uint32_t offaddr;    //去掉0X08000000后的地址HAL_FLASH_Unlock();  //解锁offaddr = Address - FLASH_BASE;		              //实际偏移地址.secpos = offaddr / FLASH_PAGE_SIZE;			       //页地址secoff = (offaddr % FLASH_PAGE_SIZE) >> 2;		   //在页内的偏移(2个字节为基本单位.)secremain = (FLASH_PAGE_SIZE >> 2) - secoff;		   //页剩余空间大小if(NumToWrite <= secremain)secremain = NumToWrite; //不大于该页范围while(1){FLASH_Read(secpos * FLASH_PAGE_SIZE + FLASH_BASE, FlashBuffer, FLASH_PAGE_SIZE >> 2); //读出整个页的内容for(i = 0; i < (FLASH_PAGE_SIZE >> 2); i++) //校验数据{if(FlashBuffer[i] != 0XFFFFFFFF){uint32_t PageError = 0;FLASH_EraseInitTypeDef EraseInitStruct = {0};EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGEERASE;EraseInitStruct.PageAddress = Address;EraseInitStruct.NbPages     = 1;  /* erase nums pages. */HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);break;}}for(i = 0; i < secremain; i++) //复制{FlashBuffer[i + secoff] = Buffer[i];}HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, secpos * FLASH_PAGE_SIZE + FLASH_BASE, (uint32_t *)FlashBuffer);  //写入整个页if(NumToWrite == secremain)break; //写入结束了else//写入未结束{secpos++;				//页地址增1secoff = 0;				//偏移位置为0Buffer += secremain;  	//指针偏移Address += secremain;	//写地址偏移NumToWrite -= secremain;	//字节(16位)数递减if(NumToWrite > (FLASH_PAGE_SIZE >> 2)) secremain = (FLASH_PAGE_SIZE >> 2); //下一个页还是写不完else secremain = NumToWrite; //下一个页可以写完了}}HAL_FLASH_Lock();  //解锁
}void FLASH_SetReadProtectionState(int onoff)
{FLASH_OBProgramInitTypeDef OptionsBytesStruct;HAL_FLASH_Unlock();HAL_FLASH_OB_Unlock();HAL_FLASH_OBGetConfig(&OptionsBytesStruct);if(onoff){if(OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL_0){OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;OptionsBytesStruct.RDPLevel   = OB_RDP_LEVEL_1;HAL_FLASH_OBProgram(&OptionsBytesStruct);HAL_FLASH_OB_Launch();}}else{if(OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL_1){OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;OptionsBytesStruct.RDPLevel   = OB_RDP_LEVEL_0;HAL_FLASH_OBProgram(&OptionsBytesStruct);HAL_FLASH_OB_Launch();}}HAL_FLASH_OB_Lock();HAL_FLASH_Lock();
}void FLASH_RdWrTest(void)
{uint32_t Address;uint32_t PageReadBuffer[FLASH_PAGE_SIZE >> 2];uint32_t PageWriteBuffer[FLASH_PAGE_SIZE >> 2];memset(PageWriteBuffer, 0XAA, sizeof(PageWriteBuffer));for(Address = 0x08003000; Address < 0x08008000; Address += FLASH_PAGE_SIZE)  // 16K~32K{FLASH_Write(Address, PageWriteBuffer, sizeof(PageReadBuffer) >> 2);memset(PageReadBuffer, 0, sizeof(PageReadBuffer));FLASH_Read(Address, PageReadBuffer, sizeof(PageReadBuffer) >> 2);if(memcmp(PageReadBuffer, PageWriteBuffer, sizeof(PageReadBuffer)) == 0){printf("page[%04d]  0x%08X read & write %s \r\n", (int)((Address - FLASH_BASE) / FLASH_PAGE_SIZE), Address, "ok");}else{printf("page[%04d]  0x%08X read & write %s \r\n", (int)((Address - FLASH_BASE) / FLASH_PAGE_SIZE), Address, "failed");}}
}

相关文章:

Air32 | 合宙Air001单片机内部FLASH读写示例

Air32 | 合宙Air001单片机内部FLASH读写示例 代码已经通过测试&#xff0c;开发环境KEIL-MDK 5.36。 测试代码 void FLASH_RdWrTest(void) {uint32_t Address;uint32_t PageReadBuffer[FLASH_PAGE_SIZE >> 2];uint32_t PageWriteBuffer[FLASH_PAGE_SIZE >> 2];mem…...

C语言基本语法-第一章

C 语言基本语法 语句 C 语言的代码由一行行语句&#xff08;statement&#xff09;组成。语句就是程序执行的一个操作命令。C 语言规定&#xff0c;语句必须使用分号结尾&#xff0c;除非有明确规定可以不写分号。 int x 1;上面就是一个变量声明语句&#xff0c;声明整数变…...

八、Spring 整合 MyBatis

文章目录 一、Spring 整合 MyBatis 的关键点二、Spring 整合 MyBatis 的步骤2.1 创建 Maven 项目&#xff0c;并导入相关依赖2.2 配置 Mybatis 部分2.3 配置 Spring 部分2.3 配置测试类 一、Spring 整合 MyBatis 的关键点 1、 将 Mybatis 的 DataSource (数据来源)的创建和管理…...

Flutter Flar动画实战

在Flare动面出现之前,Flare动画大体可以分为使用AnimationController控制的基础动画以及使用Hero的转场动画,如果遇到一些复杂的场景,使用这些动画方案实现起来还是有难度的。不过,随着Flutter开始支持Flare矢量动面,Flutter的动画开发也变得越来越简单。事实上,Flare动画…...

A stop job is running for xxxxxx

有时候服务器关机时&#xff0c;会有个进程卡在那里&#xff0c;使系统无法关闭 提示&#xff1a; A stop job is running for xxxxxx方法&#xff1a; 设置一个启动/停止的默认超时时间即可 vim /etc/systemd/system.conf DefaultTimeoutStartSec300s DefaultTimeoutStopSe…...

C++入门之stl六大组件--List源码深度剖析及模拟实现

文章目录 前言 一、List源码阅读 二、List常用接口模拟实现 1.定义一个list节点 2.实现一个迭代器 2.2const迭代器 3.定义一个链表&#xff0c;以及实现链表的常用接口 三、List和Vector 总结 前言 本文中出现的模拟实现经过本地vs测试无误&#xff0c;文件已上传gite…...

windows下以指定用户访问SMB服务器进行读写

一 概述 最近遇到一个问题&#xff0c;linux 的 smb服务器开启匿名访问&#xff0c;windows访问linux文件夹不需要用户名密码就可以进去使用&#xff0c;但是存在一个问题&#xff0c;ssh连接到linux 后修改的文件&#xff0c;在windows已smb方式下打开某个文件修改 是没有权限…...

数组根据属性去重

利用reduce函数处理&#xff0c;直接上代码&#xff01; let data [{name:晓明,id:1},{name:德华,id:2},{name:德华,id:2},{name:晓明,id:1},] var obj {}; let arr data.reduce(function (item, next) {obj[next.id] ? : obj[next.id] true && item.push(next)…...

无损音乐从哪找?五个网站+免费下载,你确定不来看看?

hi&#xff0c;大家好我是技术苟&#xff0c;每天晚上22点准时上线为你带来实用黑科技&#xff01;由于公众号改版&#xff0c;现在的公众号消息已经不再按照时间顺序排送了。因此小伙伴们就很容易错过精彩内容。喜欢黑科技的小伙伴&#xff0c;可以将黑科技百科公众号设为标星…...

2023华数杯数学建模B题思路模型论文分析

目录 一.2023华数杯数学建模最新思路&#xff1a;比赛开始后第一时间更新 更新查看文末名片 二.华数杯简介 三.往年华数杯赛题简介分析&#xff1a; 一.2023华数杯数学建模最新思路&#xff1a;比赛开始后第一时间更新 更新查看文末名片 二.华数杯简介 华数杯简介 国赛前…...

K8S系列文章之 使用Kind部署K8S 并发布服务

简单介绍 kind 即 Kubernetes In Docker&#xff0c;顾名思义&#xff0c;就是将 k8s 所需要的所有组件&#xff0c;全部部署在一个docker容器中&#xff0c;是一套开箱即用的 k8s 环境搭建方案。使用 kind 搭建的集群无法在生产中使用&#xff0c;但是如果你只是想在本地简单…...

从0到1开发go-tcp框架【4实战片— — 开发MMO之玩家聊天篇】

从0到1开发go-tcp框架【实战片— — 开发MMO】 MMO&#xff08;MassiveMultiplayerOnlineGame&#xff09;&#xff1a;大型多人在线游戏&#xff08;多人在线网游&#xff09; 1 AOI兴趣点的算法 游戏中的坐标模型&#xff1a; 场景相关数值计算 ● 场景大小&#xff1a; 250…...

无重复字符的最长子串 LeetCode热题100

题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长连续子字符串 的长度。 思路 使用滑动窗口&#xff0c;记录窗口区间的长度大小&#xff0c;取最大值。用map存储滑动窗口内所有字符&#xff0c;字符作为key&#xff0c;每个字符的数量作为value。遍历…...

Docker搭建zookeeper

问题背景 前言 本文参考自&#xff1a;docker-compose快速搭建Zookeeper集群还有一种更加详细更加全面的部署方式&#xff1a;Docker之docker-compose一键部署Zookeeper集群&#xff0c;但笔者还未验证&#xff0c;先记录下来 搭建 安装docker-ce 此处不赘述 安装docker-co…...

LeetCode 热题 100 JavaScript--160. 相交链表

/*** Definition for singly-linked list.* function ListNode(val) {* this.val val;* this.next null;* }*//*** param {ListNode} headA* param {ListNode} headB* return {ListNode}*/// 1、暴力解法 var getIntersectionNode function(headA, headB) {var p1 …...

AWS S3 协议对接 minio/oss 等

使用亚马逊 S3 协议访问对象存储 [s3-API](https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html)- 兼容S3协议的对象存储有- minio- 似乎是完全兼容 [兼容文档](https://www.minio.org.cn/product/s3-compatibility.htm…...

手机便签内容不见了怎么恢复正常?

在日常生活和工作中&#xff0c;很多人都需要随手记录事情&#xff0c;例如家庭琐事、孩子相关的事情、指定时间需要完成的工作任务、会议安排等。当我们需要随时随地记录事情的时候&#xff0c;手机便签应用就是非常不多的选择&#xff0c;我们直接打开手机上的便签APP就可以新…...

【架构】Java 系统架构演进的思考

文章目录 1 前言2 单体应用架构3 垂直应用架构4 分布式架构5 SOA 架构6 微服务云架构7 总结 1 前言 随着移动互联的发展&#xff0c;网站、H5、移动端的应用规模也不断扩大&#xff0c;不管是应用的数量还是质量都得到了指数级的提升。开发者的数量与日俱增&#xff0c;应用的…...

Python爬虫——解析_jsonpath

jsonpath的安装 pip install jsonpathjsonpath的使用&#xff1a; obj json.load(open(json文件, r, encodingutf-8)) ret jsonpath.jsonpath(obj, jsonpath语法)json文件&#xff1a; { "store": {"book": [{ "category": "末世"…...

华为发布数字资产继承功能

在华为开发者大会2023&#xff08;HDC.Together&#xff09;上&#xff0c;华为常务董事、终端BG CEO、智能汽车解决方案BU CEO余承东正式发布了数字资产继承功能&#xff0c;HarmonyOS提供了安全便捷的数字资产继承路径。 在鸿蒙世界中&#xff0c;我们每个人在每台设备、应用…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...