STM32存储左右互搏 SDIO总线读写SD/MicroSD/TF卡

STM32存储左右互搏 SDIO总线读写SD/MicroSD/TF卡

SD/MicroSD/TF卡是基于FLASH的一种常见非易失存储单元,由接口协议电路和FLASH构成。市面上由不同尺寸和不同容量的卡,手机领域用的TF卡实际就是MicroSD卡,尺寸比SD卡小,而电路和协议操作则是一样。这里介绍STM32CUBEIDE开发平台HAL库SDIO总线操作SD/MicroSD/TF卡的例程。

SD/MicroSD/TF卡访问接口

SD/MicroSD/TF卡可以通过访问更快的SDIO专用协议接口或是访问慢一些的普通SPI接口进行操作,两种协议接口复用管脚。通过SDIO访问的接口连接方式如下:
在这里插入图片描述
其中CMD连接用于指示发送的是命令还是数据。CLK提供访问同步时钟,4根数据线(DATA0 ~ DATA3 )则实现信息双向传输。
SDIO可以操作在1bit数据线和4bit数据线模式,因为4bit数据线明显效率高于1bit数据线模式,所以1bit数据线模式很少用,只有在某种极限节省连接资源的情况下可以用1bit数据线模式,在1bit模式下,数据线DATA0用来传输数据,DATA1用作中断。在4bit数据线模式下,数据线DATA0~DATA3用于传输数据,其中DATA1复用作中断线。

例程采用STM32F103VET6芯片对4GB的TF卡进行操作,TF卡也可以插入转换卡套插入SD卡接口。

STM32工程配置

首先建立基本工程并设置时钟:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置SDIO接口:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
配置使用DMA, 优先级可以根据需要调整:
在这里插入图片描述
配置UART1作为控制和打印输出接口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存并生成初始工程代码:
在这里插入图片描述

STM32工程代码

UART串口printf打印输出实现参考:STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)

对SD/MicroSD/TF卡的SDIO接口操作可以调用HAL库函数进行,代码实现在main.c文件里,实现如下功能:

  1. 串口收到0x01指令,查询SD/MicroSD/TF卡容量等信息
  2. 串口收到0x02指令,执行特定区域(块0)的擦除
  3. 串口收到0x03指令,阻塞模式执行写操作
  4. 串口收到0x04指令,阻塞模式执行读操作
  5. 串口收到0x05指令,中断模式执行写操作
  6. 串口收到0x06指令,中断模式执行读操作
  7. 串口收到0x07指令,DMA模式执行写操作
  8. 串口收到0x08指令,DMA模式执行读操作

