STM32系列(HAL库)——F103C8T6通过SPI方式读写W25Q64—(Flash存储模块)

article/2025/8/22 1:04:31

1.软件准备

(1)编程平台:Keil5

(2)CubeMX

(3)XCOM(串口调试助手)

2.硬件准备

(1)W25Q64模块

(2)F1的板子,本例使用经典F103C8T6

(3)ST-link 下载器

(4)USB-TTL模块

(5)杜邦线若干

3.模块资料

(1)模块简介:

  • W25Q64(64M-bit),W25Q16(16M-bit)和W25Q32(32M-bit)是为系统提供一个最小的空间、引脚和功耗的存储器解决方案的串行Flash存储器。25Q系列比普通的串行Flash存储器更灵活,性能更优越。基于双倍/四倍的SPI,它们能够可以立即完成提供数据给RAM,包括存储声音、文本和数据。芯片支持的工作电压2.7V到3.6V,正常工作时电流小于5mA,掉电时低于1uA。所有芯片提供标准的封装。
  •  W25Q64/16/32由每页256字节组成。每页的256字节用一次页编程指令即可完成。每次可以擦除16页(1个扇区)、128页(32KB块)、256页(64KB块)和全片擦除。
  •  W25Q64的内存空间结构:一页256字节,4K(4096字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048个扇区。
  •  W25Q64/16/32支持标准串行外围接口(SPI),和高速的双倍/四倍输出,双倍/四倍用的引脚:串行时钟、片选端、串行数据I/00(DI)、I/01(DO)、I/O2(WP)和I/03(HOLD)。SPI最高支持8OMHz,当用快读双倍/四倍指令时,相当于双倍输出时最高速率160MHz,四倍输出时最高速率32OMHz。这个传输速率比得上8位和16位的并行Flash存储器。

(2)模块参数:

  1.  采用串行Nor flash外扩存储芯片
  2. 支持SPI接口 
  3. 工作电压:2.7~3.6V
  4. 容量: 32Mbit(W25Q32)、64Mbit(W25Q64)、128Mbit(W25Q128) 

 (3)参考原理图:

更多资料可参考:W25Q64数据手册

4.CubeMX配置

(1)芯片选择

 (2)配置RCC、SYS、时钟树

配置RCC

配置SYS

配置时钟树

(3)配置串口1

(4)配置SPI1

(5)配置GPIO

 (6)设置路径、生成代码工程 

5、Keil5代码

(1)勾选Use MicroLIB

(2)创建W25Qxx.c和W25Qxx.h文件

(3)添加上述的W25Qxx.c文件进工程

——————上述两步参考之前系列教学步骤,在此不再赘述(点击跳转)

(4)W25Qxx.c和W25Qxx.h代码

        W25Qxx.h

#ifndef __W25Qxx_H
#define __W25Qxx_H/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx.h"
#include "spi.h"#define W25Q128FV_FLASH_SIZE                  0x1000000 /* 128 MBits => 16MBytes */
#define W25Q128FV_SECTOR_SIZE                 0x10000   /* 256 sectors of 64KBytes */
#define W25Q128FV_SUBSECTOR_SIZE              0x1000    /* 4096 subsectors of 4kBytes */
#define W25Q128FV_PAGE_SIZE                   0x100     /* 65536 pages of 256 bytes */#define W25Q128FV_DUMMY_CYCLES_READ           4
#define W25Q128FV_DUMMY_CYCLES_READ_QUAD      10#define W25Q128FV_BULK_ERASE_MAX_TIME         250000
#define W25Q128FV_SECTOR_ERASE_MAX_TIME       3000
#define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME    800
#define W25Qx_TIMEOUT_VALUE 1000/* Reset Operations */
#define RESET_ENABLE_CMD                     0x66
#define RESET_MEMORY_CMD                     0x99#define ENTER_QPI_MODE_CMD                   0x38
#define EXIT_QPI_MODE_CMD                    0xFF/* Identification Operations */
#define READ_ID_CMD                          0x90
#define DUAL_READ_ID_CMD                     0x92
#define QUAD_READ_ID_CMD                     0x94
#define READ_JEDEC_ID_CMD                    0x9F/* Read Operations */
#define READ_CMD                             0x03
#define FAST_READ_CMD                        0x0B
#define DUAL_OUT_FAST_READ_CMD               0x3B
#define DUAL_INOUT_FAST_READ_CMD             0xBB
#define QUAD_OUT_FAST_READ_CMD               0x6B
#define QUAD_INOUT_FAST_READ_CMD             0xEB/* Write Operations */
#define WRITE_ENABLE_CMD                     0x06
#define WRITE_DISABLE_CMD                    0x04/* Register Operations */
#define READ_STATUS_REG1_CMD                  0x05
#define READ_STATUS_REG2_CMD                  0x35
#define READ_STATUS_REG3_CMD                  0x15#define WRITE_STATUS_REG1_CMD                 0x01
#define WRITE_STATUS_REG2_CMD                 0x31
#define WRITE_STATUS_REG3_CMD                 0x11/* Program Operations */
#define PAGE_PROG_CMD                        0x02
#define QUAD_INPUT_PAGE_PROG_CMD             0x32/* Erase Operations */
#define SECTOR_ERASE_CMD                     0x20
#define CHIP_ERASE_CMD                       0xC7#define PROG_ERASE_RESUME_CMD                0x7A
#define PROG_ERASE_SUSPEND_CMD               0x75/* Flag Status Register */
#define W25Q128FV_FSR_BUSY                    ((uint8_t)0x01)    /*!< busy */
#define W25Q128FV_FSR_WREN                    ((uint8_t)0x02)    /*!< write enable */
#define W25Q128FV_FSR_QE                      ((uint8_t)0x02)    /*!< quad enable */#define W25Qx_Enable() 			HAL_GPIO_WritePin(W25QXX_CS_GPIO_Port, W25QXX_CS_Pin, GPIO_PIN_RESET)
#define W25Qx_Disable() 		HAL_GPIO_WritePin(W25QXX_CS_GPIO_Port, W25QXX_CS_Pin, GPIO_PIN_SET)#define W25Qx_OK            ((uint8_t)0x00)
#define W25Qx_ERROR         ((uint8_t)0x01)
#define W25Qx_BUSY          ((uint8_t)0x02)
#define W25Qx_TIMEOUT		((uint8_t)0x03)uint8_t BSP_W25Qx_Init(void);
static void	BSP_W25Qx_Reset(void);
static uint8_t BSP_W25Qx_GetStatus(void);
uint8_t BSP_W25Qx_WriteEnable(void);
void BSP_W25Qx_Read_ID(uint8_t *ID);
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address);
uint8_t BSP_W25Qx_Erase_Chip(void);#endif 

