当前位置: 首页 > 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;我们每个人在每台设备、应用…...

Godot PCK解包原理与专业逆向实践指南

1. 这不是“解压软件”&#xff0c;而是Godot游戏逆向工程的第一把手术刀你刚下载了一款用Godot引擎开发的独立游戏&#xff0c;想研究它的UI动效逻辑&#xff0c;或者复刻一段粒子特效&#xff0c;又或者只是单纯好奇——那个让你反复通关三次的像素风过场动画&#xff0c;图层…...

Android 11开发避坑:为什么你的App获取的Wifi MAC地址总是变?手把手教你配置固定MAC

Android 11开发实战&#xff1a;彻底解决Wifi MAC地址随机化问题最近在开发一个设备管理系统时&#xff0c;遇到了一个棘手的问题&#xff1a;我们的App在Android 11设备上获取的Wifi MAC地址每次都不一样&#xff0c;导致基于MAC地址的设备识别功能完全失效。经过一周的深入研…...

用STM32CubeMX和HAL库快速上手WS2812B:告别手动计算延时,一键生成驱动框架

基于STM32CubeMX的WS2812B智能灯光控制&#xff1a;从零构建现代化驱动方案在智能硬件和物联网设备快速发展的今天&#xff0c;WS2812B可编程LED灯带因其丰富的色彩表现和简单的单线控制方式&#xff0c;成为创客和工程师们最喜爱的显示组件之一。然而&#xff0c;传统的寄存器…...

ARM PMU外部接口与性能监控寄存器详解

1. ARM性能监控寄存器外部接口深度解析性能监控单元(PMU)是现代处理器架构中用于硬件性能分析的核心模块&#xff0c;它通过一组可编程计数器实时捕获处理器微架构层面的各类事件。在ARMv8/v9架构中&#xff0c;PMU不仅可以通过系统寄存器访问&#xff0c;还提供了标准化的外部…...

浏览器 Profile 环境排查:Cookie、LocalStorage、网络出口与自动化任务配置清单

一、为什么浏览器环境经常“今天能用&#xff0c;明天失效”很多团队遇到登录状态丢失、页面配置异常、自动化任务失败时&#xff0c;会先怀疑网络、脚本或系统本身。但在实际项目里&#xff0c;问题经常不是单点故障&#xff0c;而是浏览器环境缺少稳定管理&#xff1a;对象常…...

AI学习 - 大模型基础入门

AI学习 - 大模型基础入门 从零开始&#xff1a;Ollama 安装 → 本地模型运行 → Python 代码接入 → 理解核心概念 摘要 本文记录了在 Windows 上使用 Ollama 部署本地大模型、并通过 Python 代码接入调用的完整过程。内容涵盖&#xff1a;Ollama 安装与模型拉取、大模型基础概…...

Unity动态自然系统:Forest Environment-Dynamic Nature深度解析

1. 这不是“贴图堆砌”&#xff0c;而是自然系统级建模&#xff1a;Forest Environment-Dynamic Nature 的真实定位你有没有试过在Unity里拖进几棵树、铺点草、加个天空盒&#xff0c;然后发现场景像一张静止的风景明信片——风不动、叶不摇、雨不落、雾不散&#xff1f;我做过…...

2026 文章代码高亮方案选型

将基于 Prism.js 或 Highlight.js 的传统高亮方案与基于 Shiki 的现代化高亮方案进行对比&#xff0c;其核心区别在于底层解析原理的不同&#xff08;正则表达式 vs. TextMate 语法树&#xff09;。 以下是两种方案的底层原理、各自优缺点、核心对比矩阵以及适用场景的详细分析…...

YOLOv8晶圆体缺识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置)

摘要 晶圆制造过程中的缺陷检测是保证芯片良率的关键环节。本文基于YOLOv8目标检测算法&#xff0c;构建了一套针对晶圆表面9类典型缺陷的自动检测系统。所识别的缺陷类型包括&#xff1a;Center、Donut、Edge-Loc、Edge-Ring、Loc、Near-full、None、Random、Scratch。模型在…...

终极指南:用D2DX让《暗黑破坏神2》在现代电脑上焕发新生

终极指南&#xff1a;用D2DX让《暗黑破坏神2》在现代电脑上焕发新生 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 还在为经…...