当前位置: 首页 > news >正文

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMX+Keil,  创建一个SD卡读写的工程。

目录

一、SD卡要点速读

二、SDIO要点速读

三、SD卡座接线原理图

四、CubeMX新建工程

五、CubeMX 生成 SD卡的SDIO通信部分

六、Keil 编辑工程代码

七、实验效果

实现效果,如下图:


一、SD卡 速读

SD卡,全称Secure Digital Memory Card(安全数码卡),是嵌入式设备上常用的一种存储介质。

1、尺寸大小 分类

按卡的大小分类,可以为3种:

  • 标准SD卡 :体积较大,卡侧带写保护开关;常见于相机和摄像机中,用于存储高分辨率照片和视频;
  • mini SD卡 :现在较少看到,已逐渐被microSD卡取代;
  • Micro SD卡:旧称 TF卡,2004年更名为 Micro SD Card, 常用于扩展手机和平板电脑的存储空间。

每种卡形状大小不一,但功能一样:遵循相同的 SD卡协议、相同的命令集、相同的块大小(512)。只需确保SDIO引脚配置正确,并且遵循SD卡协议发送正确的命令,程序即可通用。

都是SD卡,但习惯上,标准SD叫SD卡,Micro SD叫TF卡。

目前,STM32开发板、Linux开发板 等,预留的卡座,一般是TF卡座,因为它占用空间最少。

2、卡的容量及标准 分类

在SD卡的表面丝印上,会有HC、XC等字样,表示它所使用的存储标准。

  • SD: 早期的版本,基本停用,最高 2GB, 分区格式为 FAT12(FAT)、FAT16。
  • SDHC:容量范围 2GB ~ 32GB, 分区格式为 FAT32。
  • SDXC:容量范围 32GB ~ 2TB, 分区格式为 exFAT。
  • SDUC:容量范围 2TB ~ 128TB, 分区格式为 exFAT。

3、SD卡的传输速度

SD卡的可变时钟频率:0~25MHz。当运行在25M+数据带宽4位时,最大理论传输速度是12.5MB/s。

而操作中,会明显低于理论速度,其受限于不同品牌的芯片优化、制造工芯、采用标准等。

SD卡是Flash存储,读写速度特点是:读快、写慢。

SD卡的最低写入速度,用Class等级来标识。

在表面丝印上,一般会有Class字样,它后面的数表示最低写入速度,单位是:MB/s。

或者,会用一个外面带半圆的数字表示。

  • Class 2:2MB/s
  • Class 4:4MB/s
  • Class 6:6MB/s
  • Class 10:10MB/s

附:常用的SD卡读写速率参考,非严谨值。

SD卡容量文件系统写入速度读取速度
32G(SDHC)FAT322MB/s8MB/s
32G(SDHC)exFAT3.5MB/s8.5MB/s
64G(SDXC)exFAT4MB/s8.5MB/s

4、SD卡的使用寿命

一般是指:擦除的最大次数。

写入数据时需要先擦除扇区内容。读数据是不影响使用寿命的,写数据才会影响使用寿命。

因此,应避免频繁地对同一地址(扇区)进行写数据。如:使用程序每隔一秒保存一次数据到同一地址,这是不妥当的。

  • TLC:1000~3000次
  • MLC:3000 ~1万次
  • SLC:可达10万次

擦写次数对使用寿命影响较小,而更容易直接“致死”的是:带电插拔,很容易坏卡,主要是静电原因!


二、SDIO要点速读

原理比较复杂,有兴趣的请自行csdn搜更详细的技术文档,或STM32的官方文档。

  • SD卡的读写通信操作,可以用 SPI、SDIO,本示例使用SDIO。
  • SDIO接口是在SD内存卡接口的基础上发展起来的;
  • SDIO接口除了能读写SD内存卡,还能连接其它SDIO接口的设备;
  • 常用的STM32F103C8,没有SDIO接口,F103系列R型号起,才带SDIO;
  • STM32F4系列芯片,带更完善的SDIO主机接口,能与MMC卡、SD卡、SDI/0卡、EC-ATA设备进行通信;
  • 三种总线模式:1-bit、4-bit、8-bit(不常用);


三、SD卡座接线原理图

STM32的SDIO外设与SD卡通信,通用接线如下图。

注:当使用弹簧式SD卡座,会有第9个脚(CD), 可不接。它用于判断SD卡是否插入,当插入SD卡时,此脚输出低电平。


