【STM32】SD卡

news2024/11/24 19:29:18

(一)常用卡的认识

在学习这个内容之前,作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解,晕头转向。

SD卡:Secure Digital Card的英文缩写,直译就是“安全数字卡”。一般用于大一些的电子设备比如:电脑、数码相机、AV等,做外存储器用。

TF卡:T-Flash卡,又叫micro SD卡,即微型SD卡。TF卡内存比较小,一般用于手机、mp4等小型数码电子产品的外存储器用。

tf卡是什么卡?-百度经验

SIM卡:用户身份识别卡,差不多就是手机卡,智能卡

SIM卡我们非常熟知,当做手机卡等在用,那TF卡和SD卡又有什么区别呢?

(1)卡的外形不同:SD卡比TF卡的尺寸要大,SD卡上有一个lock开关,即写保护开关,而TF卡没有

(2)转换代替:TF卡插入适配器可以转换成SD卡,但是SD卡一般无法转换成TF卡

img

(二)SD卡介绍

特点:容量大、高安全性、体积小

1.种类

SD存储容量等级分为四种

塔尔杰塔斯微型SD梅约雷斯

SDSC---标准容量SD卡【第一张卡,利用 FAT32 文件系统 因此它不能超过 2 GB的存储空间 ,目前它们已退出市场。】

最高2GB

SDHC---高容量SD存储卡【他们的能力范围从 2 GB至32 GB ,也因存储容量低而退出当前市场。 它是第一个使用 exFAT文件系统

2GB-32GB

SDXC---容量扩大化的安全存储卡(基于NAN闪存技术)【今天最常用的,因为它可以达到 2 TB的存储空间

32GB-2TB

SDUC---超容量SD存储卡【如果 2 TB 的容量对您来说太少,那么您可以选择 SDUC,但是它们目前稀有且昂贵,到时候还是将取代 SDXC】

2TB-128TB

注意:STM32最大仅支持32GB SD卡

2.文件形式

如果你对SD卡跟EEPROM或者NOR FLASH操作,读写数据并验证数据的准确性,则不需要FAT文件系统

但是,SD卡经常被用在Windows操作系统上存取数据,就就得使用操作系统支持的FAT文件系统

3.速度等级

SD卡还根据读写速度划分为不同的速度等级,以满足不同应用场景的需求:

写入速度等级有三个参数表示,分别是普通的速度等级Speed Class(C),超高速速度等级UHS Speed Class(U),视频速度等级Video Speed Class*(V),代表数字表示最低写入速度。

img

【C】普通的速度等级Speed Class ​ 有Class 2、Class 4、Class 6和Class 10,简写为C2、C4、C6、C10,分别表示最低写入速度为2MB/s、4MB/s、6MB/s、10MB/s。C10代表可用于高速或更高速的模式。

【U】超高速速度等级UHS Speed Class ​ UHS Speed Class 1和UHS Speed Class 3,简写为U1、U3。U1代表最低写入速度为10M/S,U3代表最低写入速度为30M/S。UHS与U1/U3(UHS Speed Class)不同,不要弄混了。一个是接口标准,一个是速度

【V】视频速度等级Video Speed Class ​ 有V6、V10、V30、V60和V90,V后面的数字表示最低写入速度,单位MB/s,V6表示最低写入速度为6MB/s,V90表示最低写入速度为90MB/s。这个参数对录制视频来说非常重要,录制不同画质的视频对存储卡视频速度等级也不一样。如果要录制4k画质视频,必须要用V30以上的存储卡。

(三)SD卡的驱动介绍

1.SD卡引脚以及接口

9pinSD卡内部结构

SD 卡允许不同的接口来访问它的内部存储单元。最常见的是 SDIO 模式SPI 模式,根据这两种接口模式,我们也列出 SD 卡引脚对应于这两种不同的电路模式的引脚功能定义

microSD 引脚,比 SD 卡少了一个电源引脚 VSS2,其它的引脚功能类似,操作时序也完全相同,所以可以用完全相同的代码驱动

