用 STM32CubeMX 快速生成一个 SD 卡读写程序
前提:默认已经装好 MDK V5 和 STM32CubeMX。
硬件平台: STM32F4xx 系列,并通过 SDIO 连接 SD 卡。
Step1.新建工程
选择芯片型号。
Step2.配置时钟引脚
Step3.配置 SDIO 为 SD 4bit 宽度总线
Step4.配置时钟树, SDIO 模块输入要求为 48MHz 时钟
Step5.配置 SDIO 时钟分频系数 CLKDIV。计算公式为 SDIO_CK = 48MHz/(CLKDIV+2)
如下图, CLKDIV=2,则 SDIO 时钟 SDIO_CK=48MHz/(2+2)=12MHz。
Step6.使用 DMA 传输
Step7.使能 SDIO 中断
Step8.配置 NVIC
注意,此处要求 SDIO 中断优先级必须高于 DMA2 stream3 和 DMA2 stream6 的中断优先级。
因此,将 DMA2 stream3 和 DMA2 stream6 的中断优先级都将为 2(或者更低)。
Step9. 生成 MDK 工程及代码
特别注意,一定要加大堆栈大小,默认的堆栈大小有可能不够用。
Step10.打开 MDK 工程
Step11.选择芯片型号
第10、11步会出现在你你的keil没有固件包的情况下,如果你的keil已经有了估计包就不会出现了。
Step12.编译工程
Step13.添加代码
在 main.c 文件添加一个变量和一个数组定义。
在 main 函数的 while(1)中循环读取 SD 卡扇区的代码,如下图。
其中, HAL_SD_ReadBlocks_DMA()函数可在 stm32f4xx_hal_sd.h 找到其原型,在 stm32f4xx_hal_sd.c 找到其实现。
Step14.再编译下载运行程序
用 J-Link 仿真调试,在 MDK 中观察 ReadAddr 和 dat_buf[]的值, dat_buf[]中的数据就是 SD卡上 ReadAddr 为起始地址的一个扇区的数据
观察结构体变量 SDCardInfo,会发现 SD 卡的容量、卡类型等基本信息都已经被包含其中。
我使用的是 8GB 的 SD 卡, SDCardInfo. CardCapacity=0x1d2400000,即约 7.28GB。
由于本程序是直接操作 SD 卡的物理扇区,而直接写物理扇区可能会破坏 SD 卡原有的文件
系统,所以代码中没有进行写操作的演示。有兴趣的朋友可自己实验,但要提前备份 SD 卡内的文件。