news 2026/6/15 19:02:47

如何利用AS32系列MCU芯片使用简洁单线模式操作QSPI FLASH?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何利用AS32系列MCU芯片使用简洁单线模式操作QSPI FLASH?

QSPI(Quad Serial Peripheral Interface) 是一种高速串行通信接口,在标准SPI(Serial Peripheral Interface)的基础上扩展至4条数据线(Quad Mode),显著提升数据传输速率。它广泛应用于Flash存储器、传感器和微控制器之间的通信。AS32系列MCU芯片开发板集成了一块S25FL512SAGMFVG13型号的QSPI FLASH,本文我们将介绍该系列芯片使用简洁单线模式操作QSPI FLASH。

代码详解:

1、扇区擦除函数

根据指导手册我们知道,在进行扇区擦除命令之前必须先给一个WREN 命令,该命令会将状态寄存器中的写使能锁存器(WEL)置位,以允许任何写入操作。此外,本文用例使用3字节地址,根据时序图可知,应先发送指令(长度可配置)接着发送一个24位地址。

我们开始讲解扇区擦除函数,代码如下:

#define WRITE_ENABLE_INST 0x06

#define WRITE_DISBALE_INST 0x04

#define ERASE_SECTOR_INST 0xD8

#define READ_RIGISTER1_INST 0x05

#define PAGE_PROGRAME_INST 0x02

#define READ_FLASH_INST 0x03

voidQSPI_FlashErase(uint32_t block_start, uint32_t sector_num)

{

uint32_t dst;

uint32_t SR_Status;

uint8_t erase_status = 1;

dst = block_start;

uint32_t num = sector_num-1;

if(dst + num * 0x3FFFF> 0xFFFFFF)

{

Printf("error :Exceeds the erase range.\r\n");

}

QSPI_Reset();

QSPI_Deinit();

QSPI_StructInitenable();

QSPI_WriteEnable();

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

for(uint32_t i = 0; i < num; i++)

{

QSPI_SectorErase();

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

QSPI_SetAddr(dst + num*0x3FFFF);

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

}

while(erase_status)

{

QSPI_SetDataLength(0);

QSPI_ReadStatus_Rigister1();

delay_ms(10);

erase_status = QSPI_ReadData();

}

QSPI_ReadFlash(dst, PROGRAME_SIZE, QSPI_BUFFER );

}

首先看第16行,对QSPI结构体初始化,分别配置片选高电平时间,QSPI时钟信号在指令之间的电平,QSPI时钟分频。

接着第17行,发送写使能命令。该函数主要配置QSPI->CCR寄存器,主要配置指令写使能指令和简介写模式,其余配置读者可查阅AS32X601设计手册的QSPI章节,这里不做过多赘述。

第22行,进行扇区擦除,和写使能函数一致,区别在于配置不同的指令,第24行设置需要擦除区域的首地址。

第30行,配置QSPI数据长度寄存器(DLR)为0,我们需要读取1字节,即SR1寄存器8位。第31行,我们发送读取QSPI FLASH的SR1寄存器指令。第33行,读取QSPI FLASH返回的8位数据,直到erase_status = 0时,我们擦除操作完成。这里是间接读取模式,还可使用轮询模式,减少CPU等待时间,完全交给QSPI FLASH来处理数据。

以下是读取SR1寄存器的相关配置,和擦除函数一致,区别在于指令,当然读者可以自行配置QSPI 为2线或4线。

2、读QSPI FLASH

接上节,我们在最后调用了QSPI_ReadFlash函数,本章节详细讲解该函数,先看FLASH手册,

该指令允许从存储器阵列的任意字节地址开始读取。每输出一个字节数据后,地址会自动递增至下一个更高地址(按顺序连续递增)。因此,只需提供起始地址000000h并发送一次读指令,即可连续读取整个存储器的内容。当到达最高地址后,地址计数器将自动回绕至000000h,从而支持无限循环的连续读取操作。

函数如下:

voidQSPI_ReadFlash(uint32_t block_start, uint32_t byte_num, uint32_t buffer[])