2.SD卡寄存器

SD卡有8个寄存器,但是不能直接进行读写操作,需要通过命令来控制。SD卡根据收到的命令要求对内部寄存器进行修改

3.SD命令以及响应

一个完整的 SD 卡操作过程是:主机(单片机等)发起“命令”--》SD 卡根据命令的内容决定是否发送响应信息及数据等,如果是数据读/写操作,主机还需要发送停止读/写数据的命令来结束本次操作,这意味着主机发起命令指令后,SD 卡可以没有响应、数据等过程,这取决于命令的含义。

(1)命令格式

SD卡命令格式由6个字节所组成,发送数据时高位在前,SD卡的写入命令格式如下:

SD 卡的命令固定为 48 位,由 6 个字节组成,字节 1 的最高 2 位固定为 01,低 6 位为命令 号(比如 CMD16,为 10000B 即 16 进制的 0X10,完整的 CMD16,第一个字节为 01010000, 即 0X10+0X40)。字节 2~5为命令参数,有些命令是没有参数的。字节 6 的高七位为 CRC 值, 最低位恒定为 1

(2)SD卡命令

SD 卡的命令总共有 12 类,分为 Class0~Class11,以下为一些重要命令

上图中,大部分的命令是初始化的时候用的,而表中的 R1、R1b、R2、R3、R6 和 R7 等是 SD卡的应答信号。在主机发送有响应的命令后,SD卡都会给出相对应的应答,以告知主机 该命令的执行情况,或者返回主机需要获取的数据。

(2)SD卡响应

响应,分为长响应136bit、短响应48bit。R1、R1b、 R3、R6 和 R7 属于短响应,而 R2 属于长响应(若使用SDLO接口时,响应通过cmd线传输)

(3)响应接口格式

响应因使用接口不同,格式也不同

(4)卡模式

在SD卡系统(主机和SD卡)定义了两种操作模式:卡识别模式(识别总线上的SD卡类型)和数据传输模式(读写操作)

系统复位后,主机和SD卡都处于卡识别模式,主机在总线上找设备。当SD卡被识别后,SD卡也进入数据传输模式,而主机在总线上是所有卡都被识别后也进入数据传输模式

只关注两个模式:卡识别模式和数据传输模式就好了。

系统复位之后,主机处于卡识别模式,寻找总线上可用的 SDIO 设备,对 SD 卡进行数据读写之前需要识别卡的种类: V1.0 标准卡、V2.0 标准卡、V2.0 高容量卡或者不被识别卡;同时,SD 卡也处于卡识别模式, 直到被主机识别到,即当 SD 卡在卡识别状态接收到 CMD3 (SEND_RCA)命令后,SD 卡就进 入数据传输模式,而主机在总线上所有卡被识别后也进入数据传输模式。

卡识别模式下,主机会复位所有处于“卡识别模式”的 SD 卡,确认其工作电压范围, 识别 SD 卡类型,并且获取 SD 卡的相对地址(卡相对地址较短,便于寻址)。在卡识别过程中, 要求 SD 卡工作在识别时钟频率 FOD 的状态下

  • 上电

  • CMD0【软件复位】

  • CMD8【主机询问SD卡是否支持电压范围】(V2.0卡支持该命令,V1.x和MMC卡不支持)

    • 如果R1响应,ACMD41

      • R3响应【判断是高容量还是标准】(响应R3中返回OCR寄存器:CCS1 高容量V2.0卡,CCS0 标准V2.0卡)

    • 如果R1不响应,ACMD41【用于判断是V1.x卡还是MMC卡,其中MMC不支持】

      • R1响应,则为V1.x卡

      • R1不响应,CMD1【判断MMC卡或其他不能被识别的卡,其中CMD1激活MMC卡】

        • 响应则是MMC卡

