一、RT-Thread-W25Q64-SPI配置

(一)SPI配置

1、创建工程后,打开设置,使能SPI
在这里插入图片描述
2、修改board.h头文件内容

在这里插入图片描述
3、打开stm32cube-使能对应SPI通道引脚(根据所使用的SPI通道进行设置)
W25Q64使用SPI2,相关设置如下所示:
在这里插入图片描述
4、生成代码,关闭stm32cubemx
修改stm32f4xx_hal_config_bak.h文件如框选所示,使能 SPI 外设模块的宏定义
在这里插入图片描述
5、将生成的SPI初始化函数复制到board.c文件末尾,原来文件中函数的内容注释掉
在这里插入图片描述
将复制的SPI初始化函数粘贴到board.c文件中末尾,如下图所示

在这里插入图片描述
随后将原来文件中的初始化函数注释掉
在这里插入图片描述

(二)读取W25Q64

SPI片选W25Q64芯片,挂载设备

struct rt_spi_device *spi_w25q64;
//片选SPI和挂载W25Q64
void spi_init()
{
    struct rt_spi_configuration cfg;
    //先把w25qxx挂载在SPI2总线上(pb12是W25Q的片选引脚)
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);
    //查找设备
    spi_w25q64=(struct rt_spi_device *)rt_device_find("spi20");
    if(spi_w25q64==RT_NULL){
        rt_kprintf("spi_w25q find failed...\n");
    } else {
        rt_kprintf("spi_w25q find success...\n");
    }
    //配置w25q-spi模式
    cfg.data_width=8;
    cfg.mode=RT_SPI_MODE_3|RT_SPI_MASTER|RT_SPI_MSB;//模式3,主机,高位先行
    cfg.max_hz=5*1000*1000;//5M
    rt_spi_configure(spi_w25q64, &cfg);
    //此时可以查看设备是否已注册
}
MSH_CMD_EXPORT(spi_init,spi bus);

读取设备ID指令:0x90
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

方法一:

//读取id方法1
void spi_read_id1()
{
    rt_uint8_t id[5]={0};//
    struct rt_spi_message msg1,msg2;
    rt_uint8_t w25_read_id=0x90;//读取ID指令
    msg1.send_buf=&w25_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;
    //制造商0XEF 设备IDxx
    rt_spi_transfer_message(spi_w25q64, &msg1);
    rt_kprintf("w25q128 ID is %x%x \n",id[3],id[4]);
}
MSH_CMD_EXPORT(spi_read_id1,spi_read_id);

方法二:

//读取id方法2
//先发送后接收数据函数
//rt_spi_send_then_recv(device, send_buf, send_length, recv_buf, recv_length)
void spi_read_id2()
{
    rt_uint8_t id[5]={0}; //存储id
    rt_uint8_t w25_read_id=0x90;//读取ID指令

    rt_spi_send_then_recv(spi_w25q64, &w25_read_id, 1, id, 5);
    rt_kprintf("w25q128 ID is %x%x \n",id[3],id[4]);

}
MSH_CMD_EXPORT(spi_read_id2,spi_read_id);

完整代码如下所示

#include"rtthread.h"
#include"rtdevice.h"
#include"drv_spi.h"
#include"drivers/spi.h"

struct rt_spi_device *spi_w25q64;
//片选SPI和挂载W25Q64
void spi_init()
{
    struct rt_spi_configuration cfg;
    //先把w25qxx挂载在SPI2总线上(pb12是W25Q的片选引脚)
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);
    //查找设备
    spi_w25q64=(struct rt_spi_device *)rt_device_find("spi20");
    if(spi_w25q64==RT_NULL){
        rt_kprintf("spi_w25q find failed...\n");
    } else {
        rt_kprintf("spi_w25q find success...\n");
    }
    //配置w25q-spi模式
    cfg.data_width=8;
    cfg.mode=RT_SPI_MODE_3|RT_SPI_MASTER|RT_SPI_MSB;//模式3,主机,高位先行
    cfg.max_hz=5*1000*1000;//5M
    rt_spi_configure(spi_w25q64, &cfg);
    //此时可以查看设备是否已注册
}
MSH_CMD_EXPORT(spi_init,spi bus);


//读取id方法1
void spi_read_id1()
{
    rt_uint8_t id[5]={0};//
    struct rt_spi_message msg1,msg2;
    rt_uint8_t w25_read_id=0x90;//读取ID指令
    msg1.send_buf=&w25_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;
    //制造商0XEF 设备IDxx
    rt_spi_transfer_message(spi_w25q64, &msg1);
    rt_kprintf("w25q128 ID is %x%x \n",id[3],id[4]);
}
MSH_CMD_EXPORT(spi_read_id1,spi_read_id);



//读取id方法2
//先发送后接收数据函数
//rt_spi_send_then_recv(device, send_buf, send_length, recv_buf, recv_length)
void spi_read_id2()
{
    rt_uint8_t id[5]={0}; //存储id
    rt_uint8_t w25_read_id=0x90;//读取ID指令

    rt_spi_send_then_recv(spi_w25q64, &w25_read_id, 1, id, 5);
    rt_kprintf("w25q128 ID is %x%x \n",id[3],id[4]);

}
MSH_CMD_EXPORT(spi_read_id2,spi_read_id);

编译运行结果
在这里插入图片描述

二、W25Q64+SFUD

(一)增加SFUD配置

在第一章节(一)SPI配置基础上增加
在这里插入图片描述
在这里插入图片描述

(二)编写代码

在这里插入图片描述

SPI片选,SFUD探测初始化

int w25q_sfud_test()
{
    //片选挂载设备
//    rt_hw_spi_device_attach(bus_name, device_name, cs_gpiox, cs_gpio_pin)
    rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);

    //探测设备
   // rt_sfud_flash_probe(spi_flash_dev_name, spi_dev_name)
    //使用sfud探测spi20设备,并将spi20连接的flash初始化为块设备,名称w25q128
    if(rt_sfud_flash_probe("W25Q64", "spi20")==RT_NULL)
    {
        rt_kprintf("w25q64 prob failed...\n");
        return -RT_ERROR;
    }
return RT_EOK;
}

MSH_CMD_EXPORT(w25q_sfud_test,sfub test);

在这里插入图片描述

写入数据和读取数据测试

sfud_flash_t test_sfud;
int w25q_read_write_test()
{
    const uint8_t test_data[]="this is w25q sfud test data!";
    uint8_t read_data[50]={0};

    //获取设备句柄
    /*
         * 使用 rt_sfud_flash_find 或者 rt_sfud_flash_find_by_dev_name 获取设备句柄:
     */
    //test_sfud=rt_sfud_flash_find("spi20");
    test_sfud=rt_sfud_flash_find_by_dev_name("W25Q64");
    if(test_sfud==RT_NULL)
    {
        rt_kprintf("find sufd_flash failed...\n");
        return -RT_ERROR;
    }
    else {
        rt_kprintf("find sufd_flash success...\n");
    }

    //调用API进行读写操作
    //写flash
    rt_kprintf("write flash...\n");
//    sfud_write(flash, addr, size, data)
//    sfud_erase_write(flash, addr, size, data)
//    sfud_write(test_sfud, 13, sizeof(test_data), test_data);
    sfud_erase_write(test_sfud, 13, sizeof(test_data), test_data);

    //读flash
    rt_kprintf("read flash...\n");
    sfud_read(test_sfud, 13, sizeof(test_data), read_data);
    rt_kprintf("read data:%s...\n",read_data);
}

MSH_CMD_EXPORT(w25q_read_write_test,sfub read write test);

在这里插入图片描述

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