|
[兆易GD32H759I-EVAL]5.熟悉SDIO接口通讯,基于FatFs文件系统实现对TF卡的读写操作
[复制链接]
1.SDIO
GD32H759系列MCU带有2路SDIO接口,它定义了SD卡、 SD I/O卡和嵌入式多媒体卡(e•MMC)主机接口,提供AHB系统总线与SD存储卡、 SD I/O卡以及e•MMC设备之间的命令和数据传输。需要注意的是SDIO在同一时间仅支持一个SD、SD I/O卡或 e•MMC,但可支持多个e•MMC。
2.原理图
在运行SDIO功能程序时,需要根据原理图上的标注,将硬件上必要的跳线帽跳到正确的位置。
3.基于SD卡底层的读写操作和验证
3.1.代码实现
-
- do
- {
- sd_error = sd_io_init();
- }
- while ((SD_OK != sd_error) && (--i));
-
- if (i)
- {
- printf("\r\nCard init success!\r\n");
- }
- else
- {
- printf("\r\nCard init failed!\r\n");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
-
-
- card_info_get();
-
-
- for (i = 0; i < 512; i++)
- {
- buf_write[i] = i;
- }
-
-
- SCB_CleanInvalidateDCache_by_Addr(buf_write, 512 * 4);
-
- printf("\r\n\r\nCard test:");
-
- sd_error = sd_block_write(buf_write, 100, 512);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nBlock write fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nBlock write success!");
- }
-
- sd_error = sd_block_read(buf_read, 100, 512);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nBlock read fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nBlock read success!");
- #ifdef DATA_PRINT
- SCB_CleanInvalidateDCache_by_Addr(buf_read, 512 * 4);
- pdata = (uint8_t *)buf_read;
-
- printf("\r\n");
-
- for (i = 0; i < 128; i++)
- {
- printf(" %3d %3d %3d %3d ", *pdata, *(pdata + 1), *(pdata + 2), *(pdata + 3));
- pdata += 4;
-
- if (0 == (i + 1) % 4)
- {
- printf("\r\n");
- }
- }
- #endif /* DATA_PRINT */
- }
-
-
- state = memory_compare(buf_write, buf_read, 128);
-
- if (SUCCESS == state)
- {
- printf("\r\nSingle block read compare successfully!");
- }
- else
- {
- printf("\r\nSingle block read compare fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
-
-
- if (SD_CCC_LOCK_CARD & sd_cardinfo.card_csd.ccc)
- {
-
- sd_error = sd_lock_unlock(SD_LOCK);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nLock failed!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nThe card is locked!");
- }
-
- sd_error = sd_erase(100, 101);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nErase failed!");
- }
- else
- {
- printf("\r\nErase success!");
- }
-
-
- sd_error = sd_lock_unlock(SD_UNLOCK);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nUnlock failed!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nThe card is unlocked!");
- }
-
- sd_error = sd_erase(100, 101);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nErase failed!");
- }
- else
- {
- printf("\r\nErase success!");
- }
-
- sd_error = sd_block_read(buf_read, 100, 512);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nBlock read fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nBlock read success!");
- #ifdef DATA_PRINT
- SCB_CleanInvalidateDCache_by_Addr(buf_read, 512 * 4);
- pdata = (uint8_t *)buf_read;
-
- printf("\r\n");
-
- for (i = 0; i < 128; i++)
- {
- printf(" %3d %3d %3d %3d ", *pdata, *(pdata + 1), *(pdata + 2), *(pdata + 3));
- pdata += 4;
-
- if (0 == (i + 1) % 4)
- {
- printf("\r\n");
- }
- }
- #endif /* DATA_PRINT */
- }
- }
-
-
- sd_error = sd_multiblocks_write(buf_write, 200, 512, 3);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nMultiple block write fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nMultiple block write success!");
- }
-
- sd_error = sd_multiblocks_read(buf_read, 200, 512, 3);
-
- if (SD_OK != sd_error)
- {
- printf("\r\nMultiple block read fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
- else
- {
- printf("\r\nMultiple block read success!");
- #ifdef DATA_PRINT
- SCB_CleanInvalidateDCache_by_Addr(buf_read, 512 * 4);
- pdata = (uint8_t *)buf_read;
-
- printf("\r\n");
-
- for (i = 0; i < 512; i++)
- {
- printf(" %3d %3d %3d %3d ", *pdata, *(pdata + 1), *(pdata + 2), *(pdata + 3));
- pdata += 4;
-
- if (0 == (i + 1) % 4)
- {
- printf("\r\n");
- }
- }
- #endif /* DATA_PRINT */
- }
-
-
- state = memory_compare(buf_write, buf_read, 128 * 3);
-
- if (SUCCESS == state)
- {
- printf("\r\nMultiple block read compare successfully!");
- }
- else
- {
- printf("\r\nMultiple block read compare fail!");
-
- gd_eval_led_on(LED1);
- gd_eval_led_on(LED2);
-
- while (1)
- {
- }
- }
-
- printf("\r\nSD card test successfully!");
3.2.运行结果
4.移植FatFs文件系统及接口函数
-
-
-
-
-
-
-
-
-
- #include "ff.h" /* Obtains integer types */
- #include "diskio.h" /* Declarations of disk functions */
- #include "sdcard.h"
- #include <stdio.h>
-
-
- #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
- #define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
- #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
-
- extern sd_error_enum sd_io_init(void);
- extern void card_info_get(void);
-
-
-
-
-
- DSTATUS disk_status (
- BYTE pdrv
- )
- {
- #if 0
- DSTATUS stat;
- int result;
-
- switch (pdrv) {
- case DEV_RAM :
- result = RAM_disk_status();
-
-
-
- return stat;
-
- case DEV_MMC :
- result = MMC_disk_status();
-
-
-
- return stat;
-
- case DEV_USB :
- result = USB_disk_status();
-
-
-
- return stat;
- }
- return STA_NOINIT;
- #else
- return RES_OK;
- #endif
- }
-
-
-
-
-
-
-
- DSTATUS disk_initialize (
- BYTE pdrv
- )
- {
- #if 0
- DSTATUS stat;
- int result;
-
- switch (pdrv) {
- case DEV_RAM :
- result = RAM_disk_initialize();
-
-
-
- return stat;
-
- case DEV_MMC :
- result = MMC_disk_initialize();
-
-
-
- return stat;
-
- case DEV_USB :
- result = USB_disk_initialize();
-
-
-
- return stat;
- }
- return STA_NOINIT;
- #else
- int result, count = 5;
-
- do
- {
- result = sd_io_init();
- count -= 1;
- }
- while (SD_OK != result);
-
- if ((SD_OK == result) && (count != 0))
- {
- printf("\r\nCard init success!");
-
- card_info_get(); printf("\r\n");
-
- return RES_OK;
- }
- else
- {
- printf("\r\nCard init failed!");
-
- while (1)
- {
- }
- }
- #endif
- }
-
-
-
-
-
-
-
- DRESULT disk_read (
- BYTE pdrv,
- BYTE *buff,
- LBA_t sector,
- UINT count
- )
- {
- #if 0
- DRESULT res;
- int result;
-
- switch (pdrv) {
- case DEV_RAM :
-
-
- result = RAM_disk_read(buff, sector, count);
-
-
-
- return res;
-
- case DEV_MMC :
-
-
- result = MMC_disk_read(buff, sector, count);
-
-
-
- return res;
-
- case DEV_USB :
-
-
- result = USB_disk_read(buff, sector, count);
-
-
-
- return res;
- }
-
- return RES_PARERR;
- #else
- int result;
-
- if (count == 1)
- {
- result = sd_block_read((uint32_t *)buff, sector, 512);
- }
- else
- {
- result = sd_multiblocks_read((uint32_t *)buff, sector, 512, count);
- }
-
- if (result == SD_OK)
- {
- return RES_OK;
- }
- else
- {
- return RES_PARERR;
- }
- #endif
- }
-
-
-
-
-
-
-
- #if FF_FS_READONLY == 0
-
- DRESULT disk_write (
- BYTE pdrv,
- const BYTE *buff,
- LBA_t sector,
- UINT count
- )
- {
- #if 0
- DRESULT res;
- int result;
-
- switch (pdrv) {
- case DEV_RAM :
-
-
- result = RAM_disk_write(buff, sector, count);
-
-
-
- return res;
-
- case DEV_MMC :
-
-
- result = MMC_disk_write(buff, sector, count);
-
-
-
- return res;
-
- case DEV_USB :
-
-
- result = USB_disk_write(buff, sector, count);
-
-
-
- return res;
- }
-
- return RES_PARERR;
- #else
- int result = sd_multiblocks_write((uint32_t *)buff, sector, 512, count);
-
- if (result == SD_OK)
- {
- return RES_OK;
- }
- else
- {
- return RES_PARERR;
- }
- #endif
- }
-
- #endif
-
-
-
-
-
-
- DRESULT disk_ioctl (
- BYTE pdrv,
- BYTE cmd,
- void *buff
- )
- {
- #if 0
- DRESULT res;
- int result;
-
- switch (pdrv) {
- case DEV_RAM :
-
-
-
- return res;
-
- case DEV_MMC :
-
-
-
- return res;
-
- case DEV_USB :
-
-
-
- return res;
- }
-
- return RES_PARERR;
- #else
- switch (cmd)
- {
- case GET_SECTOR_COUNT:
- *(DWORD *)buff = sd_card_capacity_get() / 512;
- break;
-
- case GET_SECTOR_SIZE:
- *(WORD *)buff = 512;
- break;
-
- case GET_BLOCK_SIZE:
- *(DWORD *)buff = 512;
- break;
-
- default:
- break;
- }
-
- return RES_OK;
- #endif
- }
-
- DWORD get_fattime(void)
- {
- return 0;
- }
-
-
注意:diskio.c是实现FatFs文件系统与底层SDIO操作SD卡的接口文件,其中disk_read和disk_write这两个函数中的sector参数在调用sd卡底层函数时,传递的函数实参直接传递sector就可以了,不需要将sector再乘以blocksize;因为在sd卡底层操作函数中,对sd卡操作地址已经做了处理;如果这边再乘以blocksize,就会出现我在调试时遇到的挂载文件系统提示FR_NO_FILESYSTEM错误的情况。
5.FatFs功能演示
5.1.代码实现
- #include "ff.h"
- #include "diskio.h"
- #include "ffconf.h"
- #include <string.h>
-
- FATFS FatFs;
- FIL File;
- UINT br = 0, bw = 0;
- FRESULT Result;
-
- char wBuffer[] = "\r\nGD32H7xx_SDIO_TFCard_FatFs";
- char rBuffer[200];
-
- memset(rBuffer, 0, sizeof(rBuffer));
-
- Result = f_mount(&FatFs, "0:", 1);
-
- if(Result)
- {
- printf("\r\nf_mount Fail! Result = %d\r\n", Result);
- }
- else
- {
- Result = f_open(&File, "0:/HELLO.txt", FA_READ);
-
- if(Result != RES_OK)
- {
- printf("\r\nf_open HELLO.txt Fail! Result = %d\r\n", Result);
- }
- else
- {
- do
- {
- Result = f_read(&File, rBuffer, 200, &br);
-
- if(br != 0) printf("\r\nf_read : %s\r\n", rBuffer);
-
- } while(br != 0);
-
- f_close(&File);
- }
-
- Result = f_open(&File, "0:/HELLO.txt", FA_CREATE_ALWAYS | FA_WRITE);
-
- if (Result != RES_OK)
- {
- printf("\r\nf_open HELLO.txt Fail! Result = %d\r\n", Result);
- }
- else
- {
- Result = f_write(&File, wBuffer, strlen(wBuffer), &bw);
-
- if (Result != RES_OK)
- {
- printf("\r\nf_write HELLO.txt Fail! Result = %d\r\n", Result);
- }
- else
- {
- printf("\r\nf_write HELLO.txt Result = %d, bw = %d\r\n", Result, bw);
- f_sync(&File);
- }
-
- f_close(&File);
- }
- }
5.2.运行结果
6.软件工程
|
赞赏
-
1
查看全部赞赏
-
|