主机上电后,所有卡处于空闲状态,包括当前处于无效状态的卡。主机也可以发送 GO_IDLE_STATE(CMD0)让所有卡软复位从而进入空闲状态,但当前处于无效状态的卡并不 会复位。 主机在开始与卡通信前,需要先确定双方在互相支持的电压范围内。SD 卡有一个电压支持范围,主机当前电压必须在该范围可能才能与卡正常通信。

SEND_IF_COND(CMD8)命令就是用于验证卡接口操作条件的(主要是电压支持)。卡会根据命令的参数来检测操作条件匹配性,如果卡支持主机电压就产生响应,否则不响应。而主机则根据响应内容确定卡的电压匹配性。

SD_SEND_OP_COND(ACMD41)命令可以识别或拒绝不匹配它的电压范围的卡。 ACMD41 命令的 VDD 电压参数用于设置主机支持电压范围,卡响应会返回卡支持的电压范围。

ALL_SEND_CID(CMD2)用来控制所有卡返回它们的卡识别号(CID),处于准备状态的卡 在发送 CID之后就进入识别状态。之后主机就发送 SEND_RELATIVE_ADDR(CMD3)命令,让 卡自己推荐一个相对地址(RCA)并响应命令。这个 RCA 是 16bit 地址,而 CID 是 128bit 地址, 使用 RCA 简化通信。卡在接收到 CMD3 并发出响应后就进入数据传输模式,并处于待机状态, 主机在获取所有卡 RCA 之后也进入数据传输模式。

下图为数据传播模式卡状态转换

(5)数据块读取流程

1.SD卡单块数据块读取流程

  1. 发送CMD16指令,设置数据块大小

  2. 等待CMD16响应(R1)

  3. 发送CMD17指令,开始读取数据

  4. 等待CMD17响应(R1)

  5. 读一个数据块的数据

    其中注意的是:CMD16设置的数据块大小,一般是512字节,此设置直接决定了SD卡的块大小,SD卡默认的块大小自动失效

2.SD卡多块数据块读取流程

  1. 发送CMD16指令,设置数据块大小

  2. 等待CMD16响应(R1)

  3. 发送 CMD18指令,开始读数据块

  4. 等待CMD18响应(R1)

  5. 读一个数据块的数据

  6. 读两个数据块的数据

  7. 读n个数据块的数据

  8. 发送CMD12指令,结束数据块读取

  9. 等待CMD12响应(R1)

  10. 结束多块数据块读取

(5)数据传输格式

SD卡有两种数据模式,一种是常规的 8位宽,即一次按一字节传输,另一种是一次按 512 字节传输,我们只介绍前面一种。当按 8-bit 连续传输时,每次传输从最低字节开始,每字节从最高位(MSB)开始发送,当使用一条数据线时,只能通过 DAT0** 进行数据传输

当使用 4 线模式传输 8-bit 结构的数据时,数据仍按 MSB 先发送的原则,DAT[3:0]的高位发送高数据位,低位发送低数据位。其特点为可提升传输速率。

(四)STM32驱动SD卡代码解析

1.原理图:

(1)SDIO_CK ---> 产生时钟

[SDIO_CK = SDIOCLK【48MHZ】 / ( 2 + CLKDIV ) SD卡初始化时,SDIO_CK不可超过400Khz,初始化完成之后,可设为最大操作频率(但不能超过25Mhz) ]  

(2)SDIO_CMD ---> 发送命令、接收响应

(3)SDIO_D ---> 双向传输数据

2.STM32F4 HAL函数

HAL库有为我们准备专门驱动SD卡的代码,主要存放在 stm32f4xx_hal_sd.c/h 下。

(1)HAL_SD_Init函数

初始化SIOD外设操作,其声明如下

HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd)

形参是一个SD卡的句柄,精简后如下