完整的main.c代码如下:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
#include "usart.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{__IO uint32_t firstms, secondms;__IO uint32_t counter = 0;firstms = HAL_GetTick()+1;secondms = firstms+1;while(uwTick!=firstms) ;while(uwTick!=secondms) counter++;usDelayBase = ((float)counter)/1000;
}void PY_Delay_us_t(uint32_t Delay)
{__IO uint32_t delayReg;__IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);delayReg = 0;while(delayReg!=usNum) delayReg++;
}void PY_usDelayOptimize(void)
{__IO uint32_t firstms, secondms;__IO float coe = 1.0;firstms = HAL_GetTick();PY_Delay_us_t(1000000) ;secondms = HAL_GetTick();coe = ((float)1000)/(secondms-firstms);usDelayBase = coe*usDelayBase;
}void PY_Delay_us(uint32_t Delay)
{__IO uint32_t delayReg;__IO uint32_t msNum = Delay/1000;__IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);if(msNum>0) HAL_Delay(msNum);delayReg = 0;while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
//#define BLOCKSIZE   512U /*!< Block size is 512 bytes */
#define BLOCK_START_ADDR 0 /* Block start address */
#define NUM_OF_BLOCKS 1 /* Total number of blocks */
#define BUFFER_WORDS_SIZE ((BLOCKSIZE * NUM_OF_BLOCKS) >> 2) /* Total data size in bytes *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
DMA_HandleTypeDef hdma_sdio;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV */
uint8_t uart1_rxd[256];
uint8_t uart1_txd[256];
uint8_t cmd;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t SD_Buffer_Tx[512] = {0} ;
uint8_t SD_Buffer_Rx[512] = {0};uint32_t SD_Status = 0;
uint32_t SD_Rx_Int = 0;
uint32_t SD_Tx_Int = 0;void SD_DMA_INIT_M2P(SD_HandleTypeDef* hsd) //DMA init: memory --> peripheral
{HAL_DMA_DeInit(&hdma_sdio);/* SDIO DMA Init *//* SDIO Init */hdma_sdio.Instance = DMA2_Channel4;hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;hdma_sdio.Init.Mode = DMA_NORMAL;hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;if (HAL_DMA_Init(&hdma_sdio) != HAL_OK){Error_Handler();}/* Several peripheral DMA handle pointers point to the same DMA handle.Be aware that there is only one channel to perform all the requested DMAs. *//* Be sure to change transfer direction before callingHAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */__HAL_LINKDMA(hsd,hdmarx,hdma_sdio);__HAL_LINKDMA(hsd,hdmatx,hdma_sdio);
}void SD_DMA_INIT_P2M(SD_HandleTypeDef* hsd) //DMA init: memory <-- peripheral
{HAL_DMA_DeInit(&hdma_sdio);/* SDIO DMA Init *//* SDIO Init */hdma_sdio.Instance = DMA2_Channel4;hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;hdma_sdio.Init.Mode = DMA_NORMAL;hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;if (HAL_DMA_Init(&hdma_sdio) != HAL_OK){Error_Handler();}/* Several peripheral DMA handle pointers point to the same DMA handle.Be aware that there is only one channel to perform all the requested DMAs. *//* Be sure to change transfer direction before callingHAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */__HAL_LINKDMA(hsd,hdmarx,hdma_sdio);__HAL_LINKDMA(hsd,hdmatx,hdma_sdio);
}
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_SDIO_SD_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */PY_usDelayTest();PY_usDelayOptimize();HAL_UART_Receive_IT(&huart1, uart1_rxd, 1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/*HAL_SD_CARD_TRANSFER is the operate correct and complete status for SD card operation*/if(cmd==0x01) //Get SD card information{cmd = 0;printf("\r\n SD card test...\r\n");if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER) //Get SD card resource info{printf("\r\n Initialize SD card successful!\r\n");printf(" SD card information↓ \r\n");printf(" Card Capacity : %llu \r\n", (unsigned long long)hsd.SdCard.BlockSize * hsd.SdCard.BlockNbr);printf(" One block size in bytes : %d \r\n", (int)hsd.SdCard.BlockSize);printf(" Logical Capacity in blocks : %d \r\n", (int)hsd.SdCard.LogBlockNbr);printf(" Logical block size in bytes : %d \r\n", (int)hsd.SdCard.LogBlockSize);printf(" Relative Card Address : %d \r\n", (int)hsd.SdCard.RelCardAdd);printf(" Card Type  : %d \r\n", (int)hsd.SdCard.CardType);HAL_SD_CardCIDTypeDef sdcard_cid;HAL_SD_GetCardCID(&hsd,&sdcard_cid); //Get SD card vendor infoprintf(" Manufacturer ID: %d \r\n", (int)sdcard_cid.ManufacturerID);}else{printf("\r\n SD card initiation failed!\r\n" );}}else if(cmd==0x02) //Erase SD card block{cmd = 0;printf("\r\n------------------- Block Erase -------------------------------\r\n");if(HAL_SD_Erase(&hsd, BLOCK_START_ADDR, NUM_OF_BLOCKS) == HAL_OK) //Erase block operation{while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) PY_Delay_us_t(10);printf("\r\n Erase Block Successful!\r\n");}else{printf("\r\n Erase Block Failed!\r\n");}}else if(cmd==0x03) //SD card write in block mode{cmd = 0;memset(SD_Buffer_Tx, 0xAA, sizeof(SD_Buffer_Tx)); //0xAA written into buffer for this testprintf("\r\n------------------- Write SD card block data in block mode ------------------\r\n");__disable_irq();SD_Status = HAL_SD_WriteBlocks(&hsd, SD_Buffer_Tx, BLOCK_START_ADDR, NUM_OF_BLOCKS, 0xFFFFFFFF); //Write block operation in block modeif(SD_Status==HAL_OK){while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) PY_Delay_us_t(10); //Wait for write endprintf("\r\n Write block data in block mode successful!\r\n");}else{printf("\r\n Write block data in block mode failed!\r\n");}__enable_irq();}else if(cmd==0x04) //SD card read in block mode{cmd = 0;printf("\r\n------------------- Read SD card block data in block mode ------------------\r\n");__disable_irq();SD_Status = HAL_SD_ReadBlocks(&hsd, SD_Buffer_Rx, BLOCK_START_ADDR, NUM_OF_BLOCKS, 0xFFFFFFFF); //read block operation in block modeif( SD_Status== HAL_OK){while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) PY_Delay_us_t(10); //Wait for read endprintf("\r\n Read block data in block mode successful!\r\n");for(uint32_t i = 0; i < sizeof(SD_Buffer_Rx); i++){printf("0x%02x:%02x ", (unsigned int)i, (unsigned int)SD_Buffer_Rx[i]);}printf("\r\n");}else{printf("\r\n Read block data in block mode failed!\r\n");}__enable_irq();}else if(cmd==0x05) //SD card write in INT mode{cmd = 0;memset(SD_Buffer_Tx, 0x55, sizeof(SD_Buffer_Tx)); //0x55 written into buffer for this testprintf("\r\n------------------- Write SD card block data in INT mode ------------------\r\n");SD_Tx_Int = 1;SD_Status = HAL_SD_WriteBlocks_IT(&hsd, SD_Buffer_Tx, BLOCK_START_ADDR, NUM_OF_BLOCKS); //write block operation in INT modeif(SD_Status== HAL_OK){while(SD_Tx_Int==1) PY_Delay_us_t(1); //Wait for write endprintf("\r\n Write block data in INT mode successful!\r\n");}else{printf("\r\n Write block data in INT mode failed!\r\n");}}else if(cmd==0x06) //SD card read in INT mode{cmd = 0;printf("\r\n------------------- Read SD card block data in INT mode ------------------\r\n");SD_Rx_Int = 1;SD_Status = HAL_SD_ReadBlocks_IT(&hsd, SD_Buffer_Rx, BLOCK_START_ADDR, NUM_OF_BLOCKS); //read block operation in INT modeif( SD_Status== HAL_OK){while(SD_Rx_Int==1) PY_Delay_us_t(1); //Wait for read endprintf("\r\n Read block data in INT mode successful!\r\n");for(uint32_t i = 0; i < sizeof(SD_Buffer_Rx); i++){printf("0x%02x:%02x ", (unsigned int)i, (unsigned int)SD_Buffer_Rx[i]);}printf("\r\n");}else{printf("\r\n Read block data in INT mode failed!\r\n");}}else if(cmd==0x07) //SD card write in DMA mode{cmd = 0;SD_DMA_INIT_M2P(&hsd); //Switch DMA mode directionmemset(SD_Buffer_Tx, 0x5A, sizeof(SD_Buffer_Tx)); //0x5A written into buffer for this testprintf("\r\n------------------- Write SD card block data in DMA mode ------------------\r\n");SD_Tx_Int = 1;SD_Status = HAL_SD_WriteBlocks_DMA(&hsd, SD_Buffer_Tx, BLOCK_START_ADDR, NUM_OF_BLOCKS); //write block operation in DMA modeif(SD_Status== HAL_OK){while(SD_Tx_Int==1) PY_Delay_us_t(1); //Wait for write endprintf("\r\n Write block data in DMA mode successful!\r\n");}else{printf("\r\n Write block data in DMA mode failed!\r\n");}}else if(cmd==0x08) //SD card read in DMA mode{cmd = 0;SD_DMA_INIT_P2M(&hsd); //Switch DMA mode directionprintf("\r\n------------------- Read SD card block data in DMA mode ------------------\r\n");SD_Rx_Int = 1;SD_Status = HAL_SD_ReadBlocks_DMA(&hsd, SD_Buffer_Rx, BLOCK_START_ADDR, NUM_OF_BLOCKS); //read block operation in DMA modeif( SD_Status== HAL_OK){while(SD_Rx_Int==1) PY_Delay_us_t(1); //Wait for read endprintf("\r\n Read block data in DMA mode successful!\r\n");for(uint32_t i = 0; i < sizeof(SD_Buffer_Rx); i++){printf("0x%02x:%02x ", (unsigned int)i, (unsigned int)SD_Buffer_Rx[i]);}printf("\r\n");}else{printf("\r\n Read block data in DMA mode failed!\r\n");}}else;/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/*** @brief SDIO Initialization Function* @param None* @retval None*/
static void MX_SDIO_SD_Init(void)
{/* USER CODE BEGIN SDIO_Init 0 *//* USER CODE END SDIO_Init 0 *//* USER CODE BEGIN SDIO_Init 1 *//* USER CODE END SDIO_Init 1 */hsd.Instance = SDIO;hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;hsd.Init.BusWide = SDIO_BUS_WIDE_1B;hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;hsd.Init.ClockDiv = 6;if (HAL_SD_Init(&hsd) != HAL_OK){Error_Handler();}if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK){Error_Handler();}/* USER CODE BEGIN SDIO_Init 2 *//* USER CODE END SDIO_Init 2 */}/*** @brief USART1 Initialization Function* @param None* @retval None*/
static void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}/*** Enable DMA controller clock*/
static void MX_DMA_Init(void)
{/* DMA controller clock enable */__HAL_RCC_DMA2_CLK_ENABLE();/* DMA interrupt init *//* DMA2_Channel4_5_IRQn interrupt configuration */HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 0);HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);}/*** @brief GPIO Initialization Function* @param None* @retval None*/
static void MX_GPIO_Init(void)
{/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();}/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart==&huart1){cmd = uart1_rxd[0];HAL_UART_Receive_IT(&huart1, uart1_rxd, 1);}
}void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{SD_Tx_Int = 0;
}void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{SD_Rx_Int = 0;
}
/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

