STM32H743-ARM例程13-SDIO - 实践

news/2025/9/30 20:54:16/文章来源:https://www.cnblogs.com/lxjshuju/p/19121762

目录

  • 实验平台
  • SDIO
    • SDIO简介
    • SD卡物理结构
    • SDIO总线
      • 命令
      • 响应
    • SD卡操作模式
      • SD卡识别模式
      • 数据传输模式
    • SDMMC
      • SDMMC框图
      • SDMMC时钟
  • 原理图
  • STM32CubeMX生成工程
  • 实验代码
  • 实验现象

实验平台

硬件:银杏科技GT7000双核心开发板-ARM-STM32H743XIH6,银杏科技iToolXE仿真器
软件:最新版本STM32CubeH7固件库,STM32CubeMX v6.10.0,开发板环境MDK v5.35,串口工具putty

SDIO

SDIO简介

  SD 卡(Secure Digital Memory Card) 在我们生活中已经非常普遍了,控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种就是 SDIO 接口。SDIO 全称是安全数字输入/输出接口,多媒体卡(MMC)、SD 卡、SD I/O 卡都有 SDIO 接口。 MMC 卡可以说是 SD 卡的前身,现阶段已经用得很少。STM32H743x系列控制器有两个SDIO主机接口,它可以与MMC卡、SD卡、SD I/O卡以及CE-ATA设备进行数据传输。SD I/O卡是在SD内存卡接口的基础上发展起来的外设接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备,目前根据SDIO协议的SPEC,SDIO接口支持的设备总类有蓝牙,网卡,电视卡等。CE-ATA是一种使用MMC接口界面,ATA指令集的接口,CE-ATA相较于ATA节省了很多管脚,有助于简化消费电子(CE)和ATA硬盘的结合,例如轻薄笔记本硬盘设计的硬盘高速通讯接口。
  各种媒体卡都有自己的系统规范,想了解的读者可以参考他们的官网:多媒体卡协会网站www.mmca.org、SD卡协会网站www.sdcard.org、CE-ATA工作组网站www.ce-ata.org。
  到目前为止,SDIO接口的设备整体概括图如下图所示:
在这里插入图片描述
  本章实验将针对SD卡进行读写测试,STM32H743x系列控制器只支持SD卡规范版本2.0, 即只支持标准容量SD和高容量SDHC标准卡,不支持超大容量SDXC标准卡,所以可以支持的最高卡容量是32GB。

SD卡物理结构

在这里插入图片描述

  SD卡也有着自己的寄存器,但是并不能直接进行读写,只能通过对于的命令访问,SDIO协议定义64个命令来实现一些特殊功能,SD卡接收到命令后,根据接受到的命令对内部寄存器进行修改,
下图就是我们对SD卡发送命令的数据通道:
在这里插入图片描述

SDIO总线

  SD卡一般支持两种接口,一种SDIO,另一种是SPI,本章实验我们用的SDIO接口操作方式,SPI我们后续章节我详细介绍。另外,STM32H743x系列控制器的SDIO是不支持SPI通信模式的,如果需要用到SPI通信只能使用SPI外设。
  SD总线上的通信以命令/数据的比特流为基础,起始位表示数据的传输的开始,终止位表示数据传输的结束。

命令

  SD命令由主机发出,以广播命令和寻址命令为例,广播命令是针对与SD主机总线连接的所有从设备发送的,寻址命令是指定某个地址设备进行命令传输。命令字段的组成如下:
在这里插入图片描述

  • 起始位是1bit的 0
  • 传输标志是1bit的 1,该位为1时表示命令,方向为主机传输到SD卡,该位为0时表示响应,方向为SD卡传输到主机。
  • 命令号长度是6bit,代表命令的编号它固定占用6bit,例如对于CMD17(代号:CMD0~CMD63),这6bit就应该是 17 的二进制表示 010001,每个命令都有特定的用途, 部分命令不适用于SD卡操作,只是专门用于MMC卡或者SD I/O卡
  • 参数/地址长度是32bit,不同命令有不同的参数要求
  • CRC7是校验码,长度是7bit,需要根据命令包的 [47:8] 位来计算 (起始位、方向位、命令号、参数都参与 CRC7 的计算)
  • 结束为是1bit的 1