typedef struct
{
  SD_TypeDef                   *Instance;        /*!< SD 相关寄存器基地址           */
  SD_InitTypeDef               Init;             /*!<  SDIO 初始化变量             */
  HAL_LockTypeDef              Lock;             /*!< 互斥锁,用于解决外设访问冲突    */
  uint8_t                      *pTxBuffPtr;      /*!< SD 发送数据指针              */
  uint32_t                     TxXferSize;       /*!< SD 发送缓存按字节数的大小      */
  uint8_t                      *pRxBuffPtr;      /*!< SD 接收数据指针              */
  uint32_t                     RxXferSize;       /*!< SD 接收缓存按字节数的大小      */
  __IO uint32_t                Context;          /*!<  HAL 库对 SD 卡的操作阶段     */
  __IO HAL_SD_StateTypeDef     State;            /*!<  SD 卡操作状态               */ 
  __IO uint32_t                ErrorCode;        /*!< SD 卡错误代码                */
  DMA_HandleTypeDef            *hdmatx;          /*!< SD DMA 数据发送指针          */
  DMA_HandleTypeDef            *hdmarx;          /*!<  SD DMA 数据接收指针         */
  HAL_SD_CardInfoTypeDef       SdCard;           /*!< SD 卡信息                   */
  uint32_t                     CSD[4];           /*!<  保存 SD 卡 CSD 寄存器信息    */
  uint32_t                     CID[4];           /*!< 保存 SD 卡 CID 寄存器信息     */
}SD_HandleTypeDef;

其中的

typedef struct
{
  uint32_t CardType;                     /*!< 存储卡类型标记:标准卡、高速卡           */
  uint32_t CardVersion;                  /*!<  存储卡版本            */
  uint32_t Class;                        /*!< 卡类型  */
  uint32_t RelCardAdd;                   /*!< 卡相对地址  */
  uint32_t BlockNbr;                     /*!< 卡存储块数 */
  uint32_t BlockSize;                    /*!< SD 卡每个存储块大小    */
  uint32_t LogBlockNbr;                  /*!<  以块表示的卡逻辑容量*/
  uint32_t LogBlockSize;                 /*!< 以字节为单位的逻辑块大小 */
}HAL_SD_CardInfoTypeDef;

(2)HAL_SD_ConfigWideBusOperation 函数

SD 卡上电后默认使用 1 位数据总线进行数据传输,卡如果允许,可以在初始化完成后重新设置 SD 卡的数据位宽以加快数据传输过程,以下是可修改的总线宽度值

#define SDIO_BUS_WIDE_1B ((uint32_t)0x00000000U)
#define SDIO_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0
#define SDIO_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1

(3) HAL_SD_ReadBlocks 函数

SD 卡初始化后从 SD 卡的指定扇区读一定数量的数据:

HAL_StatusTypeDef HAL_SD_ReadBlocks (SD_HandleTypeDef *hsd, uint8_t *pData,
uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);

(4)HAL_SD_WriteBlocks 函数

SD 卡初始化后,在 SD 卡的指定扇区写入一定数量的数据

HAL_StatusTypeDef HAL_SD_WriteBlocks (SD_HandleTypeDef *hsd, uint8_t *pData,
uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout);

(5)HAL_SD_GetCardInfo 函数

SD 卡初始化后,根据设备句柄读 SD 卡的相关状态信息

HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd,HAL_SD_CardInfoTypeDe*pCardInfo);
3.SDIO驱动SD卡关键代码
(1)使能SDIO和相关GPIO时钟,设置好GPIO工作模式
(2)初始化SDIO
(3)初始化SD卡

sd_init 函数:填充SDMMC结构体的控制句柄,然后使用HAL库的 HAL_SD_Init 初始化函数即可,在此过程中 HAL_SD_Init 会调用 HAL_SD_MspInit 函数回调函数,根据外设的情况,我们可以设置数据总线宽度为 4 位

(4)SD卡读取扇区数据

上我们使用它来对 HAL 库的读函数 HAL_SD_ReadBlocks进行了二次封装,并在最后加入了状态判断以使后续操作(实际上这部分代码也可以省略),直接根据读函数返回值自己作其它处理。为了保护 SD 卡的数据操作,我们在进行操作时暂时关闭了中断以防止数据读过程发生意外。

(5)SD卡写入扇区数据