STM32例程测试

串口指令0x01测试效果如下:
在这里插入图片描述
串口指令0x02测试效果如下:
在这里插入图片描述
串口指令0x03测试效果如下:
在这里插入图片描述
串口指令0x04测试效果如下:
在这里插入图片描述
串口指令0x05测试效果如下:
在这里插入图片描述
串口指令0x06测试效果如下:
在这里插入图片描述
串口指令0x07测试效果如下:
在这里插入图片描述
串口指令0x08测试效果如下:
在这里插入图片描述

STM32例程下载

STM32F103VET6 SDIO总线读写SD/MicroSD/TF卡例程下载

–End–

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

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

相关文章

基于Java SpringBoot+Vue的体育用品库存管理系统

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

力扣739. 每日温度

Problem: 739. 每日温度 文章目录 题目描述思路复杂度Code 题目描述 思路 若本题目使用暴力法则会超时&#xff0c;故而使用单调栈解决&#xff1a; 1.创建结果数组res&#xff0c;和单调栈stack&#xff1b; 2.循环遍历数组temperatures&#xff1a; 2.1.若当stack不为空同时…

【C语言】扫雷【附源码】

一、扫雷游戏规则 尽快找到雷区中的所有不是地雷的格子,而不许踩到地雷。点开的数字是几&#xff0c;则说明该数字旁边的8个位置中有几个雷&#xff0c;如果挖开的是地雷&#xff0c;则会输掉游戏。 二、代码思路&#xff1a; 宏定义&#xff1a; Row 和 Col 定义了棋盘的行数和…