命令类型:
SD 命令有 4 种类型:

  • 无响应广播命令(bc),发送到所有卡,不返回任务响应;
  • 带响应广播命令(bcr),发送到所有卡,同时接收来自所有卡响应;
  • 寻址命令(ac),发送到选定卡,DAT 线无数据传输;
  • 寻址数据传输命令(adtc),发送到选定卡,DAT线有数据传输。

详细命令描述本章不再赘述,有兴趣读者可以参考文章【SDIO】SD2.0协议分析总结(三)-- SD卡相关命令介绍。

响应

  响应 (response) 的方向都是从SD卡向主机发出,发生在 sdcmd 信号上,且只可能紧随一个命令后。部分命令要求SD卡作出响应,这些响应多用于反馈SD卡的状态。SDIO响应有7种类型 (R1-7)。其中 SD卡没有 R4、R5类型响应。各个类型响应具体情况如下表所示。

在这里插入图片描述

SD卡操作模式

SD卡识别模式

  在系统复位后,主机处于卡识别模式,认其工作电压范围,识别SD卡类型, 并且获取SD卡的相对地址(卡相对地址较短,便于寻址)。
  在主机和SD卡开始通信时,主机可能不知道SD卡支持的电压,SD卡也可能不知道它是否支持当前提供的电压。主机发出一个复位命令(CMD0),同时假定它电压可能被SD卡支持。为了验证电压,SD卡标准V2.0版本文档中定义了以下新命令,SEND_IF_COND(CMD8)命令就是用于验证卡接口操作条件的(主要是电压支持)。卡会根据命令的参数来检测操作条件匹配性,如果卡支持主机电压就产生响应,否则不响应。
  SD_SEND_OP_COND (ACMD41)被设计为为主机提供一种机制来识别和拒绝与主机所提供的VDD范围不匹配的卡。不能在指定范围内进行数据传输的SD卡,应放弃总线操作,进入Inactive 状态。OCR寄存器定义了相关的电压等级。卡在响应ACMD41之后进入准备状态,不响应ACMD41的卡为不可用卡,进入无效状态。
注意:ACMD41是特定应用程序的命令,因此APP_CMD (CMD55)应该始终在ACMD41之前被发送。在idle_state中用于CMD55的RCA将是SD卡的默认值(RCA = 0 x0000)。

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

数据传输模式

  在数据模式下我们可以对SD卡的存储块进行读写访问操作。SD卡数据包有两种格式,一种是常规数据(8bit宽),它先发低字节再发高字节,而每个字节则是先发高位再发低位,4线传输示意如图 8位宽数据包传输。
  当使用4线模式传输8-bit结构的数据时,数据仍按MSB先发送的原则,DAT[3:0]的高位发送高数据位,低位发送低数据位。硬件支持的情况下,使用4线传输可以提升传输速率。
在这里插入图片描述

  另一种数据包发送格式是宽位数据包格式,宽数据(SD内存寄存器):宽数据以MSB位优先发送。一次按512字节传输,主机发出ACMD13命令后SD卡将SSR寄存器内容通过DAT线发送给主机。
在这里插入图片描述
  只有SD卡系统处于数据传输模式下才可以进行数据读写操作。数据传输模式下可以将主机SD时钟频率设置为FPP,默认最高为25MHz,频率切换可以通过CMD4命令来实现。数据传输模式下,SD卡状态转换过程见下图