W25Qxx.c

#include "W25Qxx.h"/*********************************************************************************** 函数功能: 模块初始化*/
uint8_t BSP_W25Qx_Init(void)
{ 	BSP_W25Qx_Reset();	return BSP_W25Qx_GetStatus();
}static void	BSP_W25Qx_Reset(void)
{uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD};W25Qx_Enable();/* Send the reset command */HAL_SPI_Transmit(&hspi1, cmd, 2, W25Qx_TIMEOUT_VALUE);	W25Qx_Disable();}/*********************************************************************************** 函数功能: 获取设备状态*/
static uint8_t BSP_W25Qx_GetStatus(void)
{uint8_t cmd[] = {READ_STATUS_REG1_CMD};uint8_t status;W25Qx_Enable();/* Send the read status command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);	/* Reception of the data */HAL_SPI_Receive(&hspi1,&status, 1, W25Qx_TIMEOUT_VALUE);W25Qx_Disable();/* Check the value of the register */if((status & W25Q128FV_FSR_BUSY) != 0){return W25Qx_BUSY;}else{return W25Qx_OK;}		
}/*********************************************************************************** 函数功能: 写使能*/
uint8_t BSP_W25Qx_WriteEnable(void)
{uint8_t cmd[] = {WRITE_ENABLE_CMD};uint32_t tickstart = HAL_GetTick();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);	/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE){        return W25Qx_TIMEOUT;}}return W25Qx_OK;
}/*********************************************************************************** 函数功能: 获取设备ID*/
void BSP_W25Qx_Read_ID(uint8_t *ID)
{uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00};W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);	/* Reception of the data */HAL_SPI_Receive(&hspi1,ID, 2, W25Qx_TIMEOUT_VALUE);W25Qx_Disable();}/*********************************************************************************** 函数功能: 读数据* 输入参数: 缓存数组指针、读地址、字节数*/
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{uint8_t cmd[4];/* Configure the command */cmd[0] = READ_CMD;cmd[1] = (uint8_t)(ReadAddr >> 16);cmd[2] = (uint8_t)(ReadAddr >> 8);cmd[3] = (uint8_t)(ReadAddr);W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);	/* Reception of the data */if (HAL_SPI_Receive(&hspi1, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}W25Qx_Disable();return W25Qx_OK;
}/*********************************************************************************** 函数功能: 写数据* 输入参数: 缓存数组指针、写地址、字节数*/
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{uint8_t cmd[4];uint32_t end_addr, current_size, current_addr;uint32_t tickstart = HAL_GetTick();/* Calculation of the size between the write address and the end of the page */current_addr = 0;while (current_addr <= WriteAddr){current_addr += W25Q128FV_PAGE_SIZE;}current_size = current_addr - WriteAddr;/* Check if the size of the data is less than the remaining place in the page */if (current_size > Size){current_size = Size;}/* Initialize the adress variables */current_addr = WriteAddr;end_addr = WriteAddr + Size;/* Perform the write page by page */do{/* Configure the command */cmd[0] = PAGE_PROG_CMD;cmd[1] = (uint8_t)(current_addr >> 16);cmd[2] = (uint8_t)(current_addr >> 8);cmd[3] = (uint8_t)(current_addr);/* Enable write operations */BSP_W25Qx_WriteEnable();W25Qx_Enable();/* Send the command */if (HAL_SPI_Transmit(&hspi1,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}/* Transmission of the data */if (HAL_SPI_Transmit(&hspi1, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE){        return W25Qx_TIMEOUT;}}/* Update the address and size variables for next page programming */current_addr += current_size;pData += current_size;current_size = ((current_addr + W25Q128FV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25Q128FV_PAGE_SIZE;} while (current_addr < end_addr);return W25Qx_OK;
}/*********************************************************************************** 函数功能: 扇区擦除* 输入参数: 地址*/
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address)
{uint8_t cmd[4];uint32_t tickstart = HAL_GetTick();cmd[0] = SECTOR_ERASE_CMD;cmd[1] = (uint8_t)(Address >> 16);cmd[2] = (uint8_t)(Address >> 8);cmd[3] = (uint8_t)(Address);/* Enable write operations */BSP_W25Qx_WriteEnable();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);	/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Q128FV_SECTOR_ERASE_MAX_TIME){        return W25Qx_TIMEOUT;}}return W25Qx_OK;
}/*********************************************************************************** 函数功能: 芯片擦除*/
uint8_t BSP_W25Qx_Erase_Chip(void)
{uint8_t cmd[4];uint32_t tickstart = HAL_GetTick();cmd[0] = CHIP_ERASE_CMD;/* Enable write operations */BSP_W25Qx_WriteEnable();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);	/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() != W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Q128FV_BULK_ERASE_MAX_TIME){        return W25Qx_TIMEOUT;}}return W25Qx_OK;
}