四、CubeMX新建工程

建议复制一个已带UART1、printf的工程,这样更省时。

如果没有,可参考以下步骤。

1、新建一个普通的工程

新手可参考如下图解,老司机请直接跳过。

【STM32+CubeMX】 新建工程_STM32F407

2、为工程添加UART1通信、printf输出

用于把SD卡的测试信息,(通过USB转TTl),输出到串口助手观察。

如果,你已知晓如何通过printf输出信息,自行添加,跳过即可。

USART1 DMA发送、DMA空闲中断 接收不定长数据

UART1 快速实现移植、通信 ( bsp_UART.c 、bsp_UART.h)


五、CubeMX 配置 SD卡的SDIO 初始化

通过 CubeMX配置SDIO, 极度简单。

本节为方便测试,只使用普通的读写方式,后续篇章再添加DMA、FATFS等方式。

1、使能SDIO

  • Mode:选择SD的四线模式,即 SD 4 bits Wide bus.
  • 参数部分:F4系列不用修改配置,默认即可。F103系列,需把时钟分频系数修改为 6,即SDIOCLK Clock divide factor这一项,由默认0改为6, 不然会通信失败。

2、时钟设置

进入时钟树配置页面。

这时可能会弹出一个询问窗:是否自动配置所需时钟?

选择:NO ,手动修改即可。

如果Yes,它将针对已使能的SDIO进行必须值的配置,而系统时钟值,会被修改为其它值。不推荐。

F4系列,如果板上是25M的晶振,用如下参数值;要是8M的晶振,修改晶振、分频两处为8即可。

重点:箭头所指的Q值,它用于控制USB 、SDIO和随机数生成器的时钟。

这个时钟,必须是 48M ! 

好了,已完成配置。

重新生成工程,即可!


六、Keil 编辑工程代码

1、打开keil 工程,先重新编译一次。

  • 正常情况,编译是0 Error的。
  • 如果有Error,  应该是新建工程时,路径、名称有中文了,重新开建工程,用英文即可。

2、重要修改:SD卡的初始化,使用 1-bit 模式

CubeMX生成的SDIO初始化代码,有一个bug,需要手动修改,操作如下: 

  • 编译后,右击 main.c 文件中函数 MX_SDIO_SD_Init(), 
  • 在弹出菜单中:Go To Definition Of ...;  将跳转到SD卡初始化函数;

跳转到 sdio.c文件的 MX_SDIO_SD_Init()函数内部后,

把下图位置中的 4B,改为 1B ;

它下面还有一个4B,不用修改,只修改刚才那个即可。不要改错位置了!

重点:每次重新生成后,都要手动修改一次。如果不修改,初始化过程会导致程序卡死。

3、编写 读写测试 代码

SD卡的基础读写函数比较简单,常用的函数共4个。

1、获取SD卡信息
HAL_SD_CardInfoTypeDef pCardInfo = {0};          // SD卡信息结构体
HAL_SD_GetCardInfo(&hsd, &pCardInfo);            // 获取 SD 卡的信息2、读数据
HAL_SD_ReadBlocks(&hsd, aOldData, 7, 2, 3000);   //  SD卡的句柄、数据、块地址、块数量、超时ms3、写数据
HAL_SD_WriteBlocks(&hsd, aTestData, 7, 2, 3000)  //  SD卡的句柄、数据、块地址、块数量、超时ms4、擦除数据
HAL_SD_Erase(&hsd, 7, 8)  //  SD卡的句柄、块起始地址、块结束地址

在 main函数内的 /* USER CODE BEGIN 2 */ 注释下方,编写以下代码(可复制):