计算机研究生规划

一、计算机研究生技术栈 两条腿走路: 左侧工程实践能力&#xff1a;要掌握python编程语言&#xff0c;它和机器学习、神经网络&#xff08;这两门几乎是必须掌握的技能&#xff09;的学习有很大关系 右侧学术创新能力 二、编程语言能力提升 左边基础&#xff0c;右边教你写…

在ubuntu系统上安装ffmpeg支持rrweb使用rrvideo对视频文件转mp4格式遇到的一些问题及解决办法

在ubuntu系统上安装ffmpeg支持rrweb使用rrvideo对视频文件转mp4格式遇到的一些问题及解决办法 1,ubuntu系统上安装ffmpeg4.4.1稳定版本1,ubuntu系统上安装ffmpeg4.4.1稳定版本 按照ChatGPT3.5来 sudo apt updatesudo apt install build-essential git sudo apt-get instal…

上传应用程序到苹果应用商店的工具和要点

引言 在今天的移动应用市场中&#xff0c;将应用程序上传到苹果应用商店&#xff08;App Store&#xff09;是许多开发者的首要任务之一。然而&#xff0c;不同操作系统下的开发者可能需要使用不同的工具和遵循不同的要求来完成这一任务。本文将介绍在 macOS、Windows 和 Linu…

蓝桥杯算法题:练功

【问题描述】 小明每天都要练功&#xff0c;练功中的重要一项是梅花桩。 小明练功的梅花桩排列成 n 行 m 列&#xff0c;相邻两行的距离为 1&#xff0c;相邻两列的距离也为 1。 小明站在第 1 行第 1 列上&#xff0c;他要走到第 n 行第 m 列上。小明已经练了一段时间&#xff…

OpenHarmony实战:瑞芯微RK3566移植案例(下)

OpenHarmony实战&#xff1a;瑞芯微RK3566移植案例&#xff08;下&#xff09; OpenHarmony实战&#xff1a;瑞芯微RK3566移植案例&#xff08;中&#xff09; WIFI 整改思路及实现流程 整改思路 接下来熟悉HCS文件的格式以及"HDF WIFI”核心驱动框架的代码启动初始化…

大话设计模式——11.桥接模式(Bridge Pattern)