(5) usart.c函数添加

/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 *//* USER CODE BEGIN 1 */
/*********************************************************
*
*重定义 fputc 函数
*
*********************************************************/
int fputc(int ch,FILE *f)
{HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );return ch;
}
/* USER CODE END 1 */

(6)main函数

#include <string.h>
#include <stdio.h>
#include "W25Qxx.h"uint8_t wData[0x100];   //写缓存数组
uint8_t rData[0x100];   //读缓存数组
uint8_t ID[4];          //设备ID缓存数组
uint32_t i;void SystemClock_Config(void);int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_SPI1_Init();MX_USART1_UART_Init();printf("\r\n SPI-W25Qxx Example \r\n\r\n");/*-Step1- 验证设备ID  ************************************************Step1*/ BSP_W25Qx_Init();BSP_W25Qx_Read_ID(ID);//第一位厂商ID固定0xEF,第二位设备ID根据容量不同,具体为://W25Q16为0x14、32为0x15、40为0x12、64为0x16、80为0x13、128为0x17if((ID[0] != 0xEF) | (ID[1] != 0x16)) {                                printf("something wrong in Step1 \r\n");}else{printf(" W25Qxx ID is : ");for(i=0;i<2;i++){printf("0x%02X ",ID[i]);}printf("\r\n");}/*-Step2- 擦除块  ************************************************Step2*/ 	if(BSP_W25Qx_Erase_Block(0) == W25Qx_OK)printf(" QSPI Erase Block OK!\r\n");elseprintf("something wrong in Step2\r\n");/*-Step3- 写数据  ************************************************Step3*/	for(i =0;i<0x100;i ++){wData[i] = i;rData[i] = 0;}if(BSP_W25Qx_Write(wData,0x00,0x100)== W25Qx_OK)printf(" QSPI Write OK!\r\n");elseprintf("something wrong in Step3\r\n");/*-Step4- 读数据  ************************************************Step4*/	if(BSP_W25Qx_Read(rData,0x00,0x100)== W25Qx_OK)printf(" QSPI Read ok\r\n\r\n");elseprintf("something wrong in Step4\r\n");printf("QSPI Read Data : \r\n");for(i =0;i<0x100;i++)printf("0x%02X  ",rData[i]);printf("\r\n\r\n");/*-Step5- 数据对比  ************************************************Step5*/		if(memcmp(wData,rData,0x100) == 0 ) printf(" W25Q64FV QuadSPI Test OK\r\n");elseprintf(" W25Q64FV QuadSPI Test False\r\n");while (1){}}