{

uint32_t FIFO_LEVEL = 0;

QSPI_WriteEnable();

QSPI_SetDataLength(byte_num);

QSPI_Read_Flash();

QSPI_SetAddr(block_start);

delay_ms(10);

FIFO_LEVEL = QSPI_GetFIFOLevel();

while(FIFO_LEVEL != 0)

{

for(uint32_t i=0;i<FIFO_LEVEL;i++)

{

buffer[i] = QSPI_ReadData();

Printf("%x\t",buffer[i]);

}

FIFO_LEVEL = QSPI_GetFIFOLevel();

}

QSPI_WriteDisable();

}

同样在读数据之前需要解锁QSPI FLASH,并在操作完成后上锁。第5行,设置读取需要读取的字节数,第6行,调用QSPI_READ_FLASH(),函数如下,第9行,获取FIFO中有效字节数,当FIFO非空时,读QSPI->DR寄存器获取数据,直到FIFO为空。

3、下板验证

程序初始化后,调用QSPI_FlashErase(0x00, 1),从0地址开始,擦除1个扇区,观察打印信息,并截取了逻辑分析仪片段。

4、页编程函数

主要内容:若地址的最低9位(A8-A0)不全为0,则超出当前页末尾的传输数据将从同一页的起始地址(即最低9位全为0的地址)开始编程,即地址会在页对齐的边界内回绕。这是因为用户只需输入单个页地址即可覆盖整个页边界。

如果发送给设备的数据不足一页,这些数据字节将从所提供地址开始按顺序编程,而不会影响同一页内的其他字节。

为优化时序,使用页编程(PP)命令在页边界内加载整个页大小的编程缓冲器,相比于加载不足一页的数据到编程缓冲器,将节省总体编程时间。

intQSPI_FlashWrite(uint32_t block_start,uint32_t offset_into_block, uint32_t count, uint32_t buffer[])

{

uint32_t dst;

uint32_t ii;

uint32_t num;

dst = block_start + offset_into_block;

num = count;

if(dst%4 != 0)

{

Printf( "the addr must 4-byte alignment\r\n");

return0;

}

QSPI_Deinit();

if((dst%256) == 0)

{intloop = 0;

Printf( "the first packge is 256 bytes\r\n");

while(num > 256)

{

QSPI_StructInitenable();

QSPI_SetDataLength(0xff);

QSPI_WriteEnable();

QSPI_PageProgram();

QSPI_SetAddr(dst);

for(ii = loop*256/4; ii < loop*256/4+64; ii++)

{

QSPI->DR = buffer[ii];

}

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

dst += 256;

num -= 256;

delay_ms(20);

loop++;

}

QSPI_StructInitenable();

QSPI_SetDataLength(block_start + offset_into_block + count - dst -1);

QSPI_WriteEnable();

QSPI_PageProgram();

QSPI_SetAddr(dst);

for(ii = 256*loop/4; ii < (256*loop+block_start + offset_into_block + count - dst)/4; ii++)

{

QSPI->DR = buffer[ii];

}

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

dst += block_start + offset_into_block + count – dst;

}

else

{

QSPI_StructInitenable();

QSPI_WriteEnable();

QSPI_PageProgram();

QSPI_SetAddr(dst);

QSPI_SetDataLength(256-(dst%256));

for(ii = 0; ii < (256-(dst%256))/4; ii++)

{

QSPI->DR = buffer[ii];

}

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

dst += 256-(dst%256);

while(num > 256)

{

QSPI_StructInitenable();

QSPI_WriteEnable();

QSPI_PageProgram();

QSPI_SetAddr(dst);

QSPI_SetDataLength(256-1);

for(ii = 0; ii < 64; ii++)

{

QSPI->DR = buffer[ii];

}

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

dst += 256;

num -= 256;

}

QSPI_StructInitenable();

QSPI_WriteEnable();

QSPI_PageProgram();

QSPI_SetAddr(dst);

QSPI_SetDataLength(block_start + offset_into_block + count - dst -1);

for(ii = 0; ii < (block_start + offset_into_block + count - dst)/4; ii++)

{

QSPI->DR = buffer[ii];

}

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

dst += block_start + offset_into_block + count - dst;

}

QSPI_WriteDisable();

while( (QSPI_GetFlagStatus(QSPI_FLAG_BUSY) == 1));

QSPI_ReadFlash(block_start,PROGRAME_SIZE,QSPI_BUFFER);

return0; //RESULT_OK

}