我们使用它来对 HAL 库的写函数 HAL_SD_WriteBlocks 进行了二次封装,并在最后加入了状态判断以使后续操作(实际上这部分代码也可以省略),直接根据写函数返回值自己作其它处理。为了保护 SD 卡的数据操作,我们在进行操作时暂时关闭了中断以防止数据写过程发生意外。

4.SPI驱动SD卡步骤
(1)SD卡初始化

SPI操作模式下:在SD卡收到复位命令时,CS为有效电平(低电平),则SPI模式被启用,在发送CMD之前要先发送74个时钟,64个为内部供电上升时间,10个用于SD卡同步;之后才能开始CMD操作,在初始化时CLK时钟不能超过400KHz

(1)初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置)

(2)上电延时(>74个CLK)

(3)复位卡(CMD0),进入IDLE状态

(4)发送CMD8,检查是否支持2.0协议

(5)根据不同协议检查SD卡(命令包括:CMD55、CMD41、CMD58和CMD1等)

(6)取消片选,发多8个CLK,结束初始化

这样我们就完成了对SD卡的初始化,注意末尾发送的8个CLK是提供SD卡额外的时钟,完成某些操作。通过SD卡初始化,我们可以知道SD卡的类型(V1、V2、V2HC或者MMC),在完成了初始化之后,就可以开始读写数据了。

(2)SD卡读扇区数据

(1)发送CMD17

(2)接收卡响应R1

(3)接收数据起始令牌0XFE

(4)接收数据

(5)接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉

(6)禁止片选之后,发多8个CLK

(3)SD卡写入数据

(1)发送CMD24

(2)接收卡响应R**1**

(3)发送写数据起始令牌0XFE

(4)发送数据

(5)发送2字节的伪CRC

(6)禁止片选之后,发多8个CLK

5.SDIO驱动SD卡实验

打开SDIO

打开中断

打开usart1

打开其中断

关键也就这两个操作,其它操作都很简单,就是配配时钟,这里要提到一个小地方:一定要打开debug当中的Serial,否则程序烧录一次之后就会识别烧录器失败!!!但也不要怕,本人一早到解决方法:BOOT0用杜邦线接3V3,然后按一下开发板上的reset键,亲测有效!!!

生成完工程之后,为了串口调试方便,在usart.c当中加入以下

#include "stdio.h"
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

接着在main.c文件声明SD对象

HAL_SD_CardInfoTypeDef pCardInfo;

声明

#define BLOCK_SIZE   512                            //一个块的字节数
#define NUMBERS_PER_CHUNK 512                                           //多少个数据存一次
#define INT_SIZE 1                                                      //一个数值占几个字节
#define BUFFER_SIZE (NUMBERS_PER_CHUNK * INT_SIZE)  //存一次sd卡的数组的大小(其实就是512)
 
uint8_t buffer_TX[NUMBERS_PER_CHUNK];                           // 用于暂时存储需要发送到SD卡的数据
uint8_t buffer_RX[NUMBERS_PER_CHUNK];                           // 用于接收从SD卡中读取来的数据  

插上SD卡 在main当中添加查看SD卡信息

    HAL_SD_GetCardInfo(&hsd,&pCardInfo);
    printf("SD卡类型:%u\r\n",pCardInfo.CardType);          //卡的类型
    printf("SD卡版本:%u\r\n",pCardInfo.CardVersion); //卡的版本
    printf("SD卡块数:%u\r\n",pCardInfo.BlockNbr);    //SD卡块数
    printf("SD卡每块大小:%u\r\n",pCardInfo.BlockSize);//每一块的大小

(1)读取SD卡中的数据

 
            for(int chunk=0;chunk<1;chunk++)
        {
            //计算读取的块数量
            uint32_t blocksToRead = BUFFER_SIZE/BLOCKSIZE;
            
            //从SD卡读取数量
            if(HAL_SD_ReadBlocks(&hsd,(uint8_t *)buffer_RX,blockNum,1,1000)==HAL_OK)
            {
                while(HAL_SD_GetCardState(&hsd)!=HAL_SD_CARD_TRANSFER);//返回到传输状态退出
                
                for(int i=0;i<NUMBERS_PER_CHUNK;i++)
                {
                    printf("%d\t",buffer_RX[i]);
                }
                printf("\n读取成功!\n");
            }
            else
            {
                printf("读取失败!\n");
            }
            blockNum +=1;//更新块号读取下一个段
        }