6.接线图及效果

本例程源码下载:点击跳转 


http://chatgpt.dhexx.cn/article/j6fPmCmr.shtml

相关文章

SPI协议学习Cubmx——读写Flash W25Q64

这是最好的时代&#xff0c;这是最坏的时代&#xff1b; 这是智慧的时代&#xff0c;这是愚蠢的时代&#xff1b; 这是信仰的时期&#xff0c;这是怀疑的时期&#xff1b; 这是光明的季节&#xff0c;这是黑暗的季节&#xff1b; 这是希望之春&#xff0c;这是失望之冬&#xf…

STM32使用QUADSPI读写外部Nor Flash(以W25Q64为例)

使用QUADSPI读写W25Q64 QUADSPI介绍硬件连接双闪存模式禁止双闪存模式使能 QUADSPI命令序列指令阶段地址阶段交替字节阶段空指令周期阶段数据阶段 QUADSPI主要信号接口协议模式单线SPI模式双线SPI模式四线SPI模式 使用QUADSPI操作W25Q64发送命令函数状态轮询函数读ID函数QUADSP…

W25Q64内部结构

和STM32片上一样 我们分析 函数接口&#xff1a; 擦除1个扇区 【参数必须是4096的倍数】 void SPI_FLASH_SectorErase(uint32_t SectorAddr) 擦除芯片全部 void SPI_FLASH_BulkErase(void) 写入一页【数据比256小】 pBuffer&#xff1a;待写入数据的指针 WriteAddr&#xff…

基于STM32F401RET6字库烧录(SPIW25Q64驱动)

目录 一、SPI&W25Q64 1-SPI介绍 2-初始化SPI 3-SPI数据接收和发送函数 4-验证SPI是否配置正确&#xff08;读W25Q64的ID&#xff09; 二、W25Q64简介与API函数 1 - W25Q64芯片介绍 2- W25Q64芯片管脚说明 3- W25Q64芯片工作原理 4- W25Q64芯片操作时序 三、字库烧…

STM32CubeMx开发之路—13使用SPI读写W25Q64

!!! 本文已同步到码云 - 点击此链接获取最新 - 可进入码云提交修改 !!! 附件 源码已放到码云 ! ! ! ( 请点击文首链接进入仓库 ) 运行环境 Windows10STM32CubeMX Version 5.2.0Keil5(MDK5) Version 5.28.0.0 简介 本例程主要讲解如何使用硬件IIC读写24C02 STM32CubeMx基本配…

STM32CubeMX系列08——SPI通信(W25Q64、NRF24L01无线模块)

文章目录 1. 准备工作1.1. 所用硬件1.2. SPI 简介1.3. 生成工程1.3.1. 创建工程选择主控1.3.2. 系统配置1.3.3. 配置工程目录 2. 读写EEPROM实验&#xff08;W25Q64&#xff09;2.1. W25Q64 简介2.2. 代码实现 3. NRF24L01无线模块通信3.1. 模块简介3.2. SPI 配置3.2.1. SPI1 配…

STM32驱动W25Q64读写数据

STM32驱动W25Q64读写数据 一&#xff0e;基本参数二&#xff0e;通信协议1、时序&#xff1a;2、代码&#xff1a; 三&#xff0e;引脚定义与接线1、引脚定义2、对应接线 四&#xff0e;主要代码五&#xff0e;操作步骤与现象六&#xff0e;总结 一&#xff0e;基本参数 1.采用…

学习日记——W25Q64 FLASH—QSPI

W25Q64串行FLASH基础知识 大小&#xff1a;8M&#xff08;Byte&#xff09;&#xff08;128块&#xff08;Block&#xff09;&#xff0c;每块64K字节&#xff0c;每块16个扇区&#xff08;Sector&#xff09;&#xff0c;每个扇区4K字 节&#xff0c;每个扇区16页&#xff0c…

(STM32)W25Q64存储模块

1bit表示一个二进制位&#xff0c;1Byte表示8个二进制位。 每一个字节需要一个地址&#xff0c;所以24位地址&#xff0c;2^24次方最大寻址范围是16M。 W25Q256是特殊型号&#xff0c;切换4字节寻址模式才能使用后面的16M空间。 HOLD&#xff1a;芯片正常读写数据时&#xff…

SPIW25Q64(精华版)