在这里插入图片描述
  CMD7用于选择一张SD卡并将其置于传输状态,在同一时刻只能有一张卡处于传输状态。如果先前选择的卡处于传输状态,它与主机的连接将被释放,它将返回到待机状态。当CMD7以保留的相对卡片地址“0x0000”发出时,所有卡片都被退回到待机状态。
  据传输模式下的数据通信都是主机和目标卡之间通过寻址命令点对点进行的。卡处于传输状态下可以通过命令对卡进行数据读写、擦除。CMD12可以中断正在进行的数据通信,让卡返回到传输状态。CMD0和CMD15会中止任何数据编程操作, 返回卡识别模式,这可能导致卡数据被损坏。

SDMMC

SDMMC框图

SDMMC 由三部分组成:

  SDMMC_CK、SDMMC_D[3:0]、SDMMC_CMD这几根线即可正常驱动SD卡,复位后默认情况下SDMMC_D0用于数据传输。初始化后主机可以改变数据总线的宽度(通过ACMD6命令设置)。
SDMMC_CMD有两种操作模式:
①用于初始化时的开路模式(仅用于MMC版本V3.31或之前版本)
②用于命令传输的推挽模式(SD/SD I/O卡和MMC V4.2在初始化时也使用推挽驱动)
  STM32H7支持DS(Default Speed)、HS(High Speed),SDR以及DDR50等多种模式,见表格 SDIO总线速度模式。
在这里插入图片描述
  SDR表示单倍速率(时钟单边沿采样),DDR表示双倍速率(时钟双边沿采样),由表可知,STM32H7支持最高的SDR104总线速度模式,理论上传输速度最高可达104MB/s(实际上由于IO口速度无法达到208Mhz,所以,是达不到104MB/s的传输速度的)。这里的DS、HS、SDR12、SDR25、DDR50、SDR50、SDR104等速度模式,实际上是超高速I卡所支持的一些速度等级。
  我们的SD卡接口是3.3V供电的,所以,仅支持DS和HS模式(最高25MB/s的传输速度)。

SDMMC时钟

  在SDMMC功能框图中我们可以发现,SDMMC总共有3个时钟,分别是:
卡时钟(SDMMC_CK): SDMMC(Secure Digital MultiMediaCard)控制器输出的时钟信号,用于同步主机与SD卡/设备之间的通信。每个时钟周期在命令和数据线上传输1位命令或数据‌。标准模式下:频率范围≤25MHz,卡识别:‌频率范围≤400kHz。
SDMMC适配器内核时钟(sdmmc_ker_ck): SDMMC控制器的内核时钟输入,用于驱动SDMMC适配器内部逻辑。它通常与AHB总线时钟(sdmmc_hclk)协同工作,为SDMMC控制器提供时钟基准‌,默认选择来自pll1_q_ck,其频率一般为240Mhz,并用于产生SDMMC_CK时钟。
AHB3总线接口时钟(sdmmc_hclk): SDMMC控制器的AHB总线接口时钟,用于驱动SDMMC控制器的AHB总线接口。其频率通常为HCLK(AHB总线时钟)的一半。

原理图

在这里插入图片描述

STM32CubeMX生成工程

我们参考前面章节STM32H743-结合CubeMX新建HAL库MDK工程,打开CubeMX软件,重复步骤不再展示,我们来看配置SDMMC部分如下图所示:

在这里插入图片描述
在这里插入图片描述

实验代码

1. 主函数