简介 将抽象部分与它的实现部分分离&#xff0c;使它们可以独立变化。 UML图&#xff1a; 应用场景&#xff1a; 系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性不想使用继承导致系统类的个数急剧增加某个类存在多个变化维度使用继承方式容易出现类的膨胀 示例…

Windows编译运行TensorRT-YOLOv9 (C++)

Windows编译运行yolov9-bytetrack-tensorrt&#xff08;C&#xff09; 1 基础环境2 编译yolov9-bytetrack-tensorrt&#xff08;1&#xff09;下载yolov9-bytetrack-tensorrt源码&#xff08;2&#xff09;修改CMakeLists.txt&#xff08;3&#xff09;CMake编译 3 yolov9模型转…

python+appium调@pytest.mark.parametrize返回missing 1 required positional argument:

出错描述&#xff1a; 1、在做pythonappium自动化测试时&#xff0c;使用装饰器pytest.mark.parametrize&#xff08;“参数”&#xff0c;[值1&#xff0c;值2&#xff0c;值3]&#xff09;&#xff0c;测试脚本执行返回test_xx() missing 1 required positional argument:“…

【数据结构与算法】:归并排序和计数排序

1. 归并排序 归并排序是一种效率仅次于快速排序的排序算法。它有非递归和递归两种实现方式(本文只讲述递归实现&#xff0c;非递归实现以后有专门的文章)。 其实&#xff0c;归并排序也叫外排序。它不仅可以对内存中的数据进行排序&#xff0c;还能对文件里的数据排序。 比如&…

革新铁路安全管理,RFID电子锁技术提升效率与防护

一、铁路行业的现状与挑战 铁路行业作为全球重要的交通基础设施&#xff0c;承担着庞大的客运和货运任务。随着铁路网络的不断扩张&#xff0c;如何确保铁路资产的安全、提高运营效率、降低维护成本&#xff0c;成为行业面临的主要挑战。传统的铁路资产管理依赖于人工巡检和记…

colmap安装问题汇总

问题目录 问题0、没有root权限怎么安装colmap&#xff1f; 问题1、ERROR: SiftGPU not fully supported/Could not connect to any X display 问题2、Cannot specify include directories for imported target "freeimage::FreeImage". 问题3、could not find ZL4 问…

【GEE】遥感数据趋势分析Sen+mk

Map.centerObject(table);// 定义时间范围 var stary 2001, endy 2023; //NDVI图像集合 var NDVICL ee.ImageCollection(ee.List.sequence(stary, endy).map(function(year) {// 定义每年的开始和结束日期var startd ee.Date.fromYMD(year, 1, 1);var endd ee.Date.fromYM…

精益管理培训在哪些行业比较适用?

在当今瞬息万变的市场环境中&#xff0c;企业竞争日趋激烈&#xff0c;如何提升内部管理水平、降低成本、提高效率&#xff0c;成为企业持续发展的关键。精益管理作为一种先进的管理理念和方法&#xff0c;正逐渐被越来越多的行业所采纳和应用。本文&#xff08;深圳天行健精益…

【Vue】响应式原理与ref

首先讲讲JS中的Proxy JavaScript 运行环境包含了一些不可枚举、不可写入的对象属性&#xff0c;然而在 ES5 之前开发者无法定义他们自己的不可枚举属性或不可写入属性。ES5 引入 Object.defineProperty() 方法以便开发者在这方面能够像 JS 引擎那样做。 ES6 为了让开发者能进…

【C语言】:字符函数和字符串函数

这里写目录标题 1、strlen的使用和模拟实现2、strcpy的使用和模拟3、strcat 的使用和模拟实现4、strcmp 的使用和模拟实现5、strncpy 函数的使用6、strncat 函数的使用7、strncmp函数的使用8、strstr 的使用和模拟实现9、strtok 函数的使用10、strerror 函数的使用11、字符分类…

C语言——关于指针运算的例题分析

1.指针运算中关于 sizeof 和 strlen 的例题分析 1. sizeof(数组名)&#xff0c;这⾥的数组名表⽰整个数组&#xff0c;计算的是整个数组的⼤⼩。 2. &数组名&#xff0c;这⾥的数组名表⽰整个数组&#xff0c;取出的是整个数组的地址。 3. 除此之外所有的数组名都表⽰…

汇编入门--基础知识(1)

1.汇编语言的概念 汇编语言是一种低级编程语言&#xff0c;它与计算机的机器语言非常接近&#xff0c;但比机器语言更易于人类阅读和理解。汇编语言是用一系列的助记符来表示机器语言的操作码和操作数。每种计算机体系结构&#xff08;如x86、ARM等&#xff09;都有自己的汇编语…