示例代码里已附详细注释,比较容易理解,流程是:

  • 获取SD卡信息
  • 读取测试块的原数据 
  • 写入测试
  • 擦除测试
  • 写回原数据
    /***************** SD卡读写通信测试 *****************//* 1、获取卡信息,打印到串口助手                    *//* 2、读测试:读出测试位置原数据,保存在 aOldData[] *//* 3、写测试:在测试的块上,写入指定数据            *//*    读出刚才写入的块数据,打印到串口助手观察      *//* 4、擦除测试:擦除指定块上的数据                  *//*    读出刚才擦除块的数据,打印到串口助手观察      *//* 5、写回原数据到指定位置                          *//*    读出刚才写入的块数据,打印到串口助手观察      */    #define SD_TEST_SIZE    1024                                       // 测试数据的字节数,刚好是2个块大小:2x512static uint8_t aOldData[SD_TEST_SIZE] = {0};                       // 用于存放旧数据,先读出来,测试完了,再把旧数据写回去static uint8_t aTestData[SD_TEST_SIZE] = {0};                      // 临时缓存,用来存放测试数据HAL_SD_CardInfoTypeDef pCardInfo = {0};                            // SD卡信息结构体uint8_t status = HAL_SD_GetCardState(&hsd);                        // SD卡状态标志值if (status == HAL_SD_CARD_TRANSFER){/* 1、获取卡信息,打印到串口助手 */HAL_SD_GetCardInfo(&hsd, &pCardInfo);                          // 获取 SD 卡的信息printf("\r1、获取SD卡信息 ... \r\n");printf("卡类型:%d \r\n", pCardInfo.CardType);                 // 类型返回:0-SDSC、1-SDHC/SDXC、3-SECUREDprintf("卡版本:%d \r\n", pCardInfo.CardVersion);              // 版本返回:0-CARD_V1、1-CARD_V2printf("块数量:%d \r\n", pCardInfo.BlockNbr);                 // 可用的块数量printf("块大小:%d \r\n", pCardInfo.BlockSize);                // 每个块的大小; 单位:字节printf("卡容量:%lluG \r\n", ((unsigned long long)pCardInfo.BlockSize * pCardInfo.BlockNbr) / 1024 / 1024 / 1024);  // 计算卡的容量HAL_Delay(1000);                                               // 重要:稍作延时再开始读写测试; 避免有些仿真器烧录期间的多次复位,短暂运行了程序,导致下列读写数据不完整。      /* 2、读测试:读出测试位置原数据,保存在 aOldData[] */printf("\r2、读取测试块的原数据 ... \r\n");memset(aOldData, 0, SD_TEST_SIZE);                             // 清0数组的数据if (HAL_SD_ReadBlocks(&hsd, aOldData, 7, 2, 3000) == HAL_OK)   // 读SD卡数据块; 参数:SD结构体、数据地址、块起始地址、读的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束for (uint32_t i = 0; i < SD_TEST_SIZE; i++)                // 打印 原数据printf("%X ",  aOldData[i]);printf("\r\n");}else{printf("SD卡 读测试 失败!\n");            }/* 3-1、写测试:在测试的块上写入数据 */printf("\r3、SD卡 写入测试 ...\r\n");memset(aTestData, 0x8, SD_TEST_SIZE);                          // 为数组准备要写入的测试数据:整个数组填充指定值if (HAL_SD_WriteBlocks(&hsd, aTestData, 7, 2, 3000) == HAL_OK) // 向SD卡写入数据块; 参数:SD结构体、数据地址、块起始地址、写入的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束printf("对指定块写入结束! \r写入的数据是:\n");for (uint32_t i = 0; i < SD_TEST_SIZE; i++)                // 打印 写入的数据printf("%X ",  aTestData[i]);printf("\r\n");}else{printf("SD卡 写测试 失败!\n");}/* 3-2、读出刚才写测试的块内数据 */printf("\r现在块内的数据是:\r\n");memset(aTestData, 0, SD_TEST_SIZE);                            // 清0数组的数据if (HAL_SD_ReadBlocks(&hsd, aTestData, 7, 2, 3000) == HAL_OK)  // 读SD卡数据块; 参数:SD结构体、数据地址、块起始地址、读的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束for (uint32_t i = 0; i < SD_TEST_SIZE; i++)                // 打印 写入后块内现在数据printf("%X ",  aTestData[i]);printf("\r\n");}else{printf("SD卡 读测试 失败!\n");}/* 4-1、擦除测试:擦除指定块上的数据  */printf("\r4、擦除块测试 ...\r\n");if (HAL_SD_Erase(&hsd, 7, 8) == HAL_OK)                        // 擦除SD卡上的数据; 参数:SD结构体、块的起始地址、块的结束地址{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束printf("擦除 成功! \r\n");}else{printf("擦除 失败! \r\n");}/* 4-2、读取,擦除后指定块上的数据  */printf("擦除后,现在块内的数据是:\r\n");memset(aTestData, 0, SD_TEST_SIZE);                            // 清0数组的数据if (HAL_SD_ReadBlocks(&hsd, aTestData, 7, 2, 3000) == HAL_OK)  // 读SD卡数据块; 参数:SD结构体、数据地址、块起始地址、读的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束for (uint32_t i = 0; i < SD_TEST_SIZE; i++)                // 打印 块内现在的数据printf("%X ",  aTestData[i]);printf("\r\n");}else{printf("SD卡 读测试 失败!\n");}/* 5-1、写回测试块上的原数据 */printf("\r5、写回原数据 ...\r\n");//memset(aOldData, 1, SD_TEST_SIZE);if (HAL_SD_WriteBlocks(&hsd, aOldData, 7, 2, 3000) == HAL_OK)  // 向SD卡写入数据块; 参数:SD结构体、数据地址、块起始地址、写入的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束printf("写入结束! \n");}else{printf("SD卡 写回原数据 失败!\n");}        /* 5-2、读取,写入后的数据 */printf("现在块内的数据是: \r\n");memset(aTestData, 0, SD_TEST_SIZE);                            // 清0数组的数据if (HAL_SD_ReadBlocks(&hsd, aTestData, 7, 2, 3000) == HAL_OK)  // 读SD卡数据块; 参数:SD结构体、数据地址、块起始地址、读的块数量、超时时间;{while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER); // 等待卡的读写操作结束for (uint32_t i = 0; i < SD_TEST_SIZE; i++)                // 打印 块内现在的数据printf("%X ",  aTestData[i]);printf("\r\n\r\n");}else{printf("SD卡 读测试 失败! \r\n");}printf("SD卡 读写测试结束!\r\n");}