在这里插入代码片`int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SDMMC1_SD_Init();
MX_USART6_UART_Init();
uart6.printf("Micro SD Card Test... \r\n");
uint8_t read_buf[512];      // 读数据缓存
uint8_t write_buf[512];     // 写数据缓存
HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B);
/* SD卡状态 */
int sdcard_status = 0;
HAL_SD_CardCIDTypeDef sdcard_cid;
/* 获取SD卡状态 */
sdcard_status = HAL_SD_GetCardState(&hsd1);
// 处于数据传输模式的传输状态
if(sdcard_status == HAL_SD_CARD_TRANSFER)
{
uart6.printf("SD card init ok!\r\n\r\n");
// 打印SD卡基本信息
uart6.printf("SD card information! \r\n");
// 容量信息
uart6.printf("CardCapacity(Byte): %llu \r\n",((unsigned long long)hsd1.SdCard.BlockSize * hsd1.SdCard.BlockNbr));
// 块大小
uart6.printf("CardBlockSize(Byte): %d \r\n", hsd1.SdCard.BlockSize);
// 有多少个块
uart6.printf("CardBlockNumber: %d \r\n", hsd1.SdCard.BlockNbr);
uart6.printf("RCA: %d \r\n", hsd1.SdCard.RelCardAdd);
uart6.printf("CardType: %d \r\n", hsd1.SdCard.CardType);
// 读取并打印SD卡的CID信息
HAL_SD_GetCardCID(&hsd1, &sdcard_cid);
// 制造商
uart6.printf("ManufacturerID: %d \r\n",sdcard_cid.ManufacturerID);
}
else
{
uart6.printf("SD card init fail! \r\n" );
return 0;
}
/* 读取未操作之前的数据 */
uart6.printf("------------------- Read SD card block data Test ------------------\r\n");
/*
读一个扇区的数据:
0: 从第0个扇区开始。
1:读一个扇区的数据。
0xffff:等待时间。
note:也就是只读了第0个扇区。
*/
sdcard_status = HAL_SD_ReadBlocks(&hsd1, (uint8_t *)read_buf, 0, 1, 0xffff);
if(sdcard_status == HAL_OK)
{
uart6.printf("Read block data ok! \r\n");
for(int i = 0; i < 512; i++)
{
uart6.printf("0x%02x ", read_buf[i]);
if((i+1)%16 == 0)
{
uart6.printf("\r\n");
}
}
}
else
{
uart6.printf("Read block data fail! status = %d \r\n", sdcard_status);
}
/* 向SD卡块写入数据 */
uart6.printf("------------------- Write SD card block data Test ------------------\r\n");
/* 填充缓冲区数据 */
for(int i = 0; i < 512; i++)
{
write_buf[i] = i % 256;
}
// 开始写入数据
/*
写一个扇区的数据:
0: 从第0个扇区开始。
1:写一个扇区的数据。
0xffff:等待时间。
note:也就是只写了第0个扇区。
*/
sdcard_status = HAL_SD_WriteBlocks(&hsd1, (uint8_t *)write_buf, 0, 1, 0xffff);
if(sdcard_status == HAL_OK)
{
/* 传输完成不代表写入完成,因此要等待SD卡状态变为可传输状态。擦除操作也是一样。 */
uart6.printf("Writing block data. state = %d \r\n", HAL_SD_GetCardState(&hsd1));
while (HAL_SD_GetCardState(&hsd1) == HAL_SD_CARD_PROGRAMMING);
uart6.printf("Write block data ok,state = %d \r\n", HAL_SD_GetCardState(&hsd1));
}
else
{
uart6.printf("Write block data fail! status = %d \r\n", sdcard_status);
}
/* 读取写入之后的数据 */
uart6.printf("------------------- Read SD card block data after Write ------------------\r\n");
sdcard_status = HAL_SD_ReadBlocks(&hsd1, (uint8_t *)read_buf, 0, 1, 0xffff);
if(sdcard_status == HAL_OK)
{
uart6.printf("Read block data ok! \r\n");
for(int i = 0; i < 512; i++)
{
uart6.printf("0x%02x ", read_buf[i]);
if((i+1)%16 == 0)
{
uart6.printf("\r\n");
}
}
}
else
{
uart6.printf("Read block data fail! status = %d \r\n", sdcard_status);
}
/* 擦除SD卡块 */
uart6.printf("------------------- Block Erase -------------------------------\r\n");
/*
擦除512个扇区的数据:
0: 从第0个扇区开始。
1:一直擦除到512扇区。
note:擦除第0到第512个扇区数据,也包括0512,也就是一共512个。
*/
sdcard_status = HAL_SD_Erase(&hsd1, 0, 512);
// 等待擦除完毕
if (sdcard_status == HAL_OK)
{
uart6.printf("Erasing block. state = %d \r\n", HAL_SD_GetCardState(&hsd1));
while (HAL_SD_GetCardState(&hsd1) == HAL_SD_CARD_PROGRAMMING);
uart6.printf("Erase block ok state = %d \r\n", HAL_SD_GetCardState(&hsd1));
}
else
{
uart6.printf("Erase block fail! status = %d \r\n", sdcard_status);
}
/* 读取擦除之后的数据 */
uart6.printf("------------------- Read SD card block data after Erase ------------------\r\n");
sdcard_status = HAL_SD_ReadBlocks(&hsd1, (uint8_t *)read_buf, 0, 1, 0xffff);
if(sdcard_status == HAL_OK)
{
uart6.printf("Read block data ok \r\n" );
for(int i = 0; i < 512; i++)
{
uart6.printf("0x%02x ", read_buf[i]);
if((i+1)%16 == 0)
{
uart6.printf("\r\n");
}
}
}
else
{
uart6.printf("Read block data fail! status = %d \r\n", sdcard_status);
}
uart6.printf("------------------- Over ------------------\r\n");
while (1)
{
}
}

2. SDMMC初始化函数

void MX_SDMMC1_SD_Init(void)
{
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;                                                          //上升沿
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;                              //空闲时不关闭时钟电源
hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;                                                                              //4位数据线
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;        //关闭硬件流控制
hsd1.Init.ClockDiv = 10;                                                                                                                    //分频
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
}

3. SD卡写数据块函数

HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
//*hsd:指向SD卡的指针
//*pData:指向要写入的数据的指针
//BlockAdd:数据块地址
//NumberOfBlocks:写入的块数
//Timeout:写入超时设置

4. SD读数据块函数

HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
//*hsd:指向SD卡的指针
//*pData:指向数据读取后存放区的指针
//BlockAdd:数据块地址
//NumberOfBlocks:读取的块数
//Timeout:读取超时设置

5. SDMMC外设管理结构体

typedef struct
{
SD_TypeDef *Instance;                       /*!< SDMMC 寄存器基地址*/
SD_InitTypeDef Init;                         /*!< SD 初始化结构体*/
HAL_LockTypeDef Lock;                     /*!< SD 锁资源*/
uint32_t *pTxBuffPtr;                        /*!< 存放发送数据地址的指针*/
uint32_t TxXferSize;                         /*!< 发送数据的大小 */
uint32_t *pRxBuffPtr;                        /*!< 存放接受数据地址的指针*/
uint32_t RxXferSize;                         /*!< 接受数据的大小*/
__IO uint32_t Context;                        /*!< SDMMC 的工作模式 */
__IO HAL_SD_StateTypeDef State;             /*!< SD 卡的状态值*/
__IO uint32_t ErrorCode;                      /*!< SD 错误操作返回值*/
HAL_SD_CardInfoTypeDef SdCard;             /*!< SD 卡的信息*/
uint32_t CSD[4];                             /*!< SD 卡的 CSD 寄存器值*/
uint32_t CID[4];                             /*!< SD 卡的 CID 寄存器值*/
} SD_HandleTypeDef;

6. SDMMC 数据初始化结构体

typedef struct
{
uint32_t DataTimeOut;       // 数据传输超时
uint32_t DataLength;        // 数据长度
uint32_t DataBlockSize;     // 数据块大小
uint32_t TransferDir;        // 数据传输方向
uint32_t TransferMode;      // 数据传输模式
uint32_t DPSM;            // 数据路径状态机
} SDMMC_DataInitTypeDef;

7. SD卡信息结构体

typedef struct
{
uint32_t CardType;                                /*卡种类*/
uint32_t CardVersion;                              /*卡版本*/
uint32_t Class;                                    /*卡类*/
uint32_t RelCardAdd;                              /*相对卡地址*/
uint32_t BlockNbr;                                /*以块为单位指定卡容量*/
uint32_t BlockSize;                                /*一个块大小(以字节为单位)*/
uint32_t LogBlockNbr;                             /*以块为单位指定卡逻辑容量*/
uint32_t LogBlockSize;                             /*逻辑块大小(以字节为单位)*/
uint32_t CardSpeed;                               /*卡速度*/
}HAL_SD_CardInfoTypeDef;

实验现象

我们插入SD卡,运行程序,终端显示出SD卡的相关信息,并输出写入SD卡的数据。
在这里插入图片描述

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

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

相关文章

珠海自助建站软件网站后台程序和数据库开发

现在做的是RK平台的I2C驱动,不是说linux每个外设对应一个设备文件吗?可是找了一下一直没找到,今天特别搞了一下。I2C设备是注册为platform平台驱动的。 下面是我用adb命令查看的 linux的设备文件不一定只在dev/这个目录下面,像sys/ 目录下面也会有一些设备文件的 MID下面…

unibest + uView Plus+VSCode

Node下18+VSCode 插件:uni-app-snippets Vue (Official) Vue 3 Snippets ESLint Prettier - Code formatter Path Intellisense JSON5 syntaxpnpm create unibest@latest 项目名称:wejiaui 选择模板:base-uview-pro…

企石网站建设公司制作网页一般需要兼容哪些网站

目录 1、F12 2、robots 3、game1-喂青蛙 4、game 2 - flap bird 5、game 3 - Clash 6、Get&Post 7、sql &#xff08;1&#xff09;手工注入 &#xff08;2&#xff09;工具注入 8、命令执行漏洞 9、文件上传漏洞 10、文件泄露 11、php反序列化漏洞 12、PHP绕…

详细介绍:学科竞赛管理系统|基于SpringBoot和Vue的学科竞赛管理系统(源码+数据库+文档)

详细介绍:学科竞赛管理系统|基于SpringBoot和Vue的学科竞赛管理系统(源码+数据库+文档)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important…

青岛建站seo公司无锡网站优化工作室

在 Flutter 开发中&#xff0c;加载本地 HTML 文件是一个常见的需求&#xff0c;尤其是在需要展示离线内容或自定义页面时。flutter_inappwebview 是一个功能强大的插件&#xff0c;支持加载本地文件和网络资源。本文将详细介绍如何使用 flutter_inappwebview 加载 App 本地 HT…

个人网站怎么设计seo求职信息

本文档描述了一个可扩展的独立于操作系统的软件接口,用于执行各种系统控制和管理任务,包括电源和性能管理。 本文档描述了系统控制和管理接口(SCMI),它是一组操作系统无关的软件接口,用于系统管理。SCMI 是可扩展的,目前提供了以下接口: • 支持的接口的发现和自描述…

网站建设师恩施网页定制

导语内容提要李刚、唐炜主编的《C语言程序设计立体化教程(高等教育立体化精品系列规划教材)》主要分为四篇&#xff1a;语法基础篇、程序设计结构篇、初级应用篇和高级应用篇&#xff1b;其中第一篇语法基础部分介绍了C语言概述和C语言数据与运算&#xff1b;第二篇程序设计结构…

镇江网站推广优化做饰品网站

第二篇记录下Geometry函数&#xff0c;相对于其它语言&#xff0c;Arcade对Geometry的支持是一大亮点&#xff0c;这使得它的上限被大大提高了。 三、Geometry函数 1、Angle【角度】 单位为度&#xff08;0-360&#xff09;&#xff0c;正北为90度&#xff0c;只考虑x-y平面。…

树的遍历实现

LeetCode 144. 二叉树的前序遍历 前序遍历的顺序是:根节点 → 左子树 → 右子树 import java.util.ArrayList; import java.util.List; import java.util.Stack;public class BinaryTreePreorderTraversal {public st…

张家港英文网站制作惠州做网站 百度优化

文章目录一、MySQL数据库备份单循环1. 安装mysql2. 配置mysql环境变量3. 刷新环境变量4. 创建数据库和表lue5. 脚本制作6. 运行脚本7. 查看备份的sql文件7. 脚本升级动态传参8. 运行脚本9. 查看备份的sql文件二、MySQL数据库表备份多循环2.1. 脚本制作2.2. 运行脚本2.3. 指定目…

福田区住房和建设局网站网站要实名认证

目录 1.概念2.结构3.实现4.优缺点5.使用场景6.模式扩展7.JDK 源码解析——Collection.iterator 方法 1.概念 &#xff08;1&#xff09;Java 设计模式——工厂方法模式中考虑的是一类产品的生产&#xff0c;如畜牧场只养动物、电视机厂只生产电视机等。这些工厂只生产同种类产…

企业网站在ps里做吗wordpress 点击文章图片

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天咱们要聊聊Lock Support。Lock Support是Java并发编程的一块基石&#xff0c;它提供了一种非常底层的线程阻塞和唤醒机制&#xff0c;是许多高级同步工具的基础。 为什么要关注Lock Support&#xff1f;线程…

自媒体网站源码google store

del dict[key] # 删除dict字典里的键值

题解:AT_abc311_h [ABC311Ex] Many Illumination Plans

题意:给出一棵树,每个节点有权值,重量和颜色,问对于每个子树 \(u\),选出一个包含 \(u\) 的虚树,满足重量之和 \(\le X\),相邻两个点颜色不同且权值和最大。 做法: 首先我们会一个非常平凡的 \(O(nX^2)\) 做法,…

怎么在阿里云服务器上建设网站网站数据模版

知识导航&#xff08;就问全不全&#xff09; 当学习 Vue.js 时&#xff0c;除了基本的 HTML、CSS 和 JavaScript 知识外&#xff0c;还有一些其他的技术和语法需要了解&#xff0c;例如 ES6 和 TypeScript。以下是您可能需要学习的一些基础知识和对应的学习资源&#xff0c;我…

上海网站设计图片新建网址

没有使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 树展开时&#xff1a; 树未展开时&#xff1a; 可以看到&#xff1a; 未使用Windows经典风格时&#xff0c;QTreeView或QTreeWidget…

南阳网站建设aokuo做图网站有哪些

随着人工智能的迅猛发展&#xff0c;ChatGPT作为一种强大的自然语言处理模型&#xff0c;逐渐在学术界引起了广泛的关注。本文将探讨ChatGPT在学术写作中的应用&#xff0c;并分享使用ChatGPT进行学术写作时的一些经验和心得。 01 — ChatGPT在学术写作中的应用 1.文献综述和…

淮南移动网站建设深圳网站推广优化

区域代理的保护机制&#xff1a;在链动商城系统里设定的代理有唯一性&#xff0c;每个省只有一个省代&#xff0c;每个市只有一个市代&#xff0c;每个区县只有一个区县代。这样也是保护每个代理的收益权益。 区域代理包含的权益类别&#xff1a;购物奖励折扣&#xff1b;区域实…

品牌网站建设哪里有维影企业网站管理系统

基于springboot实现酒店客房管理平台系统演示 摘 要 随着人们的物质水平的提高&#xff0c;旅游业和酒店业发展的速度越来越快。近年来&#xff0c;市面上酒店的数量和规模都在不断增加&#xff0c;如何提高酒店的管理效率和服务质量成为了一个重要的问题。伴随着信息技术的发…

易语言如何做网站钦州建设网站

题目 给定长为n(n<2e5)的1-n的排列p&#xff0c; 求(i,j)(1<i<j<n)对的数量&#xff0c;满足gcd(i,j)≠1且gcd(pi,pj)≠1 思路来源 官方题解 题解 参考莫比乌斯函数mu&#xff0c;定义一个新函数&#xff0c; 新函数需要满足n1的时候对因子求和为0&#xff0…