Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
BSP
SD卡热插拔检测在STM32上的具体实现
发布于 2019-06-12 23:04:35 浏览:8648
订阅该版
* 本帖最后由 WillianChan 于 2019-6-13 11:04 编辑 * 我这个SD卡的热插拔功能是基于“... t-thread\bsp\stm32\stm32f469-st-disco”开发板制作的,为什么选择这款开发板制作SD卡的热插拔,请听我慢慢道来。 昨天,看到RT-Thread的GitHub上有个issue,[https://github.com/RT-Thread/rt-thread/issues/2747](https://github.com/RT-Thread/rt-thread/issues/2747),描述如图1: [align=center]![4.png](/uploads/201906/13/104555wc9x99x97q79i9rq.png)[align=center]图1 issue 于是乎萌生出解决它的想法,想到就去做了。 我的思路很简单,通过检测SD卡的check pin脚的电平边沿变化来检测SD卡时候插入和拔出。不过这个思路是有局限性的,因为有些板子的check pin是悬空的,并没有接在stm32的任何脚上,这种情况下,使用上面所述的方法进行热插拔检测就不可行了。比方说,野火的F429挑战者开发板,它的SD卡的check pin就是悬空的,如图2所示: [align=center]![2.png](/uploads/201906/12/181715kah81pdn0zrrtzdz.png)[align=center]图2 野火挑战者板子的SD卡原理图 刚好,ST官方的F469-DISCO开发板的check pin是接到PG2上的,可用上述方法实现热插拔,如图3所示: [align=center]![3.png](/uploads/201906/12/181918lsnbon4wnqro1tf0.png)[align=center]图3 ST-F469-DISCO板子的SD卡原理图 废话不多说,先把代码po上来,代码如下。代码量不多,不到100行,我已经在RT-Thread的GitHub上提交PR了,请看:[https://github.com/RT-Thread/rt-thread/blob/master/bsp/stm32/stm32f469-st-disco/board/ports/drv_sdcard.c](https://github.com/RT-Thread/rt-thread/blob/master/bsp/stm32/stm32f469-st-disco/board/ports/drv_sdcard.c) [align=center]代码1 ```#include
#ifdef BSP_USING_SDCARD #include
#include
#include
#include "drv_gpio.h" #include "drv_sdio.h" #define DBG_TAG "app.card" #define DBG_LVL DBG_INFO #include
/* SD Card hot plug detection pin */ #define SD_CHECK_PIN GET_PIN(G, 2) static void _sdcard_mount(void) { rt_device_t device; device = rt_device_find("sd0"); if (device == NULL) { mmcsd_wait_cd_changed(0); stm32_mmcsd_change(); mmcsd_wait_cd_changed(RT_WAITING_FOREVER); device = rt_device_find("sd0"); } if (device != RT_NULL) { if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK) { LOG_I("sd card mount to '/'"); } else { LOG_W("sd card mount to '/' failed!"); } } } static void _sdcard_unmount(void) { rt_thread_mdelay(200); dfs_unmount("/"); LOG_I("Unmount \"/\""); mmcsd_wait_cd_changed(0); stm32_mmcsd_change(); mmcsd_wait_cd_changed(RT_WAITING_FOREVER); } static void sd_mount(void *parameter) { rt_uint8_t re_sd_check = 1; while (1) { rt_thread_mdelay(200); if(re_sd_check && !rt_pin_read(SD_CHECK_PIN)) { _sdcard_mount(); } if (!re_sd_check && rt_pin_read(SD_CHECK_PIN)) { _sdcard_unmount(); } re_sd_check = rt_pin_read(SD_CHECK_PIN); } } int stm32_sdcard_mount(void) { rt_thread_t tid; rt_pin_mode(SD_CHECK_PIN, PIN_MODE_INPUT_PULLUP); tid = rt_thread_create("sd_mount", sd_mount, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX - 1, 20); if (tid != RT_NULL) { rt_thread_startup(tid); } else { LOG_E("create sd_mount thread err!"); } return RT_EOK; } INIT_APP_EXPORT(stm32_sdcard_mount); #endif /* BSP_USING_SDCARD */``` 上面的代码中最关键的代码是54行~71行,也就是“static void sd_mount(void *parameter)”这个线程入口函数。 这里解读一下这个函数,这个函数读懂了,热插拔检测思路就清楚了: 1、首先,对于ST-F469-DISCO这个板子,当SD卡插进去的时候,check pin是低电平,不插的时候check pin是高电平,这一点可以通过观察图3得知。 2、在这段代码里,SD卡热插拔检测放在了一个线程入口函数里面去执行,通过高低电平的边沿检测来实现热插拔检测,“rt_uint8_t re_sd_check = 1”的作用是为了让SD卡在未上电的时候已经插进去了这种情况下制造电平边沿用的。因为如果SD卡一直插着,是没有电平变化的,“rt_uint8_t re_sd_check = 1”就是为了手动制造一个电平变化出来。否则无法通过if语言的电平边沿检测,也就是说无法执行“_sdcard_mount()”。需要注意的是,这段代码中的两个if语句之后都会跟着一个“re_sd_check = rt_pin_read(SD_CHECK_PIN)”去记录上次的的电平值。 3、在上电后SD卡拔出的这种情况下,电平变化是从低电平跳变至高电平,此时第二个if语句“!re_sd_check && rt_pin_read(SD_CHECK_PIN)”为真,执行“_sdcard_unmount()”。 4、在上电后SD卡插进卡槽的这种情况下,电平变化是从高电平跳变至于低电平,此时第一个if语句“re_sd_check && !rt_pin_read(SD_CHECK_PIN)”为真,执行“_sdcard_mount()”。 5、没有第五点了,说完了。这就是原理。 热插拔检测原理说完了,理解清楚的话,_sdcard_unmount()和_sdcard_mount()就更好理解了,这两部分这里不作解释,各位自行读代码吧。 我们来看看热插拔检测的结果吧。 SD卡不插,板子上电,msh输出的只有RTT版本号: [align=center]![3.png](/uploads/201906/13/104213tu9k99swaaup6wkk.png)[align=center]图4 SD卡不插 SD卡未上电的时候就一直插着的,板子上电之后,msh输出信息如下: [align=center]![8(JYNB4@~8R_X8VN8A6R67Q.png](/uploads/201906/12/231525lf2rzvs8zvyuh8ht.png)[align=center]图5 SD卡插着上电 SD卡连续插拔,msh输出信息如下: [align=center]![EFDA)T$DL$50SF$I8@$~06J.png](/uploads/201906/12/231736vlkweam6emfss60r.png)[align=center]图6 插拔插拔插拔... SD卡拔出来之后,在msh上输入list_device查看已注册设备,并没有sd0,如图7所示: [align=center]![[]OUWDI1`11`C4FA04U9761.png](/uploads/201906/12/232021xzu46uc4145649yx.png)[align=center]图7 没有sd0 SD卡插进去之后,在msh上输入list_device查看已注册设备,sd0出来了,如图8所示: [align=center]![@XJP$TKF0K~$L(BEO1ZB[~T.png](/uploads/201906/12/232021nrpudc3u3lpgql34.png)[align=center]图8 sd0已注册 真是有趣,因吹斯听hhhhhhh... lol
查看更多
18
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2019-06-13
开源,分享,交流,共同进步
厉害,厉害
WillianChan
2019-06-13
-
>厉害,厉害 --- 牛刀小试,如有漏洞欢迎指出:lol
zhangjun
2019-06-13
这家伙很懒,什么也没写!
支持,楼主好厉害
flyboy
2019-06-13
Do my self();
因垂丝汀
WillianChan
2019-06-13
-
>支持,楼主好厉害 --- 谢谢支持:lol
word天
2019-06-13
这家伙很懒,什么也没写!
期待楼主更多大作
whj467467222
认证专家
2019-06-14
开源,分享,交流,共同进步
>牛刀小试,如有漏洞欢迎指出 --- ``` static void sd_mount(void *parameter) { rt_uint8_t re_sd_check = 1; while (1) { rt_thread_mdelay(200); if(re_sd_check && !rt_pin_read(SD_CHECK_PIN)) { _sdcard_mount(); } if (!re_sd_check && rt_pin_read(SD_CHECK_PIN)) { _sdcard_unmount(); } re_sd_check = rt_pin_read(SD_CHECK_PIN); } } ``` 如果在re_sd_check = rt_pin_read(SD_CHECK_PIN);时候读取到卡插入,卡插入是低电平。 ``` rt_thread_mdelay(200); if( 0 && 1 ) { _sdcard_mount(); } if ( 1 && 0 ) { _sdcard_unmount(); } 0 = rt_pin_read(SD_CHECK_PIN); ```
WillianChan
2019-06-14
-
>如果在re_sd_check = rt_pin_read(SD_CHECK_PIN);时候读取到卡插入,卡插入是低电平。 --- 谢谢指出:lol,确实会有这种可能性发生,不过发生得概率很低。这个BUG后期会更进修复:lol,敬请期待:handshake
WillianChan
2019-06-15
-
>如果在re_sd_check = rt_pin_read(SD_CHECK_PIN);时候读取到卡插入,卡插入是低电平。 --- BUG已修复,详情请看我的pr:[https://github.com/RT-Thread/rt-thread/pull/2779](https://github.com/RT-Thread/rt-thread/pull/2779) ``` static void sd_mount(void *parameter) { rt_uint8_t re_sd_check_pin = 1; while (1) { rt_thread_mdelay(200); if(re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) == 0) { _sdcard_mount(); } if (!re_sd_check_pin && (re_sd_check_pin = rt_pin_read(SD_CHECK_PIN)) != 0) { _sdcard_unmount(); } } } ``` 如还有其他漏洞,欢迎指出:lol
whj467467222
认证专家
2019-06-15
开源,分享,交流,共同进步
>BUG已修复,详情请看我的pr:https://github.com/RT-Thread/rt-thread/pull/2779 --- ``` static void sd_mount(void *parameter) { rt_uint8_t re_sd_check = 1; while (1) { rt_thread_mdelay(200); if(re_sd_check && !rt_pin_read(SD_CHECK_PIN)) { _sdcard_mount(); } if (!re_sd_check && rt_pin_read(SD_CHECK_PIN)) { _sdcard_unmount(); } re_sd_check = rt_pin_read(SD_CHECK_PIN); } } ``` 去掉代码中的re_sd_check = rt_pin_read(SD_CHECK_PIN);,应该就解决了啊。不知道这么操作有什么弊端
撰写答案
登录
注册新账号
关注者
2
被浏览
8.6k
关于作者
WillianChan
-
提问
6
回答
284
被采纳
8
关注TA
发私信
相关问题
1
STM32 407 串口接收数据 系统卡死
2
RTT nrf24l01 设备驱动程序
3
stm32f10x串口只能发送数据,无法接收
4
第一次尝试移植rt-thread 到stm32F103系列问题
5
有人把stm32L07xx的bsp移到rtt上来了吗?求一个
6
rt-thread线程调度异常在stm32f103芯片上
7
RTT是否支持STM32F429
8
请问谁有 STM32F40x HAL + RT-THREAD 模板
9
rt-thread在stm32f411下的移植问题
10
针对STM32F7系列平台的MPU,Cache特性,需要注意哪些问题?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部