RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词:SFUD,FLASH,W25Q64,W25Q128,STM32F407

说明:RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动。

提示:SFUD添加后的存储位置

1.打开RT-Thread Setting SPI SFUD

打开 SFUD ,SPI

右键-详细配置

SFUD的配置 放置于如下头文件 rtconfig.h

2.开启board.h/stm32F1xx_hal_config.h中关于SPI的宏定义

STEP 1:第一步打开RT-Thread Setting SPI SFUD 中已经操作实现。

STEP 2:定义与spi总线相关的宏,例如#define BSP_USING_SPI1

STEP 4:修改您的stm32xxxx_hal_config.h文件以支持spi外围设备。 定义与外围设备相关的宏,例如#define HAL_SPI_MODULE_ENABLED

STEP 3:将由stm32cubemx生成的stm32xxxx_hal_msp.c的spi init函数复制到board.c文件的末尾,例如void HAL_SPI_MspInit(SPI_HandleTypeDef * hspi)

如下复制过程,将由stm32cubemx生成的 SPI 驱动部分代码全部复制到 board.c文件的末尾

3.stm32cubemx SPI 驱动生成过程

如何打开 stm32cubemx 建工程的过程就不讲解,直接讲关于SPI的配置过程

根据对应的STM32芯片打开一个工程配置SPI部分

时钟配置

 时钟树配置

SPI接口设置

输出项目设置

代码生成器 设置

生成代码

打开文件夹

SPI.C文件夹内便是生成的关于SPI接口的配置驱动代码

4.编译烧录后 发送命令 list_device 可以看到SPI总线 SPI1 已经注册到系统

5.SPI从设备驱动编写

SPI的总线设备已经注册完毕,接下来需要进行SPI从设备驱动编写,这里直接使用开发板板载的SPI Flash W25Q64进行测试,

新建 w25q_test.c

#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include "spi_flash_sfud.h"static int rt_hw_spi_flash_init(void)
{__HAL_RCC_GPIOB_CLK_ENABLE();rt_hw_spi_device_attach("spi1", "spi10", GPIOC, GPIO_PIN_0);// spi10 表示挂载在 spi3 总线上的 0 号设备,PC0是片选,这一步就可以将从设备挂在到总线中。if (RT_NULL == rt_sfud_flash_probe("W25Q64", "spi10"))  //注册块设备,这一步可以将外部flash抽象为系统的块设备{return -RT_ERROR;};return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);

        不支持 SFDP 标准的 Flash 已经在 Flash 参数信息表中定义,sfud_flash_def.h 文件有关于 flash 芯片的配置信息,配置中有的型号可以直接定义使用;配置中没有,且不支持SFDP的Flash 可以自己添加。

        注意:上述代码中的 "W25Q64" 与下截图的型号无关,进过测试,将"W25Q64" 改为"W25Q664" 编译烧录后,串口打印的数据任然一样,打印信息是 SFUD 自动探测读出的 Flash 的信息。具体原理不清楚。

编译后烧录,串口会显示 FLASH 的注册信息

SFUD打印了 基本Flash参数表信息

 \ | /
- RT -     Thread Operating System/ | \     4.0.2 build Jul  3 20202006 - 2019 Copyright by rt-thread team
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud.c:862) The flash device manufacturer ID is 0xEF, memory type ID is 0x40, capacity ID is 0x17.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:132) Check SFDP header is OK. The reversion is V1.5, NPN is 0.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:175) Check JEDEC basic flash parameter header is OK. The table id is 0, reversion is V1.5, length is 16, parameter table pointer is 0x000080.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:203) JEDEC basic flash parameter table info:
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:204) MSB-LSB  3    2    1    0
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0001] 0xFF 0xF9 0x20 0xE5
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0002] 0x03 0xFF 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0003] 0x6B 0x08 0xEB 0x44
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0004] 0xBB 0x42 0x3B 0x08
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0005] 0xFF 0xFF 0xFF 0xFE
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0006] 0x00 0x00 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0007] 0xEB 0x40 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0008] 0x52 0x0F 0x20 0x0C
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0009] 0x00 0x00 0xD8 0x10
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:215) 4 KB Erase is supported throughout the device. Command is 0x20.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:234) Write granularity is 64 bytes or larger.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:245) Target flash status register is non-volatile.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:271) 3-Byte only addressing.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:305) Capacity is 8388608 Bytes.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 4KB block erase. Command is 0x20.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 32KB block erase. Command is 0x52.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 64KB block erase. Command is 0xD8.
[SFUD] Find a Winbond flash chip. Size is 8388608 bytes.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud.c:840) Flash device reset success.
[SFUD] W25Q64 flash device is initialize success.
[SFUD] Probe SPI flash W25Q64 by SPI device spi10 success.
msh >

