STM32+HAL:SDIO+DMA模式读写SD卡详解
创作时间:
作者:
@小白创作中心
STM32+HAL:SDIO+DMA模式读写SD卡详解
引用
CSDN
1.
https://blog.csdn.net/m0_60372743/article/details/138328162
一、准备工作
有关CUBEMX的初始化配置,参见相关文档。
二、所用工具
- 芯片:STM32F407ZGT6
- IDE:MDK-Keil软件
- 库文件:STM32F4xxHAL库
三、实现功能
实现用SDIO+DMA读写SD卡内容
四、HAL库配置
- 开启SDIO
- 模式配置为1bit,开启DMA传输,开启中断
- Clock transition on which the bit capture is made(时钟跳变沿捕获数据配置):数据捕获边沿设置,可设置为上升沿/下降沿
- SDIO Clock divider bypass(时钟分频器旁路使能):使能该参数时,SDIO_CLK=SDIOCLK;否则SDIO_CLK频率由时钟分频因子决定
- SDIO Clock output enable when the bus is idle(空闲模式时钟输出使能):节能模式,此实验不使能
- SDIO hardware flow control(硬件流控):设置是否使能SDIO的硬件流控,此处不使能
- SDIOCLK clock divide factor(时钟分频因子):当不使能时钟分频器旁路时,SDIO_CLK=SDIOCLK / (2+时钟分频因子)
- 开启串口通信
至此,HAL库配置完毕
五、Keil填写代码
- SD.h
#ifndef __SD_H__
#define __SD_H__
#include "sdio.h"
#include "stdio.h"
void SDCard_TestRead(void);
void SDCard_TestWrite(void);
void SDCard_ShowInfo(void);
void SDCard_EraseBlocks(uint8_t BlockAddrStart,uint8_t BlockAddrEnd);
void SDCard_Write_DMA(uint8_t *TX, uint32_t BlockCount, uint32_t BlockAddr);
void SDCard_Read_DMA(uint8_t *RX,uint32_t BlockCount,uint32_t BlockAddr);
#endif
- SD.c
篇幅有限,仅提供SD.c核心代码
/**
* @brief SD卡DMA写入函数
* @param uint8_t *TX: 写入数据数组(若要存入负数,需提前加一个数值,典型值为127,此时数据范围为-127 ~ 128)
* @param BlockCount: 写入的总片数
* @param BlockAddr: 起始写入的片数
*/
void SDCard_Write_DMA(uint8_t *TX, uint32_t BlockCount, uint32_t BlockAddr)
{
HAL_SD_WriteBlocks_DMA(&hsd, TX, BlockAddr, BlockCount); //存入TX数组数据到sd卡
}
/**
* @brief SD卡DMA读取函数
* @param uint8_t *RX: 读取数据数组(若已存入负数,需在打印时减一个数值,典型值为127,此时数据范围为-127 ~ 128)
* @param BlockCount: 读取的总片数
* @param BlockAddr: 起始读取的片数
*/
void SDCard_Read_DMA(uint8_t *RX, uint32_t BlockCount, uint32_t BlockAddr)
{
HAL_SD_ReadBlocks_DMA(&hsd, RX, BlockAddr, BlockCount); //读取sd卡数据到RX数组
}
/**
* @brief SD卡擦除函数
* @param BlockAddrStart: 擦除开始块数
* @param BlockAddrEnd: 擦除结束块数
*/
void SDCard_EraseBlocks(uint8_t BlockAddrStart,uint8_t BlockAddrEnd)
{
printf("\r\n*** Erasing blocks ***\r\n");
if(HAL_SD_Erase(&hsd, BlockAddrStart, BlockAddrEnd)==HAL_OK) //擦除数据
printf("Erasing blocks,OK\r\n");
else
printf("Erasing blocks,fail\r\n");
HAL_SD_CardStateTypeDef cardState=HAL_SD_GetCardState(&hsd);
printf("GetCardState()= %d\r\n", cardState); //打印当前sd卡数据状态
while(cardState != HAL_SD_CARD_TRANSFER)
{
HAL_Delay(1);
cardState=HAL_SD_GetCardState(&hsd);
}
printf("Blocks %d-%d is erased.\r\n",BlockAddrStart, BlockAddrEnd);
}
- main.c
uint8_t rx[BLOCKSIZE],tx[BLOCKSIZE];
/* USER CODE BEGIN 2 */
printf("Hello World\r\n");
HAL_Delay(500);
SDCard_Write_DMA(tx,1,6);
HAL_Delay(500);
SDCard_Read_DMA(rx,1,6);
HAL_Delay(500);
SDCard_EraseBlocks(0,10);
/* USER CODE END 2 */
六、巨人之肩
- 【STM32+HAL】利用SDIO将大量数据存入SD卡,并根据需要读出
- STM32CubeMX教程27 SDIO - 读写SD卡
七、源码提供
资源【STM32+HAL】SDIO+DMA模式读写SD卡
八、更多DMA应用
详见【STM32+HAL】DMA应用
九、结语
本文介绍了使用STM32F407ZGT6芯片通过MDK-Keil软件和STM32F4xxHAL库实现SD卡读写的具体步骤,包括HAL库配置、代码实现等,并提供了核心代码示例。希望对从事嵌入式系统开发的工程师有所帮助。
热门推荐
Type-C与雷电接口:一文读懂两者本质区别
适合不同肤质的平价身体乳推荐指南
如何应对论文查重?10个实用策略助你提升学术写作
保险丝是过载保护还是短路保护?短路保护和过载保护有什么区别?
解读“药品追溯码”,合理用药更安心
目标实施过程管控流程怎么设计才能确保高效执行?
馆陶崖柏:兼具药用价值与科研意义的珍贵植物
西安电子科技大学和西南交通大学哪个好?谁实力强
从购物到旅游,消费体验大升级,这些亮点不容错过!
广西八条精品旅游线路,邂逅不一样的冬日暖阳
薰衣草:爱情与幸运的芬芳使者
5天3板!金价不断创新高,这家A股公司最新公告!
女性最大的聪明:自知
HTML表格边框颜色调整完全指南:从基础到进阶
中国中铁三所研究机构落地雄安新区
深入解析DPU:AI时代的芯片分工与超级网卡
癌症家庭中的亲人同样需要关怀和支持!
什么是血液病?减少接触致病诱因,预防血液病
让实验动物科技为科学进步开启无限可能
守护实验动物伦理:科研与人性的平衡之道
黑茶的奥秘:发酵过程中的微生物奇迹
终于知道绿茶、黄茶、红茶、黑茶、乌龙,白茶,花茶之间的区别了
宝宝何时开始自主如厕?家长应该怎么教?收下这份指南
锆板的主要特性及应用领域
睡眠呼吸暂停综合征的症状与治疗方法
猪肝是碳水还是蛋白质?一文详解猪肝的营养成分与食用指南
数字人交互案例怎么写
卖港口受挫,长和欲拆分最赚钱业务在英国上市?李嘉诚这次失算了
富血小板血浆(PRP),血液“自救”到底有多神奇?
带泥的皮蛋怎么剥皮?皮蛋能直接剥皮吃吗?