在线时间102 小时
UID3338547
注册时间2017-1-28
NXP金币49
TA的每日心情 | 无聊 2021-12-29 19:06 |
---|
签到天数: 47 天 [LV.5]常住居民I
金牌会员
- 积分
- 1371
- 最后登录
- 2024-3-21
|
本帖最后由 day_day 于 2020-3-12 21:45 编辑
(一)SDK
SDK加入:
Drivers-sdif
Middleware-file system-fatfs+sd+ram
Middleware-memories-common+sd
(二)引脚配置
(三)时钟
时钟绝对不可以使用pll1_clk,也不能是从这个时钟来的其他分支,比如main_clk如果是从pll1_clk来的同样不能用。这个时钟坑过我一次,无论如何都无法驱动!
(四)移植sdmmc
移植工作可以直接从例程中拷过来,例程中的sdmmc-port文件夹直接整个靠到自己生成的工程下。
(五)设置fatfs为sd卡器件
SDK导入完毕后,source里面有一个ffconf.h文件
将
#define RAM_DISK_ENABLE
改为
#define SD_DISK_ENABLE
(六)头文件
- #include "fsl_sd.h"
- #include "fsl_sd_disk.h"
- #include "ffconf.h"
- #include "ff.h"
- #include "diskio.h"
复制代码
(七)全局变量
- static status_t sdcardWaitCardInsert(void);
- static const sdmmchost_detect_card_t s_sdCardDetect = {
- .cdType = BOARD_SD_DETECT_TYPE,
- .cdTimeOut_ms = (~0U),
- };
复制代码
(八)检测SD卡并上电
- static status_t sdcardWaitCardInsert(void)
- {
- /* Save host information. */
- g_sd.host.base = SD_HOST_BASEADDR;
- g_sd.host.sourceClock_Hz = SD_HOST_CLK_FREQ;
- /* card detect type */
- g_sd.usrParam.cd = &s_sdCardDetect;
- /* SD host init function */
- if (SD_HostInit(&g_sd) != kStatus_Success)
- {
- PRINTF("\r\nSD host init fail\r\n");
- return kStatus_Fail;
- }
- /* power off card */
- SD_PowerOffCard(g_sd.host.base, g_sd.usrParam.pwr);
- /* wait card insert */
- if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdCardDetect, true) == kStatus_Success)
- {
- PRINTF("\r\nCard inserted.\r\n");
- /* power on the card */
- SD_PowerOnCard(g_sd.host.base, g_sd.usrParam.pwr);
- }
- else
- {
- PRINTF("\r\nCard detect fail.\r\n");
- return kStatus_Fail;
- }
- return kStatus_Success;
- }
复制代码 Main函数里面:
- //insert tf car
- while (sdcardWaitCardInsert() != kStatus_Success){
- PRINTF("\r\nPlease insert a card into board.\r\n");
- SysTick_DelayTicks(1000);
- }
复制代码
(九)驱动代码
- //value
- static FATFS g_fileSystem;
- static FIL g_fileObject;
- const TCHAR driverNumberBuffer[3U] = {SDDISK + '0', ':', '/'};
- BYTE work[FF_MAX_SS];
- //mount
- if (f_mount(&g_fileSystem, driverNumberBuffer, 0U))
- {
- PRINTF("Mount volume failed.\r\n");
- while(1);
- }
- //chdrive
- if(f_chdrive((char const *)&driverNumberBuffer[0U]))
- {
- PRINTF("Change drive(f_chdrive) failed.\r\n");
- while(1);
- }
- //make fs
- if (f_mkfs(driverNumberBuffer, FM_ANY, 0U, work, sizeof work))
- {
- PRINTF("Make file system failed.\r\n");
- while(1);
- }
- //mkdir
- FRESULT error = f_mkdir(_T("/dir_1"));
- if (error)
- {
- if (error == FR_EXIST)
- {
- PRINTF("Directory exists.\r\n");
- }
- else
- {
- PRINTF("Make directory failed.\r\n");
- return -1;
- }
- }
- else
- PRINTF("Make directory success.\r\n");
复制代码
可以看到tf卡里面多了个dir_1文件夹
(十)注意
1-不能在中断里面读写
官方移植的FATFS读写接口有个BUGsdmmc-port中的fsl_sdmmc_event.c文件里面有个 SDMMCEVENT_Wait 函数,这个函数等待是采用计数的方式实现。但这个计数依靠systick中断服务函数周期地自增。如果默认没有配置systick拥有更高的抢断优先级的话,一旦在任意中断服务函数里面读写tf卡都会导致卡死。
应尽量避免在中断服务函数里面读写fatfs;或者设置中断优先级;或者优化代码,采用轮询读取
不过从软件架构的角度来说,在中断这种暂时性强的时期做大量的读写任务也并不明智。可以通过标志位来指示主循环处理tf卡和fatfs的读写任务。
2-绝对不能用PLL1向SDIO提供时钟
PLL1 到 MAIN_CLK 再到SDIO也不行,fatfs读写会莫名没有响应
工程:
LPC55S69_Project_tf.zip
(1.22 MB, 下载次数: 211)
|
|