【STM32】检测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操作,导致错误 。
NVIC

编写代码

显示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();
    }
  }
}

实现的效果

实现的效果

如果对你有帮助,点个赞吧 ^ ^!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值