硬汉嵌入式论坛

 找回密码
 立即注册
查看: 9384|回复: 5
收起左侧

[有问必答] stm32F407的sd卡拔出后,需要做什么处理吗?

[复制链接]

45

主题

70

回帖

205

积分

高级会员

积分
205
发表于 2020-12-26 16:11:25 | 显示全部楼层 |阅读模式
如题,参考了一些历程,有点糊涂。SD卡的热插拔,除了f_mount,加载 卸载文件系统,插上时,重新初始化sd卡,那拔出SD卡,对SD要怎么处理,比如SD_PowerOFF,停止SD时钟,关闭DMA之类的。我看其他工程好像都没有对SD卡做处理啊。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2020-12-28 08:02:28 | 显示全部楼层
参考我V6的综合Demo设计

底层实现Init和Uinit,然后应该程序处理:

【安富莱】F429开发板RTOS+emWin+FS+TCP/IP+USB+CAN+Modbus综合Demo已发布(2017-03-21)
https://forum.anfulai.cn/forum.p ... 7330&fromuid=58
(出处: 硬汉嵌入式论坛)



  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: AppTaskPinDetect
  4. *        功能说明: 主要实现SD卡插拔检测
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *   优 先 级: 12
  8. *********************************************************************************************************
  9. */
  10. __task void AppTaskPinDetect(void)
  11. {
  12.         OS_RESULT xResult;
  13.         const uint16_t usMaxBlockTime = 0xFFFF; /* 设置无限等待 */
  14.        
  15.         /* 无限等待,直到GUI的状态栏对话框已经创建 */
  16.         if(os_evt_wait_or(GUIDetectBIT_15, usMaxBlockTime) == OS_R_EVT){}
  17.        
  18.         /*
  19.                 检测上电前SD卡是否已经插入,这种情况是无法通过中断引脚检测出来,
  20.             因为没有上升沿或者下降沿的跳变。SD插入是低电平,拔出是高电平。
  21.                 PE2
  22.         */
  23.         if(!(GPIOE->IDR & (1 << 2)))
  24.         {
  25.                 os_evt_set(SDDetectBIT_0, os_tsk_self());
  26.         }
  27.                
  28.     while(1)
  29.     {
  30.                 /*
  31.                         1. 无限等待SD卡插拔状态变化。
  32.                     2. 无限等待网线插拔状态变化,暂未放在这个任务实现。
  33.                 */
  34.                 if(os_evt_wait_or(PinDetect_ALL, usMaxBlockTime) == OS_R_EVT)
  35.                 {
  36.                         xResult = os_evt_get ();
  37.                
  38.                         switch (xResult)
  39.                         {
  40.                                 case SDDetectBIT_0:
  41.                                     /* 设置一段延迟时间,滤除插拔SD卡时造成的抖动, 拔出过程误差较大,这里等待100ms再检测 */
  42.                                         os_dly_wait(100);
  43.                                         if((GPIOE->IDR & (1 << 2)))
  44.                                         {
  45.                                                 UnmountSD(); /* 卸载SD卡 */
  46.                                                 WM_SendMessageNoPara(hWinStatus, MSG_SDPlugOut);
  47.                                         }
  48.                                         else
  49.                                         {
  50.                                                 MountSD();  /* 挂载SD卡 */
  51.                                                 WM_SendMessageNoPara(hWinStatus, MSG_SDPlugIn);
  52.                                         }
  53.                                         EXTI->IMR |= (1<<2); /* 使能中断  */
  54.                                         break;
  55.                                        
  56.                                 /* 其他值不处理 */
  57.                                 default:                     
  58.                                         break;
  59.                         }       
  60.                 }
  61.     }
  62. }
复制代码


回复

使用道具 举报

45

主题

70

回帖

205

积分

高级会员

积分
205
 楼主| 发表于 2020-12-28 11:30:28 | 显示全部楼层
eric2013 发表于 2020-12-28 08:02
参考我V6的综合Demo设计

底层实现Init和Uinit,然后应该程序处理:

/*
*********************************************************************************************************
*        函 数 名: UnmountSD
*        功能说明: 卸载SD卡
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void UnmountSD(void)
{
        uint8_t result;

        /* 卸载SD卡 */
        result = funinit("M0:");
        if(result != NULL)
        {
                printf_libdbg("卸载文件系统失败\r\n");
        }
        else
        {
                printf_libdbg("卸载文件系统成功\r\n");
        }
}
funinit来源于FS_CM3.Lib,没办法在查找了,也不了解FS。看到这个结构体,
/* MCI Device Driver Control Block */
MCI_DRV __DRV_ID = {
  Init,
  UnInit,
  Delay,
  BusMode,
  BusWidth,
  BusSpeed,
  Command,
  ReadBlock,
  WriteBlock,
  SetDma,
  CheckMedia                            /* Can be NULL if not existing        */
};
加载时调用Init,那么卸载时要调用UnInit?
回复

使用道具 举报

45

主题

70

回帖

205

积分

高级会员

积分
205
 楼主| 发表于 2020-12-28 13:45:28 | 显示全部楼层
eric2013 发表于 2020-12-28 08:02
参考我V6的综合Demo设计

底层实现Init和Uinit,然后应该程序处理:

我是这么做的 裸机程序 200ms执行一次

void sd_mount(void)
{
        static uint8_t re_sd_check_pin = 0;
        static uint8_t is_ok = 0;
       
        if(is_ok == 0)              //上电首次
        {
                if (GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) == Bit_RESET) //第一次上电 就插着SD卡
                {
                        _sdcard_mount();
                        is_ok = 1;                       
                }
        }
        else                        
        {
                if (re_sd_check_pin && (re_sd_check_pin = GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN)) == 0)
        {
            _sdcard_mount();
        }

        if (!re_sd_check_pin && (re_sd_check_pin = GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN)) == 1)
        {
            _sdcard_unmount();
        }
        }
}
/**
  * @brief  卸载SD卡
  * @retval
  */
static void _sdcard_unmount(void)
{
        /* 卸载文件系统 */
        f_mount(FS_SD, RT_NULL);
        SD_LowLevel_DeInit();
        LOG_I("Unmount \"0:/\"\r");
}
static void _sdcard_mount(void)
{
        if(elm_mount(FS_SD, &gfs) == FR_OK)        /* Mount a logical drive */
        {
                LOG_I("sd card mounted!\r");
        }
        else
        {
                LOG_E("sd card mount failed!\r");
        }
}
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2020-12-29 09:16:55 | 显示全部楼层
chinashaoshu 发表于 2020-12-28 11:30
/*
********************************************************************************************** ...

对,自动调用的。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2020-12-29 09:17:20 | 显示全部楼层
chinashaoshu 发表于 2020-12-28 13:45
我是这么做的 裸机程序 200ms执行一次

void sd_mount(void)

注意去抖,很重要。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-16 15:40 , Processed in 0.037955 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表