6.SFUD命令介绍

        通过串口发送 sf 命令,可以查到关于 SFUD 系统的命令,可以通过命令对Flash进行读写、擦除等操作。

msh >sf
Usage:
sf probe [spi_device]           - probe and init SPI flash by given 'spi_device'
sf read addr size               - read 'size' bytes starting at 'addr'
sf write addr data1 ... dataN   - write some bytes 'data' to flash starting at 'addr'
sf erase addr size              - erase 'size' bytes starting at 'addr'
sf status [<volatile> <status>] - read or write '1:volatile|0:non-volatile' 'status'
sf bench                        - full chip benchmark. DANGER: It will erase full chip!
sf probe [spi_device]           - 探测命令:使用如 sf probe spi10 ,就能探测到挂载的spi10设备
sf read addr size               - 读flash:使用如 sf read 00 100 ,表示从地址00开始读100个字节
sf write addr data1 ... dataN   - 写flash:使用如 sf write 17 01 02 03 04 05 06 07 08 09 10 11 ,表示从17地址开始写入后面这些数据
sf erase addr size              - 擦除命令:
sf status [<volatile> <status>] - 查询状态:查询状态寄存器的值- 全芯片基准测试。 危险:它将擦除整个芯片!

7.SFUD 测试程序

#include "user_cfg.h"/*
W25Q128介绍
W25Q128是华邦公司推出的大容量SPI FLASH产品,W25Q128的容量为128M bit,该系列还有W25Q80/16/32/64等。
W25Q128将16M的容量分为256个块(Block),每个块大小为64K字节,每个块又分为16个扇区(Sector),每个扇区4K个字节。
W25Q128的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。这样我们需要给W25Q128开辟一个至少4K的缓存区,这样对SRAM要求比较高,要求芯片必须有4K以上SRAM才能很好的操作。
W25Q128的擦写周期多达10W次,具有20年的数据保存期限,支持电压为2.7~3.6V,
W25Q128支持标准的SPI,还支持双输出/四输出的SPI,最大SPI时钟可以到80Mhz(双输出时相当于160Mhz,四输出时相当于320M),更多的W25Q128的介绍,请参考W25Q128的DATASHEET。*//* SPI Flash 驱动 */
static int rt_hw_spi_flash_init(void)
{//__HAL_RCC_GPIOB_CLK_ENABLE();/* 往总线 spi1 上挂载一个 spi10 从设备 */rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_4);/*spi10 表示挂载在 spi3 总线上的 0 号设备,PC0是片选,这一步就可以将从设备挂在到总线中。*//* 使用 SFUD 探测 spi10 从设备,并将 spi10 连接的 flash 初始化为块设备,名称 W25Q64DW */if (RT_NULL == rt_sfud_flash_probe("W25Q128JV", "spi10"))  /* 注册块设备,这一步可以将外部flash抽象为系统的块设备*/{return -RT_ERROR;};return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);void W25Q_Flash_test(void)
{sfud_err result;uint8_t *read_data;  // 读取到的数据uint8_t *write_data; // 将要写入的数据sfud_flash *sfud_dev = NULL;sfud_dev = rt_sfud_flash_find("spi10"); // 获取 sfud_dev// 或者 sfud_dev = rt_sfud_flash_find_by_dev_name("W25Q128");/*擦除 Flash 数据;flash: Flash 设备对象;addr:起始地址;size:从起始地址开始擦除数据的总大小*/sfud_erase(sfud_dev, 0, 1024);           // 擦除从 0 开始的 4096 字节write_data = rt_malloc(4096);              // 内存申请,函数会从系统堆空间中找到合适大小的内存块,然后把内存块可用地址返回给用户。rt_memset(write_data, 1, 4096);            // 作用是在一段内存块中填充某个给定的值,将  write_data 32 个地址填入1/*往 Flash 写数据:flash:Flash 设备对象;addr:起始地址;size:从起始地址开始写入数据的总大小;data:待写入的数据*/sfud_write(sfud_dev, 0, 4096, write_data); // 将数据 32 字节的 write_data 从 0 开始写入 flashread_data = rt_malloc(4096);rt_memset(read_data, 0, 4096);for (uint16_t var = 0; var < 4096; ++var){rt_kprintf("var = %d ,data = %d \n",var,read_data[var]) ;}/*读取 Flash 数据; flash: Flash 设备对象 ;addr: 起始地址;size:从起始地址开始读取数据的总大小;data:读取到的数据*/sfud_read(sfud_dev, 0, 4096, read_data);   // 读取从 0 开始的 32 字节,存入 read_datafor (uint16_t var = 0; var < 4096; ++var){rt_kprintf("var = %d ,data = %d \n",var,read_data[var]) ;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611437.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S的部署策略,重建更新和滚动更新

Deployment Strategies 部署战略 When it comes time to change the version of software implementing your service, a Kubernetes deployment supports two different rollout strategies: RecreateRollingUpdate 当需要更改实施服务的软件版本时&#xff0c;Kubernetes …

跟着我学Python进阶篇:02.面向对象(上)

往期文章 跟着我学Python基础篇&#xff1a;01.初露端倪 跟着我学Python基础篇&#xff1a;02.数字与字符串编程 跟着我学Python基础篇&#xff1a;03.选择结构 跟着我学Python基础篇&#xff1a;04.循环 跟着我学Python基础篇&#xff1a;05.函数 跟着我学Python基础篇&#…

Linux C/C++ 显示NIC流量统计信息

NIC流量统计信息是由操作系统维护的。当数据包通过NIC传输时&#xff0c;操作系统会更新相关的计数器。这些计数器记录了数据包的发送和接收数量、字节数等。通过读取这些计数器&#xff0c;我们可以获得关于网络流量的信息。 为什么需要这些信息? 可以使用这些信息来监控网络…

Java建筑工程建设智慧工地源码

智慧工地管理平台依托物联网、互联网&#xff0c;建立云端大数据管理平台&#xff0c;形成“端云大数据”的业务体系和新的管理模式&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材料等关键业务数据&#xff0c;打通从一线操作与远程监管的数据…

C++11_lambda表达式

文章目录 一、lambda表达式1.lambda的组成2.[capture-list] 的其他使用方法2.1混合捕捉 二、lambda表达式的使用场景1.替代仿函数 总结 一、lambda表达式 lambda表达式是C11新引入的功能&#xff0c;它的用法与我们之前学过的C语法有些不同。 1.lambda的组成 [capture-list] …

【C++进阶05】AVL树的介绍及模拟实现

一、AVL树的概念 二叉搜索树的缺点 二叉搜索树虽可以缩短查找效率 但如果数据有序或接近有序 二叉搜索树将退化为单支树 查找元素相当于在顺序表中搜索元素&#xff0c;效率低下 AVL树便是解决此问题 向二叉搜索树中插入新结点 并保证每个结点的左右子树 高度之差的绝对值不超…

Java诊断利器Arthas

https://arthas.aliyun.com/doc/https://arthas.aliyun.com/doc/ 原理 利用java.lang.instrument(容器类) 做动态 Instrumentation(执行容器) 是 JDK5 的新特性。使用 Instrumentation&#xff0c;开发者可以构建一个独立于应用程序的代理程序&#xff08;Agent&#xff09;&…

汽车IVI中控开发入门及进阶(十二):手机投屏

前言: 汽车座舱有车载中控大屏、仪表/HUD多屏的显示能力,有麦克风/喇叭等车载环境更好的音频输入输出能力,有方控按键、旋钮等方便的反向控制输入能力,还有高精度的车辆数据等。但汽车座舱中控主机硬件计算能力升级迭代周期相对较长,汽车的应用和服务不够丰富。现在很多汽…

.NetCore部署微服务(二)

目录 前言 概念 一 Consul注册服务中心 1.1 consul下载 1.2 consul运行 二 服务注册 2.1 安装Consul包 2.2 修改配置文件 2.3 注入Consul服务 2.3 修改Controller&#xff0c;增加HealthCheck方法 三 运行服务 3.1 docker运行服务 前言 上一篇讲到微服务要灵活伸缩…

「超级细菌」魔咒或将打破,MIT 利用深度学习发现新型抗生素

作者&#xff1a;加零 编辑&#xff1a;李宝珠、三羊 MIT 利用图神经网络 Chemprop 识别潜在抗生素&#xff0c;特异性杀死鲍曼不动杆菌。 自然界中充满了各种各样的微生物&#xff0c;例如结核杆菌&#xff08;导致肺结核&#xff09;、霍乱弧菌&#xff08;导致霍乱&#…

数据结构实验4:链表的基本操作

目录 一、实验目的 二、实验原理 1. 节点 2. 指针 3.链表的类型 3.1 单向链表 3.2 双向链表 3.3 单向循环链表 3.4 双向循环链表 4. 单链表的插入 4.1 头插法 4.2 尾插法 4.3 在指定位置插入元素 5. 单链表的删除 5.1 删除指定数值的节点 5.2 删除指定位置的节点 …

Pytorch从零开始实战16

Pytorch从零开始实战——ResNeXt-50算法的思考 本系列来源于365天深度学习训练营 原作者K同学 对于上次ResNeXt-50算法&#xff0c;我们同样有基于TensorFlow的实现。具体代码如下。 引入头文件 import numpy as np from tensorflow.keras.preprocessing.image import Ima…

TensorRt(5)动态尺寸输入的分割模型测试

文章目录 1、固定输入尺寸逻辑2、动态输入尺寸2.1、模型导出2.2、推理测试2.3、显存分配问题2.4、完整代码 这里主要说明使用TensorRT进行加载编译优化后的模型engine进行推理测试&#xff0c;与前面进行目标识别、目标分类的模型的网络输入是固定大小不同&#xff0c;导致输入…

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》 写在最前面私钥加密与伪随机性 第二部分流加密与CPA多重加密 CPA安全加密方案CPA安全实验、预言机访问&#xff08;oracle access&#xff09; 操作模式伪随机函数PR…

Java微服务系列之 ShardingSphere - ShardingSphere-JDBC

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项…

报错解决:No module named ‘pytorch_lightning‘ 安装pytorch_lightning

报错记录 执行如下代码&#xff1a; import pytorch_lightning报错&#xff1a; No module named ‘pytorch_lightning’ 解决方式 安装pytorch_lightning包即可。 一般情况下&#xff0c;缺失的包通过pip安装&#xff0c;即&#xff1a; pip install pytorch_lightning然…

1 快速前端开发

1 前端开发 目的&#xff1a;开发一个平台&#xff08;网站&#xff09;- 前端开发&#xff1a;HTML、CSS、JavaScript- Web框架&#xff1a;接收请求并处理- MySQL数据库&#xff1a;存储数据地方快速上手&#xff1a;基于Flask Web框架让你快速搭建一个网站出来。1.快速开发…

HarmonyOS应用开发学习笔记 应用上下文Context 获取文件夹路径

1、 HarmoryOS Ability页面的生命周期 2、 Component自定义组件 3、HarmonyOS 应用开发学习笔记 ets组件生命周期 4、HarmonyOS 应用开发学习笔记 ets组件样式定义 Styles装饰器&#xff1a;定义组件重用样式 Extend装饰器&#xff1a;定义扩展组件样式 5、HarmonyOS 应用开发…

14-股票K线图功能-个股日K线SQL分析__ev

需求&#xff1a;统计个股日K线数据&#xff0c;也就是把某只股票每天的最高价&#xff0c;开盘价&#xff0c;收盘价&#xff0c;最低价形成K线图。

山西电力市场日前价格预测【2024-01-11】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-01-11&#xff09;山西电力市场全天平均日前电价为231.43元/MWh。其中&#xff0c;最高日前电价为422.21元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…