STM32F103通过硬件SPI驱动W25Q64,并把读取到的地址打印在屏上。
一、硬件基础与接口匹配 STM32F103 SPI外设特性 接口数量:3个SPI接口SPI1/SPI2/SPI3,支持主从模式。 时钟配置:SPI1挂载于APB2总线最高72MHz,SPI2/SPI3挂载于APB1总线最高36MHz,通过分频可实现最高18MHz的SPI时钟输出。 数据格式:支持8/16位数据帧,可配置MSB/LSB优先传输,兼容W25Q64的SPI模式0,CPOL=0, CPHA=0或模式3,CPOL=1, CPHA=1。 W25Q64 SPI接口特性 存储结构:8MB容量,分为128个块64KB/块、2048个扇区4KB/扇区。 SPI协议支持:标准SPI模式0/3,最大时钟频率80MHz实际需根据主机能力调整。 关键指令:写使能0x06、页编程0x02、扇区擦除0x20、读状态寄存器0x05等。
二、硬件连接与配置 引脚连接 STM32F103: SPI1_SCK → PA5(SPI1时钟) SPI1_MISO → PA6(主机输入/从机输出) SPI1_MOSI → PA7(主机输出/从机输入) W25Q64_CS → PA1(片选,软件控制)
W25Q64:
SCK → STM32 SPI1_SCK
MISO → STM32 SPI1_MISO
MOSI → STM32 SPI1_MOSI
CS → STM32 GPIO(低电平有效)

SPI初始化配置 时钟分频:根据W25Q64最大支持频率(如18MHz),配置SPI时钟分频系数(如APB2 72MHz / 4 = 18MHz)。 数据格式:8位数据帧,MSB优先传输。 SPI模式:模式0(CPOL=0, CPHA=0)或模式3(需与W25Q64匹配)。 NSS信号:软件控制片选(GPIO模拟),避免硬件NSS自动管理冲突。
原理图

框图

三、配置
四、代码 主函数
{
/* USER CODE BEGIN 1 */
HAL_StatusTypeDef error;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM6_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
OLED_INIT();
HAL_Delay(2000);
OLED_Clear();
W25QXX_Init();
Test_SPI_Funtion();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
把地址显示在屏上
void W25QXX_Init(void)
{
uint8_t temp;
char flashInfo[32]; // 存储FLASH信息的字符串缓冲区
__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟
W25QXX_E = W25QXX_ReadID(); // 读取FLASH ID
// 初始化OLED屏幕(假设已实现OLED_Init())
OLED_Init(); // 初始化OLED
OLED_Clear(); // 清屏
// 显示固定信息(标题、作者、日期等)
OLED_ShowString(25, 0, "RY MCU", 16, 0);
sprintf(flashInfo, "FLASH ID:0x%04X", W25QXX_E);
OLED_ShowString(0, 4, flashInfo, 16, 0); // 在第6行显示
}
uint8_t W25QXX_ReadSR(uint8_t regno)
{
uint8_t byte=0,command=0;
switch(regno)
{
case 1:
command=W25X_ReadStatusReg1; //读状态寄存器1指令
break;
case 2:
command=W25X_ReadStatusReg2; //读状态寄存器2指令
break;
case 3:
command=W25X_ReadStatusReg3; //读状态寄存器3指令
break;
default:
command=W25X_ReadStatusReg1;
break;
}
FLASH_CS_LOW() ; //使能器件
SPI1_ReadWriteByte(command); //发送读取状态寄存器命令
byte=SPI1_ReadWriteByte(0Xff); //读取一个字节
FLASH_CS_HIGH();; //取消片选
return byte;
}
//W25QXX写使能
//将WEL置位
void W25QXX_Write_Enable(void)
{
FLASH_CS_LOW() ; //使能器件
SPI1_ReadWriteByte(W25X_WriteEnable); //发送写使能
FLASH_CS_HIGH();; //取消片选
}
//W25QXX写禁止
//将WEL清零
void W25QXX_Write_Disable(void)
{
FLASH_CS_LOW() ; //使能器件
SPI1_ReadWriteByte(W25X_WriteDisable); //发送写禁止指令
FLASH_CS_HIGH();; //取消片选
}
五、实现显示效果
OLED显示
调试显示