由于篇幅过长,可以看下一篇文章具体讲解以及更多玩法!

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

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

相关文章

《JVM第5课》虚拟机栈

无痛快速学习入门JVM&#xff0c;欢迎订阅本免费专栏 Java虚拟机栈&#xff08;Java Virtual Machine Stack&#xff0c;简称JVM栈&#xff0c;又称Java方法栈&#xff09;是 JVM 运行时数据区的一部分&#xff0c;主要用于支持Java方法的执行。每当一个新线程被创建时&#xf…

Java Executor RunnableScheduledFuture 总结

前言 相关系列 《Java & Executor & 目录》《Java & Executor & RunnableScheduledFuture & 源码》《Java & Executor & RunnableScheduledFuture & 总结》《Java & Executor & RunnableScheduledFuture & 问题》 涉及内容 《…

软考(中级-软件设计师)数据库篇(1101)

第6章 数据库系统基础知识 一、基本概念 1、数据库 数据库&#xff08;Database &#xff0c;DB&#xff09;是指长期存储在计算机内的、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和存储&#xff0c;具有较小的冗余度、较高的数据独立性和扩展…

zynq PS端跑Linux响应中断

这篇文章主要是讲述如何在Zynq的PS上跑Linux启动IRQ&#xff0c;环境为vivado2019.1&#xff0c;petalinux2019.1 ubuntu20.04&#xff0c;本人初学者&#xff0c;欢迎批评指正 1. Vivado硬件设计 确保自定义IP的中断信号通过 IRQ_F2P 连接到PS端。在开始Petalinux配置之前&a…

R语言贝叶斯

原文链接&#xff1a;R语言贝叶斯进阶&#xff1a;INLA下的贝叶斯回归、生存分析、随机游走、广义可加模型、极端数据的贝叶斯分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247625527&idx8&snba4e50376befd94022519152609ee8d0&chksmfa8daad0cdfa…

qt QRadioButton详解

QRadioButton 是一个可以切换选中&#xff08;checked&#xff09;或未选中&#xff08;unchecked&#xff09;状态的选项按钮。单选按钮通常呈现给用户一个“多选一”的选择&#xff0c;即在一组单选按钮中&#xff0c;一次只能选中一个按钮。 重要方法 QRadioButton(QWidget…

webm格式怎么转换成mp4?这9种转换方法你肯定能够学会!

webm格式怎么转换成mp4&#xff1f;WebM&#xff0c;作为一种新兴的视频文件格式&#xff0c;虽然带着革新性的光芒&#xff0c;在视频压缩效率和播放流畅性上表现出色&#xff0c;却也面临着几个重要的挑战&#xff0c;这些问题直接影响了用户的体验&#xff0c;首先&#xff…

HTML 语法规范全解:构建清晰、兼容性强的网页基础

文章目录 一、代码注释1.1 使用注释的主要目的1.2 使用建议二、标签的使用2.1 开始标签和结束标签2.2 自闭合标签2.3 标签的嵌套2.4 标签的有效性三、属性四、缩进与格式4.1 一致的缩进4.2 元素单独占用一行4.3 嵌套元素的缩进4.4 避免冗长的行五、字符编码六、小结在开发 HTML…

10 P1094 [NOIP2007 普及组] 纪念品分组

题目&#xff1a; 代码&#xff1a; #include<iostream> using namespace std; # define M 100 #include<algorithm> int sa[100005];int main() {int w,n;cin>>w>>n;for(int i1;i<n;i){cin>>sa[i];}sort(sa1,sa1n);int l1;int rn;int count…

