RT-thread SPI SFUD读写W25Q128

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

MCU:STM32F091CC
IDE:RT-Thread Studio 2.2.1
IO对应关系(SPI2):

功能IO
MISOPB14
MOSIPB15
SCKPB13
CSPB12

参考资料:
1.RTT官方SPI文档
2.在潘多拉上使用 SFUD 操作 Flash


一、SFUD 是什么?

SFUD (Serial Flash Universal Driver) 是一款开源的串行 SPI Flash 通用驱动库。

二、使用步骤

1.添加SPI2总线

  • 打开SPI及SFUD的驱动框架
    在这里插入图片描述
  • 在Board.h中定义SPI使用
    在这里插入图片描述
  • 在stm32f0xx_hal_conf.h中打开 HAL 库对 SPI 的支持
    在这里插入图片描述
  • 初始化IO及时钟
    使用CubeMX生成HAL_SPI_MspInit(),并将其复制到board.c中。
    备注:NSS使用软件控制。
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hspi->Instance==SPI2)
  {
  /* USER CODE BEGIN SPI2_MspInit 0 */

  /* USER CODE END SPI2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SPI2_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**SPI2 GPIO Configuration
    PB13     ------> SPI2_SCK
    PB14     ------> SPI2_MISO
    PB15     ------> SPI2_MOSI
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI2_MspInit 1 */

  /* USER CODE END SPI2_MspInit 1 */
  }
}
  • 下载运行
  • 可以看到SPI2添加成功了。
    在这里插入图片描述

2.W25Q128读写操作

  • 挂载 SPI FLASH W25Q128 到 SPI 总线:
static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);

    if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi20"))
    {
        return -RT_ERROR;
    };

    return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
  • 读取 SPI FLASH W25Q128的ID :
#define W25Q_SPI_DEVICE_NAME     "spi20"

static void spi_w25q_sample(int argc, char *argv[])
{
    struct rt_spi_device *spi_dev_w25q;
    char name[RT_NAME_MAX];
    rt_uint8_t w25x_read_id = 0x90;
    rt_uint8_t id[5] = {0};

    if (argc == 2)
    {
        rt_strncpy(name, argv[1], RT_NAME_MAX);
    }
    else
    {
        rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
    }

    /* 查找 spi 设备获取设备句柄 */
    spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
    if (!spi_dev_w25q)
    {
        rt_kprintf("spi sample run failed! can't find %s device!\n", name);
    }
    else
    {
        /* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
        rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
        rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);

        /* 方式2:使用 rt_spi_transfer_message()发送命令读取ID */
        struct rt_spi_message msg1, msg2;

        msg1.send_buf   = &w25x_read_id;
        msg1.recv_buf   = RT_NULL;
        msg1.length     = 1;
        msg1.cs_take    = 1;
        msg1.cs_release = 0;
        msg1.next       = &msg2;

        msg2.send_buf   = RT_NULL;
        msg2.recv_buf   = id;
        msg2.length     = 5;
        msg2.cs_take    = 0;
        msg2.cs_release = 1;
        msg2.next       = RT_NULL;

        rt_spi_transfer_message(spi_dev_w25q, &msg1);
        rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);

    }
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample);

读取成功如图
在这里插入图片描述

  • 使用SFUD写/读 W25Q128 :
#include "spi_flash.h"
#include "./sfud/inc/sfud.h"

static void spi_w25q_sf_sample(int argc, char *argv[])
{
    uint8_t *read_data;  // 读取到的数据
    uint8_t *write_data; // 将要写入的数据
    sfud_flash *sfud_dev = NULL;
    sfud_err ret;
    sfud_dev = rt_sfud_flash_find("spi20"); // 获取 sfud_dev
    // 或者 sfud_dev = rt_sfud_flash_find_by_dev_name("W25Q128");

    write_data = rt_malloc(32);
    rt_memset(write_data, '1', 32);
    ret = sfud_erase_write(sfud_dev, 0, 32, write_data); // 将数据 32 字节的 write_data 从 0 开始写入 flash
    if(ret == SFUD_SUCCESS)
    {
        rt_kprintf("sfud write data at 0 is:%s\n", write_data);
    }
    else
    {
        rt_kprintf("sfud write data failed\n");
    }
    read_data = rt_malloc(32);
    ret = sfud_read(sfud_dev, 0, 32, read_data);   // 读取从 0 开始的 32 字节,存入 read_data
    if(ret == SFUD_SUCCESS)
    {
        rt_kprintf("sfud read data at 0 is:%s\n", read_data);
    }
    else
    {
        rt_kprintf("sfud read data failed\n");
    }

}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(spi_w25q_sf_sample, spi w25q sf sample);

在这里插入图片描述


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值