【STM32 CubeMX】SPI W25Q64功能实现

这篇具有很好参考价值的文章主要介绍了【STM32 CubeMX】SPI W25Q64功能实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

SPI Flash 存储器在嵌入式系统中扮演着重要角色,它可以为微控制器提供额外的存储空间,并且具有快速的读写速度和较大的存储容量。W25Q64 是一款常见的 SPI Flash 存储器,容量为64Mb,采用 SPI 接口进行通信。在 STM32 微控制器上实现对 W25Q64 的功能使用,可以通过 STM32 CubeMX 和相关的库函数轻松完成。本文将介绍如何利用 STM32 CubeMX 和 SPI 库来实现对 W25Q64 的基本功能。


一、内部函数的实现

1.1 选中和取消选中SPI Flash

当CS引脚为GPIO_PIN_RESET为选中该设备,当CS引脚为GPIO_PIN_SET表示取消选中该设备,所以这个函数非常好实现,只需要使用HAL_GPIO_WritePin函数进行写pin即可

static void SPIFlash_Select(void)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET);
}

static void SPIFlash_DeSelect(void)
{
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);
}

1.2 写使能函数

如果你需要写使能,你只需要发送命令0x06即可,你可以使用查询方式来发送,也可以使用中断函数来发送。
在发送命令的时候,你需要选中该Flash设备,当你写完命令后,需要取消选中Flash设备。
【STM32 CubeMX】SPI W25Q64功能实现,从0带你学会如何像人类一样写STM32程序,stm32,嵌入式硬件,单片机,c语言,c,SPI Flash,mcu
我们可以这样实现他:

static volatile int g_spi1_tx_complete = 0;
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
	if(hspi == &hspi1)
	{
		g_spi1_tx_complete = 1;
	}
}

void Wait_SPI_TxCplt(int timeout)
{
	while(g_spi1_tx_complete == 0 && timeout--)
	{
		HAL_Delay(1);
	}
	g_spi1_tx_complete = 0;
}

static int SPIFlash_WriteEnable(void)
{
	uint8_t buf[1] = {0x06};
	SPIFlash_Select();
	HAL_SPI_Transmit_IT(&hspi1,buf,1);
	Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);
	SPIFlash_DeSelect();
}

1.3 获取读状态

当我们擦除扇区或者写扇区的时候,他并不是发送数据完成,这个数据就写进去的,我们需要等待他内部编程完。我们可以使用命令,把里面的状态拿出来
【STM32 CubeMX】SPI W25Q64功能实现,从0带你学会如何像人类一样写STM32程序,stm32,嵌入式硬件,单片机,c语言,c,SPI Flash,mcu
在这里,我们需要发送2个命令,但是有用的只有命令1(发送的命令为0x05),因为发送了2个命令,所以我们需要接收两个数据,但是有用的只有接收到的数据2。

static volatile int g_spi1_txrx_complete = 0;
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
	if(hspi == &hspi1)
	{
		g_spi1_txrx_complete = 1;
	}
}

void Wait_SPI_TxRxCplt(int timeout)
{
	while(g_spi1_txrx_complete == 0 && timeout--)
	{
		HAL_Delay(1);
	}
	g_spi1_txrx_complete = 0;
}

static int SPIFlash_ReadStatus(void)
{
		uint8_t txbuf[2] = {0x05,0xff};
		uint8_t rxbuf[2] = {0,0};
		SPIFlash_Select();
		HAL_SPI_TransmitReceive_IT(&hspi1, txbuf, rxbuf, 2);
		Wait_SPI_TxRxCplt(SPI_FLASH_TIMEOUT);
		SPIFlash_DeSelect();
		
		return rxbuf[1];
}

1.4 等待就绪状态

所谓的等待就绪状态其实就是当SPIFlash_ReadStatus函数&上1他还是等于1,就代表擦除扇区或者写扇区已经完成了

static int SPIFlash_WaitReady(void)
{
	while(SPIFlash_ReadStatus() & 1 == 1);
}

二、Flash读写函数实现

2.1 读Flash ID

读Flash ID可以让我们知道这个SPI Flash是否有用
和前面的获取读状态一样。在这里,我们需要发送2个命令,但是有用的只有命令1(发送的命令为0x9F),因为发送了2个命令,所以我们需要接收两个数据,但是有用的只有接收到的数据2。

