感觉在F7上尽是些比较复杂的东西了。
板载一个TF卡接口,忍不住就塞了块TF卡进去,得配置一下。以前看别人的教程,光一个SD卡驱动流程就晕了,但总得试一下。实际上如果使用HAL库的话,驱动流程要简单得多。
- uint8_t BSP_SD_Init(void)
- {
- uint8_t sd_state = MSD_OK;
-
- /* uSD device interface configuration */
- uSdHandle.Instance = SDMMC1;
- uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
- uSdHandle.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
- uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
- uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_1B;
- uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
- uSdHandle.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV;
-
- /* Msp SD Detect pin initialization */
- BSP_SD_Detect_MspInit(&uSdHandle, NULL);
- if(BSP_SD_IsDetected() != SD_PRESENT) /* Check if SD card is present */
- {
- return MSD_ERROR_SD_NOT_PRESENT;
- }
-
- /* Msp SD initialization */
- BSP_SD_MspInit(&uSdHandle, NULL);
- /* HAL SD initialization */
- if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
- {
- sd_state = MSD_ERROR;
- }
-
- /* Configure SD Bus width */
- if(sd_state == MSD_OK)
- {
- /* Enable wide operation */
- if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_4B) != SD_OK)
- {
- sd_state = MSD_ERROR;
- }
- else
- {
- sd_state = MSD_OK;
- }
- }
-
- return sd_state;
- }
复制代码 这是从官方例程里截取的驱动SD卡的代码片段,实际上并不怎么复杂。主要的工作流程
- 设置SD接口的基本参数
- BSP_SD_IsDetected()检测TF卡是否插上
- 初始化SD相关的GPIO
- HAL_SD_Init(&uSdHandle, &uSdCardInfo) 初始化SD
- 将总线宽度设置为4
重头戏在第4步,也就是传统意义上的SD外设驱动过程,仔细一看,原来这个调用的是库函数!ST把初始化工作都作完了,你就调用就行,有没欢喜得晕过去!
当然泼冷水的来了,这样子不利于理解外设的工作原理,其实只要你真想了解SD驱动原理,把这个函数反复啃上八遍,不就理解了么?关键还是你自己的态度,哈哈。
代码就不上了,自己用CUBEMX创建一个工程,设置好参数,好好研究吧。
这样子驱动的TF卡停留在底层,要想像在电脑上一样访问TF卡的内容,得另外一个组件:FATFS。
FATFS就是一个文件系统,配置好后,使用FOPEN, FREAD类的函数就可以访问SD卡上的内容,实际上FATFS是一个硬件无关组件,配置好底层的驱动,可以驱动USB、SPI FLASH等许多存储设备。
HAL做了大量的工作,帮助我们更好的使用FATFS。
首先在工程里面添加FATFS组件,最简单的办法就是将FATFS整个拷到目标工程下面,然后将相应的支持文件加入到工程当中。
这些都是要加入到工程中必不可少的文件。
注意最后面的那个文件sd_diskio.c,这个文件就是FATFS与SD接口的桥梁,FATFS执行读写操作,实际上要调用SD的读写函数,下面以读操作为例,
接着看
disk是一个结构体变量,其定义如下
其中的Diskio_drvTypeDef结构定义如下
将SD卡的读写与FATFS的读写连接到一起的是下面这个定义
这样,一个f_read操作就被链接到了SD_Read操作,下面就是SD_Read的代码,可以看到该函数执行SD的块读写操作。
嗯,有点乱,该好好捋一捋思路了!
下面是做实验的结果,将点阵字库放到SD卡上,读写点阵字库输出的效果!
|