第1至13行定义了函数参数并计算目标地址,同时检查地址是否4字节对齐,若未对齐则报错返回。第14行对QSPI控制器进行复位。第15至48行处理目标地址256字节对齐的情况:第16至35行循环写入完整的256字节数据页,每次写入前初始化硬件、设置数据长度、使能写入、发送页编程命令并设置地址,随后通过循环写入64个32位数据,等待操作完成后更新地址和剩余计数;第36至47行处理剩余不足256字节的数据尾部,采用类似的流程但数据长度根据剩余量动态计算。第49至88行处理目标地址未256字节对齐的情况:第51至60行先写入从起始地址到下一个256字节边界的首部数据片段;第61至75行循环写入后续完整的256字节页;第76至87行处理最后的尾部数据。

5、下板验证

准备写入1024个数,0-0x3FF,共4K,从0地址开始,观察打印信息

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 18:24:39

AS32S601型MCU芯片电源管理(PMU)模块详解

一、电源管理模块 PMU&#xff08;Power Management Unit&#xff09;电源管理模块 PMU是芯片的 “能耗与电源管家”&#xff0c;核心目标是平衡功耗与供电稳定性&#xff0c;适配嵌入式设备的低功耗、长续航需求&#xff0c;具体作用包括&#xff1a;1. 多电源域的独立管控为了…

作者头像 李华
网站建设 2026/6/15 11:46:30

全网热议!2025年度最佳数字人公司排行榜,助你引领智能时代

在数字化转型的浪潮中&#xff0c;数字人技术正走向前沿&#xff0c;吸引了广泛关注。本文将为您揭晓2025年度最佳数字人公司排行榜&#xff0c;深入分析这些公司如何通过创新与技术&#xff0c;助力智能时代的到来。让我们一起探寻这些杰出公司的优势与发展潜力&#xff0c;助…

作者头像 李华
网站建设 2026/6/15 11:43:45

如何快速配置LyricsX:Mac桌面歌词显示终极指南

如何快速配置LyricsX&#xff1a;Mac桌面歌词显示终极指南 【免费下载链接】Lyrics Swift-based iTunes plug-in to display lyrics on the desktop. 项目地址: https://gitcode.com/gh_mirrors/lyr/Lyrics 还在为Mac音乐播放器缺乏专业歌词显示功能而烦恼吗&#xff1f…

作者头像 李华
网站建设 2026/6/15 9:33:30

网易云音乐快速听歌神器:3步实现个性化推荐与播放量提升

网易云音乐快速听歌神器&#xff1a;3步实现个性化推荐与播放量提升 【免费下载链接】netease-cloud-fastplay 网易云音乐快速听歌&#xff0c;自定义听歌风格&#xff0c;一键刷听歌次数 项目地址: https://gitcode.com/gh_mirrors/ne/netease-cloud-fastplay 网易云音…

作者头像 李华
网站建设 2026/6/15 8:41:30

解锁室内AI训练新纪元:Habitat-Matterport 3D数据集全方位指南

解锁室内AI训练新纪元&#xff1a;Habitat-Matterport 3D数据集全方位指南 【免费下载链接】habitat-matterport3d-dataset This repository contains code to reproduce experimental results from our HM3D paper in NeurIPS 2021. 项目地址: https://gitcode.com/gh_mirro…

作者头像 李华
网站建设 2026/6/15 9:36:53

web前端:基于Three.js库的星云探索交互网页

设计概述 本次分享将介绍如何使用Three.js库创建一个沉浸式的 "星云探索" 交互应用。这个项目通过WebGL构建可视化的星系模型&#xff0c;结合自定义着色器实现动态星云效果&#xff0c;构建了一个包含星系生成、交互探索、状态管理的完整应用&#xff0c;展现了Web…

作者头像 李华