int SPIFlash_ReadID(void)
{
	uint8_t txbuf[2] = {0x9F,0xff};
	uint8_t rxbuf[2] = {0,0};
	
	SPIFlash_Select();
	HAL_SPI_TransmitReceive_IT(&hspi1, txbuf, rxbuf, 2);
	Wait_SPI_TxRxCplt(SPI_FLASH_TIMEOUT);
	SPIFlash_DeSelect();
	
	return rxbuf[1];
}

当rxbuf[1]的值为0xEF时,代码这个SPI Flash没有问题

2.2 擦除某个扇区

首先,我们要发送命令加上3个字节的地址,所以我们需要4字节的buf
如果你想擦除某个扇区,你需要使用0x20命令。
接下来,我们往buf的后3字节填充地址,地址是先发高位再发低位的。
再完成发送之后,我们还需要等待就绪,即调用SPIFlash_WaitReady函数

int SPIFlash_EraseSector(uint32_t addr)
{
	SPIFlash_WriteEnable();
	
	uint8_t txbuf[4] = {0x20};
	
	txbuf[1] = addr>>16 & 0xff;
	txbuf[2] = addr>>8 & 0xff;
	txbuf[3] = addr>>0 & 0xff;
	
	SPIFlash_Select();
	HAL_SPI_Transmit_IT(&hspi1,txbuf,4);
	Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);
	SPIFlash_DeSelect();
	
	SPIFlash_WaitReady();
	
	return 0;
}

2.3 写扇区

写操作在发送命令+地址的和我们的擦除某个扇区的是一样的,只不过我们的写扇区的命令为0x02
再发送完命令+地址之后,我们就可以直接调用HAL库的发送函数进行datas的发送即可。

int SPIFlash_Write(uint32_t addr,uint8_t *datas,uint32_t len)
{
	SPIFlash_WriteEnable();
	
	uint8_t txbuf[4] = {0x02};
	
	txbuf[1] = addr>>16 & 0xff;
	txbuf[2] = addr>>8 & 0xff;
	txbuf[3] = addr>>0 & 0xff;
	
	SPIFlash_Select();
	HAL_SPI_Transmit_IT(&hspi1,txbuf,4);
	Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);
	
	HAL_SPI_Transmit_IT(&hspi1,datas,len);
	Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);
	
	SPIFlash_DeSelect();
	
	SPIFlash_WaitReady();
	
	return 0;
}

2.4 读数据

读操作在发送命令+地址的和我们的擦除某个扇区的是一样的,只不过我们的写扇区的命令为0x03
在写完上面这些数据之后,我们需要等待写完,接下来我们就可以去调用HAL库的读SPI函数了

static volatile int g_spi1_rx_complete = 0;

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
	if(hspi == &hspi1)
	{
		g_spi1_rx_complete = 1;
	}
}

void Wait_SPI_RxCplt(int timeout)
{
	while(g_spi1_rx_complete == 0 && timeout--)
	{
		HAL_Delay(1);
	}
	g_spi1_rx_complete = 0;
}

int SPIFlash_Read(uint32_t addr,uint8_t *datas,uint32_t len)
{
	uint8_t txbuf[4] = {0x03};
	
	txbuf[1] = addr>>16 & 0xff;
	txbuf[2] = addr>>8 & 0xff;
	txbuf[3] = addr>>0 & 0xff;
	
	SPIFlash_Select();
	HAL_SPI_Transmit_IT(&hspi1,txbuf,4);
	Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);
	
	HAL_SPI_Receive_IT(&hspi1,datas,len);
	Wait_SPI_RxCplt(SPI_FLASH_TIMEOUT);
	
	SPIFlash_DeSelect();
	
	return 0;
}

三、测试代码

char *str = "www.csdn.net\r\n";
	
r = SPIFlash_ReadID();
SPIFlash_EraseSector(4096);
SPIFlash_Write(4096,(uint8_t*)str,strlen(str)+1);
SPIFlash_Read(4096,(uint8_t*)flash_buf,20);

总结

通过本文的介绍,我们了解了如何在 STM32 CubeMX 中配置并利用 SPI 库来实现对 W25Q64 SPI Flash 存储器的功能。首先,我们通过 CubeMX 配置了 STM32 的 SPI 外设,包括时钟分频、数据大小、模式等参数。然后,我们编写了初始化代码,将 SPI 外设与 W25Q64 进行连接,并实现了基本的读写功能。在编写代码时,我们充分利用了 STM32 的 HAL 库提供的函数,简化了通信过程的实现。最后,我们在主函数中调用了相应的读写函数,并通过调试工具验证了功能的正确性。通过本文的学习,读者可以掌握在 STM32 微控制器上使用 CubeMX 和 SPI 库来实现对 W25Q64 SPI Flash 存储器的功能,为嵌入式系统的开发提供了便利。文章来源地址https://www.toymoban.com/news/detail-835080.html