完成后,位置如下图:


七、实验效果

程序运行后,串口助手输出如下:

如有错漏 ,望指正~~~!

相关文章:

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMXKeil, 创建一个SD卡读写的工程。 目录 一、SD卡要点速读 二、SDIO要点速读 三、SD卡座接线原理图 四、CubeMX新建工程 五、CubeMX 生成 SD卡的SDIO通信部分 六、Keil 编辑工程代码 七、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、SD卡 速读…...

新手理解:Android 中 Handler 和 Thread.sleep 的区别及应用场景

新手理解&#xff1a;Android 中 Handler 和 Thread.sleep 的区别及应用场景 Handler 是啥&#xff1f;Handler 的几个核心功能&#xff1a; Thread.sleep 是啥&#xff1f;Thread.sleep 的核心特点&#xff1a; 两者的区别它们的应用场景1. Handler 的应用场景2. Thread.sleep…...

C语言-----扫雷游戏

扫雷游戏的功能说明 &#xff1a; • 使⽤控制台实现经典的扫雷游戏 • 游戏可以通过菜单实现继续玩或者退出游戏 • 扫雷的棋盘是9*9的格⼦ • 默认随机布置10个雷 • 可以排查雷&#xff1a; ◦ 如果位置不是雷&#xff0c;就显⽰周围有⼏个雷 ◦ 如果位置是雷&#xff0c;就…...

监控与调试:性能优化的利器 — ShardingSphere

在分布式数据库系统中&#xff0c;监控和调试是确保系统高效运行的关键。ShardingSphere 提供了多种监控和调试工具&#xff0c;帮助开发者实时跟踪和优化性能&#xff0c;识别瓶颈&#xff0c;进行故障排查&#xff0c;从而提升系统的稳定性和响应速度。本文将介绍如何使用 Sh…...

Kubernetes相关知识入门详解

一、Pod的滚动升级 1.服务升级的一般思路&#xff1a;停止与该服务相关的所有服务pod&#xff0c;重新拉去更新后的镜像并启动。这种方法存在一个比较现实的问题是逐步升级导致较长时间的服务不可用。 2.Kubernetes滚动升级的思路&#xff1a;通过滚动升级的命令创建新的rc&…...

多层 RNN原理以及实现

数学原理 多层 RNN 的核心思想是堆叠多个 RNN 层&#xff0c;每一层的输出作为下一层的输入&#xff0c;从而逐层提取更高层次的抽象特征。 1. 单层 RNN 的数学表示 首先&#xff0c;单层 RNN 的计算过程如下。对于一个时间步 t t t&#xff0c;单层 RNN 的隐藏状态 h t h_t…...

Unity阿里云OpenAPI 获取 Token的C#【记录】

获取Token using UnityEngine; using System; using System.Text; using System.Linq; using Newtonsoft.Json.Linq; using System.Security.Cryptography; using UnityEngine.Networking; using System.Collections.Generic; using System.Globalization; using Cysharp.Thr…...

