本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外设与 SPI Flash 通信(W25Q64)。
1. 准备工作
硬件准备
- 开发板
首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi):
- SPI Flash
小熊派开发板板载一片SPI Flash,型号为W25Q64
,大小为 8 MB,最大支持 80 Mhz的操作频率。
软件准备
- 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码;
Keil MDK和串口助手的安装包都可以关注“小熊派开源社区”微信公众号,在资料教程一栏中可获取安装包。
2.生成MDK工程
选择芯片型号
打开STM32CubeMX,打开MCU选择器:
搜索并选中芯片STM32L431RCT6
:
配置时钟源
- 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;
- 如果使用默认内部时钟(HSI),这一步可以略过;
这里我都使用外部时钟:
配置串口
小熊派开发板板载ST-Link并且虚拟了一个串口,原理图如下:
这里我将开关拨到AT-MCU
模式,使PC的串口与USART1之间连接。
接下来开始配置USART1
:
配置QSPI接口
首先查看小熊派开发板上 SPI Flash 的原理图:
其引脚连接情况如下:
SPI Flash连接引脚 | 对应引脚 |
---|---|
QUADSPI_BK1_NCS | PB11 |
QUADSPI_BK1_CLK | PB10 |
QUADSPI_BK1_IO0 | PB1 |
QUADSPI_BK1_IO1 | PB0 |
接下来配置 QSPI 接口:
配置时钟树
STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz
即可:
生成工程设置
代码生成设置
最后设置生成独立的初始化文件:
生成代码
点击GENERATE CODE
即可生成MDK-V5工程:
3. 在MDK中编写、编译、下载用户代码
重定向printf( )函数
4. 封装 SPI Flash(W25Q64)的命令和底层函数
MCU 通过向 SPI Flash 发送各种命令 来读写 SPI Flash内部的寄存器,所以这种裸机驱动,首先要先宏定义出需要使用的命令,然后利用 HAL 库提供的库函数,封装出三个底层函数,便于移植:
- 向 SPI Flash 发送命令的函数
- 向 SPI Flash 发送数据的函数
- 从 SPI Flash 接收数据的函数
接下来开始编写代码~
宏定义操作命令
#define ManufactDeviceID_CMD 0x90
#define READ_STATU_REGISTER_1 0x05
#define READ_STATU_REGISTER_2 0x35
#define READ_DATA_CMD 0x03
#define WRITE_ENABLE_CMD 0x06
#define WRITE_DISABLE_CMD 0x04
#define SECTOR_ERASE_CMD 0x20
#define CHIP_ERASE_CMD 0xc7
#define PAGE_PROGRAM_CMD 0x02
封装发送命令的函数(重点)
/**
* @brief 向SPI Flash发送指令
* @param instruction —— 要发送的指令
* @param address —— 要发送的地址
* @param dummyCycles —— 空指令周期数
* @param instructionMode —— 指令发送模式
* @param addressMode —— 地址发送模式
* @param addressSize —— 地址大小
* @param dataMode —— 数据发送模式
* @retval 成功返回HAL_OK
*/
HAL_StatusTypeDef QSPI_Send_Command(uint32_t instruction,
uint32_t address,
uint32_t dummyCycles,
uint32_t instructionMode,
uint32_t addressMode,
uint32_t addressSize,
uint32_t dataMode)
{
QSPI_CommandTypeDef cmd;
cmd.Instruction = instruction; //指令
cmd.Address = address; //地址
cmd.DummyCycles = dummyCycles;