到了这里,关于【STM32 CubeMX】SPI W25Q64功能实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】SPI初步使用 读写FLASH W25Q64

    (1) SS( Slave Select):从设备选择信号线,常称为片选信号线,每个从设备都有独立的这一条 NSS 信号线,当主机要选择从设备时,把该从设备的 NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行 SPI通讯。所以 SPI通讯以 NSS 线置低电

    2024年02月10日
    浏览(57)
  • 【STM32】STM32学习笔记-硬件SPI读写W25Q64(40)

    在大容量产品和互联型产品上,SPI接口可以配置为支持SPI协议或者支持I2S音频协议。SPI接口默认工作在SPI方式,可以通过软件把功能从SPI模式切换到I2S模式。 在小容量和中容量产品上,不支持I2S音频协议。 串行外设接口(SPI)允许芯片与外部设备以半/全双工、同步、串行方式

    2024年02月19日
    浏览(69)
  • 【STM32】STM32学习笔记-软件SPI读写W25Q64(38)

    在大容量产品和互联型产品上,SPI接口可以配置为支持SPI协议或者支持I 2 S音频协议。SPI接口默认工作在SPI方式,可以通过软件把功能从SPI模式切换到I2S模式。 在小容量和中容量产品上,不支持I 2 S音频协议。 串行外设接口(SPI)允许芯片与外部设备以半/全双工、同步、串行方

    2024年01月24日
    浏览(51)
  • STM-32:SPI通信协议/W25Q64简介—软件SPI读写W25Q64

    SPI是串行外设接口(Serial Peripheral Interface)的缩写,是美国摩托罗拉公司(Motorola)最先推出的一种同步串行传输规范,也是一种单片机外设芯片串行扩展接口,是一种高速、全双工、同步通信总线,所以可以在同一时间发送和接收数据,SPI没有定义速度限制,通常能达到甚

    2024年02月16日
    浏览(47)
  • 【STM32篇】SPI时序驱动W25Q64(硬件SPI和模拟SPI)

            由于MCU的FLASH空间有限,在特殊使用场所中会存在FLASH存储不够使用的情况。例如上篇中驱动LCD屏,需要将一个中文字库保存到MCU的FLASH中是不太现实的(STM32F103ZET6内部FLASH大小512KB),为此可使用外部FLASH作为拓展。         W25Q64(64Mbit)是为系统提供一个最小的空

    2024年02月08日
    浏览(51)
  • W25Q64模块以及STM32代码

    W25Qxx 系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、字库存储、固件程序存储等场景 ( 易失性存储器:SRAM、DRAM...              非易失性存储器:E2PROM、Flash... ) 存储介质: Nor Flash (闪存) 时钟频率: 80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI

    2024年04月10日
    浏览(75)
  • STM32驱动W25Q64读写数据

    1.采用串行Nor flash外扩存储芯片 2.支持SPI接口 3.工作电压:2.7~3.6V 4.容量: 32Mbit(W25Q32) 64Mbit(W25Q64) 128Mbit(W25Q128) 此处使用硬件SPI 引脚 功能 CS(NSS) 片选,低电平有效 SCK 时钟信号引脚 MISO/DO 模块数据输出引脚 MOSI/DI 模块数据输入引脚 W25Q64模块 STM32F103C8T6 VCC 3.3V SPI_CS GPIO

    2023年04月08日
    浏览(52)
  • 26、江科大stm32视频学习笔记——W25Q64简介

    一、W25Q64简介 1、W25Q64的内存空间结构:  一页256字节,4K(4096 字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048 个扇区。   2、W25Q64每页大小由256字节组成,每页的256字节用一次页编程指令即可完成。 3、擦除指令分别支持: 16页(1个扇区)、128页、256页、全片

    2024年01月22日
    浏览(53)
  • Clion开发Stm32之存储模块(W25Q64)驱动编写

    涵盖之前文章: Clion开发STM32之HAL库SPI封装(基础库) 头文件 源文件

    2024年02月10日
    浏览(51)
  • 【STM32篇】LCD显示汉字(从W25Q64中读取GBK字库)

            汉字显示在很多单片机产品中都需要用到,显示个别汉字可使用MCU的flash保存汉字字模,而显示更多的汉字就可能要在产品中保存一整个字库作为汉字储备。对于STM32F103VET6单片机FLASH只有512K字节,要存下一个字库就有点乏力且浪费单片机资源。在上一章节中完成了

    2024年02月09日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包