1. SPI总线 1.1 W25Q64 1.1 W25Q64简介 W25Q64 是一种具有SPI接口的FlASH存储器&#xff0c;具有32768个可编程页(Page256B)&#xff0c;2048个可擦除扇区(Sector16*Page)&#xff0c;128个可擦除块(Block16*Sector)&#xff0c;容量为128*16*16*256B8MB(64bit)&#xff0c;…

W25Q64简介(译)

W25Q64是华邦公司推出的大容量SPI FLASH产品&#xff0c;其容量为64Mb。该25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件。W25Q64将8M字节的容量分为128个块&#xff0c;每个块大小为64K字节&#xff0c;每个块又分为16个扇区&#xff0c;每个扇区4K个字节。W25Q…

W25Q64Flash芯片

W25Q64Flash芯片STM32操作 通讯方式&#xff1a;SPI通讯 大小&#xff1a;64是bit 换算字节是8M&#xff08;Byte&#xff09;&#xff08;128块&#xff08;Block&#xff09;&#xff0c;每块16个扇区&#xff08;Sector&#xff09;&#xff0c;每个扇区4K字节&#xff08;…

SPI通讯介绍 以及读写W25Q64(块,扇区,页的区别)

附工程百度网盘链接 链接&#xff1a;https://pan.baidu.com/s/1nCgNb5OyGpABAL657-gX0A?pwd6666 提取码&#xff1a;6666 介绍:摩托罗拉开发的一种通用数据总线, 四根通讯线SCK(串行时钟总线),MOSI(主机输出从机输入),MISO(主机输入从机输出),SS(从机选择)而且是同步全双…

W25Q64调试

简介 W25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件。W25Q64将8M字节的容量分为128个块&#xff0c;每个块大小为64K字节&#xff0c;每个块又分为16个扇区&#xff0c;每个扇区4K个字节。 引脚介绍 串行数据输入、输出和 IOs&#xff08;DI、DO 和 IO0、IO1、…

软件SPI读写W25Q64硬件SPI读写W25Q64

目录 软件SPI读写W25Q64 MySPI W25Q64 主函数 硬件SPI读写W25Q64 软件SPI读写W25Q64 程序整体框架&#xff1a; SPI模块包含通信引脚封装&#xff0c;初始化&#xff0c;SPI三个基本时序单元&#xff08;起始&#xff0c;终止&#xff0c;交换一个字节&#xff09; W2…

W25Q64Flash芯片STM32操作

1、W25Q64Flash芯片介绍 通讯方式&#xff1a;SPI通讯 大小&#xff1a;8M&#xff08;Byte&#xff09; &#xff08;128块&#xff08;Block&#xff09;&#xff0c;每块64K字节&#xff0c;每块16个扇区&#xff08;Sector&#xff09;&#xff0c;每个扇区4K字节&…

STM32学习笔记(十一)丨SPI通信(W25Q64芯片简介,使用SPI读写W25Q64存储器芯片)

本篇文章包含的内容 一、SPI的通信协议及其原理1.1 SPI简介1.2 SPI通信的硬件连接1.3 SPI的时序基本单元1.3.1 起始条件和终止条件1.3.2 交换字节&#xff08;模式0&#xff0c;先移入&#xff0c;再移出&#xff09;1.3.3 交换字节&#xff08;模式1&#xff0c;先移出&#x…

看单片机原理图-外部FLASHW25Q64

系列文章目录 看单片机原理图-最小系统 看单片机原理图-最小系统电源电路 看单片机原理图-输入输出电路LED指示、按键输入 看单片机原理图-红外遥控、EEPROM 看单片机原理图-FLASH 文章目录 系列文章目录前言一、FLASH 前言 硬件&#xff1a;百问网100ASK_STM32F103_MINI开发…

W25Q64 Flash芯片原理与应用方案(含W25Q64中文数据手册)

W25Q64是华邦公司推出的大容量SPI FLASH产品&#xff0c;其容量为64Mb&#xff08;8MB&#xff09;&#xff0c;应用较为广泛。 W25Q系列的器件在灵活性和性能方面远远超过普通的串行闪存器件。W25Q64将8M字节的容量分为128个块&#xff0c;每个块大小为64K字节&#xff0c;每个…

cortex_m3_stm32嵌入式学习笔记(二十一):SPI实验(通信总线)

SPI 是英语 Serial Peripheral interface 的缩写&#xff0c;顾名思义就是串行外围设备接口。是 Motorola首先在其 MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM&#xff0c; FLASH&#xff0c;实时时钟&#xff0c; AD 转换器&#xff0c;还有数字信号处理器和数…