【STM32】检测SD卡是否插入
- 开发环境
- 原理图
- 确定引脚的高低电平
- 中断方式检测插入
- 配置引脚
- 打开引脚的中断
- 编写代码
- 显示SD卡信息
- 引脚中断回调函数
- 实现的效果
开发环境
软件:STM32CubeIDE1.14.1
硬件:立创天空星STM32F407VE;SD卡
原理图
要确认TF卡槽的9脚SD_DECT (自行确认具体的引脚)是否连接了
比如下图的就连上了PD3
下面的这个就没有连接,无法检测。
确定引脚的高低电平
SD插入后引脚为低电平,没插入为高电平。如果不知道怎么检测,有如下方法
把PD3(检测引脚)设为输入模式,然后不断检测引脚的电平。插拔几次,看串口输出的电平即可确认。
知道SD卡检测引脚的电平后,就可以检测SD卡的状态了 。
GPIO_PinState SD_insert
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
SD_insert = HAL_GPIO_ReadPin(SD_DECT_GPIO_Port, SD_DECT_Pin);
printf("sd:%d\n", SD_insert);
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(1000);
中断方式检测插入
如果喜欢,可以轮询检测引脚的状态,也即上面提到的检测电平的方法,不过这样效率太低,可以改用中断的方式。
配置引脚
配置引脚为外部中断,选择上升下降沿触发外部中断,这样插入和拔出都能检测
打开引脚的中断
注意这个中断优先级应该比SDIO的中断要高,不然拔出了还在进行SDIO操作,导致错误 。
编写代码
显示SD卡信息
先写一个能显示SD卡信息的函数,在插入时显示卡的信息。
void SD_Getinfo(void)
{
printf("SD_Getinfo\n");
HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&hsd);
HAL_SD_CardCIDTypeDef SD_CardCID;
if (state == HAL_SD_CARD_TRANSFER)
{
HAL_SD_GetCardCID(&hsd, &SD_CardCID);
printf("\nInitialize SD card sucessfully!\n");
printf("SD card information\n");
printf("CardType :%ld\n", hsd.SdCard.CardType);
printf("CardVersion :%ld\n", hsd.SdCard.CardVersion);
printf("Class :%ld\n", hsd.SdCard.Class);
printf("RelCardAdd :%ld\n", hsd.SdCard.RelCardAdd);
printf("BlockNbr :%ld\n", hsd.SdCard.BlockNbr);
printf("BlockSize :%ld\n", hsd.SdCard.BlockSize);
printf("LogBlockNbr :%ld\n", hsd.SdCard.LogBlockNbr);
printf("LogBlockSize :%ld\n", hsd.SdCard.LogBlockSize);
printf("ManufacturerID :%d\n", SD_CardCID.ManufacturerID);
}
else
{
printf("SD card initialize failed.\n");
}
}
引脚中断回调函数
开启中断后,需要编写GPIO中断回调函数。插入时调用 MX_SDIO_Init(); 初始化SDIO,然后显示SD卡的信息。
拔出时复位SDIO HAL_SD_DeInit(&hsd); 再显示会提示没有初始化。
由于插拔过程电平是不稳定的,类似按键的抖动,因此需要消抖。
这里为了简单,直接用HAL延时。实际应用自行查找更好的消抖方法
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_Delay(30);
if (GPIO_Pin == SD_DECT_Pin)
{
/* in = 0 */
if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(SD_DECT_GPIO_Port, SD_DECT_Pin))
{
printf("SD in\n");
MX_SDIO_SD_Init();
printf("SD init\n");
SD_Getinfo();
}
/* out = 1 */
else
{
printf("SD out\n");
HAL_SD_DeInit(&hsd);
printf("SD deinit\n");
SD_Getinfo();
}
}
}
实现的效果
如果对你有帮助,点个赞吧 ^ ^!