基于STM32F407实现w25q128 的SPI通讯
前言
W25Q128是比较常见的flash 芯片,由于之前的板子重新设计更换管脚后一直没有正常工作,所以重新进行了编码和调试,用于寻找原因(代码已实现flash读写,之前由于管脚配置模式不对导致不能读写)。
W25Q128 说明
这是W25Q128的手册介绍:
这是W25Q128的管脚定义,比较重要的是SPI通讯中需要使用的MISO,MOSI,NSS,CLK,分别对应芯片管脚中的DO,DI,CS,CLK;本文不使用RESET脚,置高保持HOLD状态;WP使用时需要置高;
原理图如下:
STM32F407上使用spi2总线:管脚对应如下:
SPI2 | PIN |
---|---|
MISO | PC2 |
MOSI | PC3 |
NSS | PB9 |
CLK | PB10 |
WP | PE4 |
代码设计
本文基于rt-thread的框架,采用Easyflash控制存储功能;
rt-thread spi API参考官方文档:
链接: rt-thread spi 设备.
链接: Easyflash 教程.
参考代码如下:
#include "drv_flash.h"
#include <easyflash.h>
#include "drv_spi.h"
// IO 初始化
void spi2_io_init(void)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB10 ------> SPI2_SCK
PC2 ------> SPI2_MISO
PC3 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = SPI2_SCK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI2_SCK_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI2_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(SPI2_MOSI_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SPI2_MISO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SPI2_MISO_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, GPIO_PIN_SET);
}
// STM32F407 与 W25Q128 建立通讯
rt_spi_flash_device_t w25q128;
int rt_hw_spi_flash_init(void)
{
//__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
//rt_hw_spi_device_attach("spi1", "flash", GPIOA, GPIO_PIN_4);
rt_hw_spi_device_attach("spi1", "flash", GPIOA, GPIO_PIN_4);
w25q128 = rt_sfud_flash_probe("W25Q128", "flash");
if (RT_NULL == w25q128)
{
return -RT_ERROR;
}
return RT_EOK;
}
// 读写测试
uint8 flash_test()
{
uint8 ip[4] = {192,168,1,1};
uint8 len = 0;
ef_set_env_blob("ip", ip, sizeof(ip));
rt_memset(ip,0,sizeof(ip));
len = ef_get_env_blob("ip", ip, sizeof(ip) , NULL);
return len;
}
//主函数
int main()
{
rt_hw_spi_flash_init();
easyflash_init();
flash_test();
while(1)
{
}
}
每ri
个人理解:~~