基于RTThread的学习(三):正点原子潘多拉 QSPI 通信 W25Q128 实验

本文详细介绍了如何在STM32L4开发板上配置QSPI,包括RTThread_setting设置、board.h和stm32l4_hal_conf.h的配置,以及W25Q128Flash的挂载、初始化和ID查看过程。重点讲解了弱回调函数和正确选择设备接口的方法。
摘要由CSDN通过智能技术生成

1、基于芯片创建工程

2、QSPI配置

2.1、RTThing_setting 设置组件

2.2、配置board.h 文件

2.3、cubemx生成QSPI的硬件初始化代码;HAL_QSPI_MapInit;

这里注意:你所买的开发板对应的qspi 连接的是否是cubemx 上边显示的,如果不是你需要将引脚复用为你的开发板上原理图的引脚;

比如:正点原子潘多拉 stm32l475vet6的原理图

我们就需要找到运力图的引脚将其复用;

将QSPI使能之后保存工程,并生成代码;

然后打开RTThread Studio 刷新工程后找到 cubx 目录下生成的代码,打开stm32l4xx_hal_map.c文件,将 HAL_QSPI_MapInit() 和HAL_QSPI_DeMapInit()这两个函数复制到 board.c 即可;

这两个函数是HAL 库中的弱回调函数,drv_qspi.c 函数会调用这两个函数;如果想了解具体的流程

可以了解一下hal 库的弱回调函数;

2.4、配置stm32l4_hal_conf.h

加入#define HAL_QSPI_MODULE_ENABLED,(这个在配置第一步后好像自动生成了宏定义,但是官方还是给了第四部的操作;)

2.5重新启动程序

这里cubemx 目录下会提示报错,右键将其排除构建即可;

3、W25Q128测试应用程序编写;

在application 下新建test_w25q128.c 文件;

3.1、挂载与初始化SPI设备;

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-04-07     29232       the first version
 */

#include  <rtthread.h>
#include  <rtdevice.h>
#include  <board.h>

#define QSPI_BUS_NAME    "qspi1"
#define QSPI_DEVICE_NAME  "qspi10"
#define W25Q_FLASH_NAME   "W25Q128FV"
#define QSPI_CS_PIN      GET_PIN(E,11)


static int rt_hw_qspi_flash_with_sfud_init(void)
{
    stm32_qspi_bus_attach_device(QSPI_BUS_NAME , QSPI_DEVICE_NAME, (uint32_t)GET_PIN(E,11), 4,RT_NULL, RT_NULL);

    /* init w25q128 */
    if (RT_NULL == rt_sfud_flash_probe(W25Q_FLASH_NAME, QSPI_DEVICE_NAME))
    {
        rt_kprintf("init_failed\n");
        return -RT_ERROR;
    }

    return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_qspi_flash_with_sfud_init);

启动代码 查看是否挂载 初始化成功;

3.3、查看ID

新建 sample_qspi.c

编写以下代码:

/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-08-15     misonyo      first implementation.
 */
/*
 * 程序清单:这是一个 QSPI 设备使用例程
 * 例程导出了 spi_w25q_sample 命令到控制终端
 * 命令调用格式:spi_w25q_sample spi10
 * 命令解释:命令第二个参数是要使用的SPI设备名称,为空则使用默认的SPI设备
 * 程序功能:通过SPI设备读取 w25q 的 ID 数据
*/

#include <rtthread.h>
#include <rtdevice.h>

#define W25Q_SPI_DEVICE_NAME     "qspi10"

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_qspi_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_qspi_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);

这里需要注意 如果你是使用的QSPI的主设备,函数要使用QSPI的接口读写函数,不能使用SPI的读写函数,否则回报 read data error;

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Easyflash库是一个基于Flash存储器的数据存储解决方案,支持多种Flash存储器,包括QSPI Flash,比如W25Q128。配置W25Q128 QSPI Flash需要以下步骤: 1. 确认W25Q128芯片的型号和引脚定义。 2. 配置QSPI控制器,包括时钟源、模式、数据线数等。 3. 初始化QSPI控制器和W25Q128 Flash。 4. 使用Easyflash库对Flash进行读写操作。 下面是一个简单的W25Q128 QSPI Flash配置代码示例: ```c #include "w25q128.h" /* 定义W25Q128引脚 */ #define W25Q128_CLK_PIN 1 #define W25Q128_CS_PIN 2 #define W25Q128_D0_PIN 3 #define W25Q128_D1_PIN 4 #define W25Q128_D2_PIN 5 #define W25Q128_D3_PIN 6 /* 初始化QSPI控制器 */ void qspi_init(void) { /* 配置时钟源、模式、数据线数等参数 */ } /* 初始化W25Q128 Flash */ void w25q128_init(void) { /* 配置W25Q128的模式、时钟速度等参数 */ } /* 读取Flash中的数据 */ void read_flash_data(void) { uint8_t buf[256]; /* 从地址0x1000处读取256字节数据 */ w25q128_read_data(0x1000, buf, 256); /* 处理读取到的数据 */ } /* 写入数据到Flash中 */ void write_flash_data(void) { uint8_t buf[256]; /* 将数据写入buf中 */ /* 写入256字节数据到地址0x1000处 */ w25q128_write_data(0x1000, buf, 256); } int main(void) { /* 初始化QSPI控制器和W25Q128 Flash */ qspi_init(); w25q128_init(); /* 读写Flash中的数据 */ read_flash_data(); write_flash_data(); return 0; } ``` 需要注意的是,具体的配置和使用方法可能会因为硬件平台和软件环境等因素而有所不同,以上代码仅供参考。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灰灰的996

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值