java+vue项目部署记录

目录 前言 一、java和vue 二、部署记录 1.获取代码 2.运行前端 3.运行后端 三、其他 1.nvm 总结 前言 近期工作需要部署一套javavue前后分离的项目&#xff0c;之前都略有接触&#xff0c;但属于不及皮毛的程度&#xff0c;好在对其他开发语言、html js这些还算熟&am…...

PID 控制算法(二):C 语言实现与应用

在本文中&#xff0c;我们将用 C 语言实现一个简单的 PID 控制器&#xff0c;并通过一个示例来演示如何使用 PID 控制算法来调整系统的状态&#xff08;如温度、速度等&#xff09;。同时&#xff0c;我们也会解释每个控制参数如何影响系统的表现。 什么是 PID 控制器&#xf…...

深入MapReduce——计算模型设计

引入 通过引入篇&#xff0c;我们可以总结&#xff0c;MapReduce针对海量数据计算核心痛点的解法如下&#xff1a; 统一编程模型&#xff0c;降低用户使用门槛分而治之&#xff0c;利用了并行处理提高计算效率移动计算&#xff0c;减少硬件瓶颈的限制 优秀的设计&#xff0c…...

在Spring Boot中使用SeeEmitter类实现EventStream流式编程将实时事件推送至客户端

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…...

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践&#xff1a;一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏&#xff0c;觉得这个抽屉式的侧滑栏非常的有趣&#xff0c;打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 &#xff08;C&#xff0c;GIF帧率砍到毛都不剩了&#xff09; QProperty…...

基于ESP32-IDF驱动GPIO输出控制LED

基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…...

OpenCV文字绘制支持中文显示

OpenCV版本&#xff1a;4.4 IDE&#xff1a;VS2019 功能描述 OpenCV绘制文本的函数putText()不支持中文的显示&#xff0c;网上很多方法推荐的都是使用FreeType来支持&#xff0c;FreeType是什么呢&#xff1f;FreeType的官网上有介绍 FreeType官网 https://www.freetype.or…...

jenkins-k8s pod方式动态生成slave节点

一. 简述&#xff1a; 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式&#xff0c;Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务&#xff0c;从而充分利用集群资源并实现更好的隔离性…...

消息队列篇--基础篇(消息队列特点,应用场景、点对点和发布订阅工作模式,RabbmitMQ和Kafka代码示例等)

1、消息队列的介绍 消息&#xff08;Message&#xff09;是指在应用之间传送的数据&#xff0c;消息可以非常简单&#xff0c;比如只包含文本字符串&#xff0c;也可以更复杂&#xff0c;可能包含嵌入对象。 消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09…...

Jetpack架构组件学习——使用Glance实现桌面小组件

基本使用 1.添加依赖 添加Glance依赖: // For AppWidgets supportimplementation "androidx.glance:glance-appwidget:1.1.0"// For interop APIs with Material 3implementation "androidx.glance:glance-material3:1.1.0"// For interop APIs with Mater…...

go读取excel游戏配置

1.背景 游戏服务器&#xff0c;配置数据一般采用csv/excel来作为载体&#xff0c;这种方式&#xff0c;策划同学配置方便&#xff0c;服务器解析也方便。在jforgame框架里&#xff0c;我们使用以下的excel配置格式。 然后可以非常方便的进行数据检索&#xff0c;例如&#xff…...

Linux系统下速通stm32的clion开发环境配置

陆陆续续搞这个已经很久了。 因为自己新电脑是linux系统无法使用keil&#xff0c;一开始想使用vscode里的eide但感觉不太好用&#xff1b;后面想直接使用cudeide但又不想妥协&#xff0c;想趁着这个机会把linux上的其他单片机开发配置也搞明白&#xff1b;而且非常想搞懂cmake…...

快慢指针及原理证明(swift实现)

目录 链表快慢指针一、快慢指针基本介绍二、快慢指针之找特殊节点1.删除链表的倒数第k个结点题目描述解题思路 2.链表的中间节点题目描述解题思路 三、快慢指针之环形问题1.判断环形链表题目描述解题思路 2.判断环形链表并返回入环节点题目描述解题思路 3.变种——判断快乐数题…...

web前端3--css

