STM32F750vbt6首次上电无法写入SD卡需复位才正常问题咨询
问题原因
首次上电写卡失败、RST复位后正常,核心是时序和配置问题,和SD卡本身的工作特性直接相关:
- 冷启动时SD卡未就绪:SD卡规范明确要求,供电电压升到额定值后,卡内部需要至少1ms的上电复位时间,大容量卡、工业级卡通常需要10~50ms才能进入可响应命令的状态,同时接口需要输出至少74个时钟周期完成同步。你的代码在系统时钟配置完成后立刻执行SDMMC初始化,冷启动阶段SD卡还没完成自身复位,
MX_SDMMC1_SD_Init()直接执行失败,retSD变量为非0值,后续整个写文件的判断分支直接被跳过,自然不会有内容写入。而按RST引脚复位时,仅复位STM32芯片,SD卡供电全程没有中断,早就处于就绪状态,单片机重新跑初始化时可以直接和SD卡通信,所以操作成功。 - FatFs挂载参数配置错误:
f_mount接口第三个参数传0代表启用延迟挂载,不会在调用f_mount时实际执行文件系统挂载,要等第一次文件读写操作才会触发挂载,这种模式在卡刚处于就绪临界状态时很容易挂载失败。 - 代码鲁棒性不足:所有FatFs操作都没做返回值校验,
f_write、f_close执行失败完全无感知,而且写完文件立刻调用FATFS_UnLinkDriver,很容易出现文件系统缓存还没完全写入SD卡就断开驱动的问题,会导致文件损坏甚至卡内文件系统错误。 - 额外笔误:while循环里的LED闪烁代码写错了引脚,两次操作分别对应LED1和LED2,正常闪烁应该操作同一个IO口。
修复方法
按以下步骤修改即可解决:
- 在SDMMC初始化前增加冷启动延时,同时加入初始化重试逻辑,兼容不同SD卡的上电速度差异:
// 系统时钟、GPIO初始化完成后,先等待SD卡上电稳定 HAL_Delay(200); uint8_t sd_init_retry = 0; retSD = 1; // 先标记初始化失败 // 最多重试10次SD卡初始化 while(sd_init_retry < 10) { if(HAL_SD_Init(&hsd1) == HAL_OK) // 对应SDMMC1初始化,和原MX_SDMMC1_SD_Init逻辑一致 { retSD = 0; break; } sd_init_retry++; HAL_Delay(50); }
- 修改f_mount参数为1,强制立即挂载文件系统,不要用延迟挂载,同时给所有FatFs操作加返回值校验,确保写操作、关文件、缓存刷写全部完成后再卸载驱动、取消链接,参考逻辑如下:
if(retSD == 0) { FRESULT res; // 第三个参数改为1,立即挂载 res = f_mount(&SDFatFs, (TCHAR const*)SDPath, 1); if(res == FR_OK) { res = f_open(&MyFile, "file.txt", FA_CREATE_ALWAYS | FA_WRITE); if(res == FR_OK) { uint32_t byteswritten = 0; res = f_write(&MyFile, wtext, sizeof(wtext), (void*)&byteswritten); // 校验写结果,确保所有内容都写入 if(res == FR_OK && byteswritten == sizeof(wtext)) { f_close(&MyFile); // 所有操作完成、缓存刷写完毕后再卸载、取消驱动链接 f_mount(NULL, (TCHAR const*)SDPath, 0); FATFS_UnLinkDriver(SDPath); } else { f_close(&MyFile); // 写失败处理,可自行加错误指示逻辑 } } } }
- 硬件排查:确认SD卡CMD、D0~D3引脚的10K上拉电阻焊接正常,SD卡供电引脚的100nF去耦电容贴装到位,避免冷启动时供电跌落导致SD卡初始化异常。
- 修正while循环里的LED笔误:原代码两次IO操作分别写了LED1、LED2两个引脚,改为操作同一个LED引脚即可实现正常闪烁。
内容的提问来源于stack exchange,提问作者yaser kh
相关产品推荐
相关产品推荐

