RT-Thread studio SPI+SFUD+W25Q64
·
一、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);

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

所有评论(0)