注意&#xff08;本文一切代码一律是在vscode中书写&#xff09; 1、书写位置 1、行内样式 //<标签名 style"样式声明"> <p style"color: red;">666</p> 2、内嵌样式 1、style标签 里面写css代码 css与html之间分离 2、css属性:值…...

一文大白话讲清楚webpack基本使用——5——babel的配置和使用

文章目录 一文大白话讲清楚webpack基本使用——5——babel的配置和使用1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. babel-loader的配置和使用2.1 针对ES6的babel-loader2.2 针对typescript的babel-loader2.3 babel配置文件 一文大白话讲清楚webpack基…...

Python自动化运维:一键掌控服务器的高效之道

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...

基于quartz,刷新定时器的cron表达式

文章目录 前言基于quartz&#xff0c;刷新定时器的cron表达式1. 先看一下测试效果2. 实现代码 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&…...

HTML常用属性

HTML标签的常见属性包括许多不同的功能&#xff0c;可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释&#xff1a; 1. src 描述&#xff1a;src&#xff08;source&#xff09;属性指定一个资源的路径&#xff0c;通常用于图像、音频、视频等标签。常见…...

在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具

在 3D 应用程序中&#xff0c;交互式操作对象&#xff08;如平移、旋转、缩放&#xff09;是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo&#xff0c;用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo&#xff0c;并展示如何通过代码实…...

蓝桥杯练习日常|递归-进制转换

蓝桥云课760数的计算 一、递归 题目&#xff1a; 我的解题代码&#xff1a; #include <iostream> using namespace std; int sum0; int main() {// 请在此输入您的代码int n;cin>>n;int fun(int n);fun(n); cout<<sum<<\n;return 0; } // void fu…...

LabVIEW滤波器选择与参数设置

在信号处理应用中&#xff0c;滤波器是去除噪声、提取目标信号的重要工具。LabVIEW 提供多种类型的滤波器&#xff08;如低通、高通、带通、带阻&#xff09;&#xff0c;用户需要根据采样频率、信号特性和应用需求合理选择滤波器类型及参数设置。本文以 采样率 100kHz&#xf…...

【c语言日寄】Vs调试——新手向

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…...

C#中的Timers.Timer使用用法及常见报错

System.Timers.Timer 是一个基于服务器的计时器&#xff0c;它可以在应用程序中定期触发事件。这个计时器特别适合用于多线程环境&#xff0c;并且不应该与用户界面(UI)直接交互。在 ASP.NET 中&#xff0c;通常使用 System.Timers.Timer 来处理周期性的任务。 主要使用步骤&am…...

chrome小插件:长图片等分切割

前置条件&#xff1a; 安装有chrome谷歌浏览器的电脑 使用步骤&#xff1a; 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.选择图片进行切割&#xff0c;切割完成后会自动保存 代码…...

mysql数据被误删的恢复方案

文章目录 一、使用备份恢复二、使用二进制日志&#xff08;Binary Log&#xff09;三、使用InnoDB表空间恢复四、使用第三方工具预防措施 数据误删是一个严重的数据库管理问题&#xff0c;但通过合理的备份策略和使用适当的恢复工具&#xff0c;可以有效地减少数据丢失的风险…...

K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略

1. Pod资源清单的编写 1.1 Pod运行单个容器的资源清单 ##创建工作目录 mkdir -p /root/manifests/pods && cd /root/manifests/pods vim 01-nginx.yaml ##指定api版本 apiVersion: v1 ##指定资源类型 kind: Pod ##指定元数据 metadata:##指定名称name: myweb ##用户…...

Unity Line Renderer Component入门

Overview Line Renderer 组件是 Unity 中用于绘制连续线段的工具。它通过在三维空间中的两个或两个以上的点的数组&#xff0c;并在每个点之间绘制一条直线。可以绘制从简单的直线到复杂的螺旋线等各种图形。 1. 连续性和独立线条 连续性&#xff1a;Line Renderer 绘制的线条…...

计算机工程:解锁未来科技之门!

计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展&#xff0c;计算机技术已经深深渗透到我们生活的方方面面&#xff0c;从医疗、金融到教育&#xff0c;无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业&#xff0c;计算机技术的应用尤为突出。比如&a…...

翻译:How do I reset my FPGA?

文章目录 背景翻译&#xff1a;How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放&#xff08;同步复…...

在Unity中使用大模型进行离线语音识别

文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…...

SpringBoot+Vue使用Echarts

