当前位置: 首页 > 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");}}
}
http://www.lryc.cn/news/112739.html

相关文章:

  • C语言基本语法-第一章
  • 八、Spring 整合 MyBatis
  • Flutter Flar动画实战
  • A stop job is running for xxxxxx
  • C++入门之stl六大组件--List源码深度剖析及模拟实现
  • windows下以指定用户访问SMB服务器进行读写
  • 数组根据属性去重
  • 无损音乐从哪找?五个网站+免费下载,你确定不来看看?
  • 2023华数杯数学建模B题思路模型论文分析
  • K8S系列文章之 使用Kind部署K8S 并发布服务
  • 从0到1开发go-tcp框架【4实战片— — 开发MMO之玩家聊天篇】
  • 无重复字符的最长子串 LeetCode热题100
  • Docker搭建zookeeper
  • LeetCode 热题 100 JavaScript--160. 相交链表
  • AWS S3 协议对接 minio/oss 等
  • 手机便签内容不见了怎么恢复正常?
  • 【架构】Java 系统架构演进的思考
  • Python爬虫——解析_jsonpath
  • 华为发布数字资产继承功能
  • 阿里云NAS文件存储基本介绍与购买使用
  • 大模型使用——超算上部署LLAMA-2-70B-Chat
  • 机器学习笔记:李宏毅ChatGPT课程1:刨析ChatGPT
  • Llama 2 with langchain项目详解(三)
  • 牛客 AB30 排序(快排模板)
  • 【Linux旅行记】第一个小程序“进度条“!
  • DeepMind将AI用于可控核聚变:将等离子体形状模拟精度提高65%
  • Scrum是什么意思,Scrum敏捷项目管理工具有哪些?
  • 【从零单排Golang】第十三话:使用WaitGroup等待多路并行的异步任务
  • WSL2安装CentOS7和CentOS8
  • 不平衡电网条件下基于变频器DG操作的多目标优化研究(Matlab代码Simulink实现)