LeetCode.冗余连接(并查集以及广度优先搜索)

684.冗余连接| 传送门&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 树可以看成是一个连通且 无环 的 无向 图。 给定往一棵 n 个节点 (节点值 1&#xff5e;n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间&#xff0c;且这条附加的边不属于树中…

一文彻底整明白,基于Ollama工具的LLM大语言模型Web可视化对话机器人部署指南

在上一篇博文中&#xff0c;我们在本地部署了Llama 3 8B参数大模型&#xff0c;并用 Python 写了一个控制台对话客户端&#xff0c;基本能愉快的与 Llama 大模型对话聊天了。但控制台总归太技术化&#xff0c;体验不是很友好&#xff0c;我们希望能有个类似 ChatGPT 那样的 Web…

BES2600WM---HiLink RM56 EVK

0 Preface/Foreword 1 环境搭建 1.1 安装依赖工具 sudo apt-get install build-essential gcc g make zlib* libffi-dev e2fsprogs pkg-config flex bison perl bc openssl libssl-dev libelf-dev libc6-dev-amd64 binutils binutils-dev libdwarf-dev u-boot-tools mtd-utils…

Leetcode21:合并两个有效链表

原题地址&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示…

51c嵌入式~IO合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/12383193 一、单片机通信数据接收解析方法 前阵子一朋友使用单片机与某外设进行通信时&#xff0c;外设返回的是一堆格式如下的数据&#xff1a; AA AA 04 80 02 00 02 7B AA AA 04 80 02 00 08 75 AA AA 04 80 02 00 9B E2…

java或c#是如何对数据库的表字段加密的处理的?

对于表格数据的加密处理&#xff0c;通常涉及到对数据库中存储的数据进行加密&#xff0c;以保护敏感信息。 Java示例&#xff08;使用AES算法加密数据库表数据&#xff09; 首先&#xff0c;你需要一个数据库连接&#xff0c;这里假设你使用的是JDBC连接MySQL数据库。以下是…

Android Studio Dolphin 下载、安装与配置教程

文章目录 Android Studio Dolphin简介一、核心特性二、新增功能三、用户体验优化 一&#xff0c;下载百度网盘迅雷云盘 二&#xff0c;安装三&#xff0c;下载组件四&#xff0c;添加SDK五&#xff0c;创建项目六&#xff0c;安装 Device模拟器运行项目 Android Studio Dolphin…

java开发等一些问题,持续更新

微服务和单服务的区别 微服务&#xff08;Microservices&#xff09;和单体服务&#xff08;Monolithic Architecture&#xff09;是两种不同的软件架构风格&#xff0c;各有其特点和适用场景。 微服务架构&#xff1a; 模块化&#xff1a; 微服务架构将应用程序分解为一系列小…

全国分省灵活就业情况数据集(2015-2019年)

数据简介&#xff1a;就业是民生之本&#xff0c;是“六稳”“六保”之首&#xff0c;对于拥有14亿人口的中国而言&#xff0c;就业问题至关重要。“十四五”规划建议中指出&#xff0c;应强化就业优先政策&#xff0c;千方百计稳定和扩大就业&#xff0c;实现更充分更高质量就…

杂货 | 每日资讯 | 2024.10.31

注意&#xff1a;以下内容皆为AI总结 在2024年10月30日&#xff0c;人工智能领域涌现出一些重要的新发展和大事件。这些新进展涉及人工智能在金融、搜索技术以及大型科技公司业务扩展中的广泛应用。本文将详细解读当天的几大AI事件&#xff0c;以便大家更好地理解当今AI技术的…

分享几款开源好用的图片在线编辑,适合做快速应用嵌入

图片生成器是指一种工具或软件&#xff0c;用于自动生成图片或图像内容&#xff0c;通常依据用户设定的参数或模板进行操作。这种工具能够帮助用户快速创建视觉效果丰富的图像&#xff0c;而无需具备专业的设计技能。 在数字化时代&#xff0c;图片编辑已经成为日常工作和生活的…