前言 在vue项目中使用echarts&#xff0c;本次演示是使用vue2 1 前端准备 echarts官网&#xff1a; https://echarts.apache.org/zh/index.html 官网提供了基本的使用说明和大量的图表 1.1 下载echarts 执行命令 npm install echarts 直接这样执行很可能会失败&#xff0c;…...

【QT】-explicit关键字

explicit explicit 是一个 C 关键字&#xff0c;用于修饰构造函数。它的作用是防止构造函数进行隐式转换。 为什么需要 explicit&#xff1f; 在没有 explicit 的情况下&#xff0c;构造函数可以用于隐式类型转换。这意味着&#xff0c;如果你有一个接受某种类型的参数的构造…...

docker: Device or resource busy

(base) [rootbddx-vr-gpu-bcc2 /]#rm -rf /ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/ rm: cannot remove ‘/ssd1/docker/overlay2/8d96a51e3fb78e434fcf2b085e952adcc82bfe37485d427e1e017361a277326d/merged’: Device or re…...

Vue - toRefs() 和 toRef() 的使用

一、toRefs() 在 Vue 3 中,toRefs()可以将响应式对象的属性转换为可响应的 refs。主要用于在解构响应式对象时&#xff0c;保持属性的响应性。 1. 导入 toRefs 函数 import { toRefs } from vue;2. 将响应式对象的属性转换为 ref const state reactive({count: 0,message:…...

(2024,MLLM,Healthcare,综述)多模态学习是否已在医疗保健领域实现通用智能?

Has Multimodal Learning Delivered Universal Intelligence in Healthcare? A Comprehensive Survey 目录 0. 摘要 1. 简介 5. MLLM 5.1 模态编码器与跨模态适配器 5.1.1 图像编码器 (Image Encoder) 5.1.2 语言模型 (Language Model) 5.1.3 跨模态适配器 (Cross-moda…...

css命名规范——BEM

目录 引言 BEM是什么? 块Block 元素Element 修饰语Modifier BEM解决了哪些问题? 在流行框架的组件中使用 BEM 格式 实战 认识设计图 如何使用当前的css规范正确命名? 引言 css样式类命名难、太难了,难于上青天,这个和js变量命名还不一样。看看项目中五花八门的样…...

使用PHP函数 “is_object“ 检查变量是否为对象类型

在PHP中&#xff0c;变量可以保存不同类型的值&#xff0c;包括整数、字符串、数组、布尔值等等。其中&#xff0c;对象是一种特殊的数据类型&#xff0c;用于封装数据和方法。在处理PHP代码中&#xff0c;我们经常需要检查一个变量是否为对象类型&#xff0c;以便进行相应的处…...

Golang:使用DuckDB查询Parquet文件数据

本文介绍DuckDB查询Parquet文件的典型应用场景&#xff0c;掌握DuckDB会让你的产品分析能力更强&#xff0c;相反系统运营成本相对较低。为了示例完整&#xff0c;我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…...

Moretl FileSync增量文件采集工具

永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…...

消息队列篇--原理篇--Pulsar(Namespace,BookKeeper,类似Kafka甚至更好的消息队列)

Apache Pulusar是一个分布式、多租户、高性能的发布/订阅&#xff08;Pub/Sub&#xff09;消息系统&#xff0c;最初由Yahoo开发并开源。它结合了Kafka和传统消息队列的优点&#xff0c;提供高吞吐量、低延迟、强一致性和可扩展的消息传递能力&#xff0c;适用于大规模分布式系…...

linux 扩容

tmpfs tmpfs 82M 0 82M 0% /run/user/1002 tmpfs tmpfs 82M 0 82M 0% /run/user/0 [输入命令]# fdisk -lu Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors Units: sectors of 1 * 512 512 bytes Sector size (logi…...

数据表中的数据查询

文章目录 一、概述二、简单查询1.列出表中所有字段2.“*”符号表示所有字段3.查询指定字段数据4.DISTINCT查询 三、IN查询四、BETWEEN ADN查询1.符合范围的数据记录查询2.不符合范围的数据记录查询 五、LIKE模糊查询六、对查询结果排序七、简单分组查询1.统计数量2.统计计算平均…...

深入了解 Java split() 方法:分割字符串的利器

Java 提供的 split() 方法是 String 类中一个常用的工具&#xff0c;它可以将一个字符串根据指定的分隔符切割成多个子字符串&#xff0c;并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式&#xff0c;并…...