- #include "diskio.h"
 
- #include "sd.h"
 
- #include "malloc.h"
 
 
 
- #define SD_CARD  0  //SD卡,卷标为0
 
- #define EX_FLASH 1  //外部flash,卷标为1
 
 
- #define FLASH_SECTOR_SIZE   512
 
 
- //初始化磁盘
 
- DSTATUS disk_initialize (
 
-     BYTE pdrv               /* Physical drive nmuber (0..) */
 
- )
 
- {
 
-     u8 res=0;
 
-     switch(pdrv)
 
-     {
 
-         case SD_CARD://SD卡
 
-             res = SD_Initialize();//SD_Initialize()
 
-             if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
 
-             {
 
-                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
 
-             }
 
-             break;
 
-         case EX_FLASH://外部flash
 
-             break;
 
-         default:
 
-             res=1;
 
-     }
 
-     if(res)return  STA_NOINIT;
 
-     else return 0; //初始化成功
 
- }
 
 
- //获得磁盘状态
 
- DSTATUS disk_status (
 
-     BYTE pdrv       /* Physical drive nmuber (0..) */
 
- )
 
- {
 
-     return 0;
 
- }
 
 
- //读扇区
 
- //drv:磁盘编号0~9
 
- //*buff:数据接收缓冲首地址
 
- //sector:扇区地址
 
- //count:需要读取的扇区数
 
- DRESULT disk_read (
 
-     BYTE pdrv,      /* Physical drive nmuber (0..) */
 
-     BYTE *buff,     /* Data buffer to store read data */
 
-     DWORD sector,   /* Sector address (LBA) */
 
-     UINT count      /* Number of sectors to read (1..128) */
 
- )
 
- {
 
-     u8 res=0;
 
-     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
 
-     switch(pdrv)
 
-     {
 
-         case SD_CARD://SD卡
 
-             res=SD_ReadDisk(buff,sector,count);
 
-             if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
 
-             {
 
-                 SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
 
-             }
 
-             break;
 
-         case EX_FLASH://外部flash
 
-             res=0;
 
-             break;
 
-         default:
 
-             res=1;
 
-     }
 
-    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
 
-     if(res==0x00)return RES_OK;
 
-     else return RES_ERROR;
 
- }
 
 
- //写扇区
 
- //drv:磁盘编号0~9
 
- //*buff:发送数据首地址
 
- //sector:扇区地址
 
- //count:需要写入的扇区数
 
- #if _USE_WRITE
 
- DRESULT disk_write (
 
-     BYTE pdrv,          /* Physical drive nmuber (0..) */
 
-     const BYTE *buff,   /* Data to be written */
 
-     DWORD sector,       /* Sector address (LBA) */
 
-     UINT count          /* Number of sectors to write (1..128) */
 
- )
 
- {
 
-     u8 res=0;
 
-     if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
 
-     switch(pdrv)
 
-     {
 
-         case SD_CARD://SD卡
 
-             res=SD_WriteDisk((u8*)buff,sector,count);
 
-             break;
 
-         case EX_FLASH://外部flash
 
-             res=0;
 
-             break;
 
-         default:
 
-             res=1;
 
-     }
 
-     //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
 
-     if(res == 0x00)return RES_OK;
 
-     else return RES_ERROR;
 
- }
 
- #endif
 
 
 
- //其他表参数的获得
 
-  //drv:磁盘编号0~9
 
-  //ctrl:控制代码
 
-  //*buff:发送/接收缓冲区指针
 
- #if _USE_IOCTL
 
- DRESULT disk_ioctl (
 
-     BYTE pdrv,      /* Physical drive nmuber (0..) */
 
-     BYTE cmd,       /* Control code */
 
-     void *buff      /* Buffer to send/receive control data */
 
- )
 
- {
 
-     DRESULT res;
 
-     if(pdrv==SD_CARD)//SD卡
 
-     {
 
-         switch(cmd)
 
-         {
 
-             case CTRL_SYNC:
 
-                 SD_CS_L;
 
-                 if(SD_WaitReady()==0)res = RES_OK;
 
-                 else res = RES_ERROR;
 
-                 SD_CS_H;
 
-                 break;
 
-             case GET_SECTOR_SIZE:
 
-                 *(WORD*)buff = 512;
 
-                 res = RES_OK;
 
-                 break;
 
-             case GET_BLOCK_SIZE:
 
-                 *(WORD*)buff = 8;
 
-                 res = RES_OK;
 
-                 break;
 
-             case GET_SECTOR_COUNT:
 
-                 *(DWORD*)buff = SD_GetSectorCount();
 
-                 res = RES_OK;
 
-                 break;
 
-             default:
 
-                 res = RES_PARERR;
 
-                 break;
 
-         }
 
-     }
 
-     else res=RES_ERROR;//其他的不支持
 
-     return res;
 
- }
 
- #endif
 
- //获得时间
 
- //User defined function to give a current time to fatfs module      */
 
- //31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
 
- //15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
 
- DWORD get_fattime (void)
 
- {
 
-     return 0;
 
- }
 
diskio.c文件主要进行磁盘初始化以及进行获取磁盘状态和读写扇区等操作;
4、关于main.c文件
- /********************************** (C) COPYRIGHT *******************************
 
- * File Name          : main.c
 
- * Author             : WCH
 
- * Version            : V1.0.0
 
- * Date               : 2020/04/30
 
- * Description        : Main program body.
 
- *******************************************************************************/
 
- #include "debug.h"
 
- #include "spi.h"
 
- #include "sd.h"
 
- #include "ff.h"
 
 
 
- //定义变量
 
- FATFS fs;                     /* FatFs文件系统对象 */
 
- FIL fnew;                     /* 文件对象 */
 
- FRESULT res_sd;               /* 文件操作结果 */
 
- UINT fnum;                    /* 文件成功读写数量 */
 
- BYTE ReadBuffer[1024]={0};    /* 读缓冲区 */
 
- BYTE WriteBuffer[] =          /* 写缓冲区*/
 
- "欢迎使用沁恒CH32V103开发板,新建文件系统测试文件\r\n";
 
 
- /*******************************************************************************
 
- * Function Name  : main
 
- * Description    : Main program.
 
- * Input          : None
 
- * Return         : None
 
- *******************************************************************************/
 
- int main(void)
 
- {
 
-     u32 sd_size;
 
 
-         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 
-     Delay_Init();
 
-         USART_Printf_Init(115200);
 
 
-         printf("SystemClk:%d\r\n",SystemCoreClock);
 
-         printf("This is SD FATFS example\r\n");
 
 
-         if(SD_Detect()==0)
 
-         {
 
-             printf("未检测SD卡插入!\n");
 
-         }
 
-         else
 
-         {
 
-             printf("已检测SD卡插入!\n");
 
 
-             if(SD_Initialize())
 
-             {
 
-                 printf("SD卡初始化出错,请检查!!\n");
 
-                 Delay_Ms(500);
 
-             }
 
-             else
 
-             {
 
-                 printf("SD卡初始化完成!\n");
 
-                 sd_size=SD_GetSectorCount();//得到扇区数
 
-                 printf("SD Card Size(MB):%d\n",sd_size>>11);
 
-             }
 
-         }
 
 
-     //在外部SPI SD挂载文件系统,文件系统挂载时会对SPI设备初始化
 
-     res_sd = f_mount(&fs,"0:",1);
 
 
-     /*----------------------- 格式化测试 ---------------------------*/
 
-         /* 如果没有文件系统就格式化创建创建文件系统 */
 
-         if(res_sd == FR_NO_FILESYSTEM)
 
-         {
 
-             printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
 
-         /* 格式化 */
 
-             res_sd=f_mkfs("0:",0,0);
 
 
-             if(res_sd == FR_OK)
 
-             {
 
-                 printf("》SD卡已成功格式化文件系统。\r\n");
 
-           /* 格式化后,先取消挂载 */
 
-                 res_sd = f_mount(NULL,"0:",1);
 
-           /* 重新挂载   */
 
-                 res_sd = f_mount(&fs,"0:",1);
 
-             }
 
-             else
 
-             {
 
-                 printf("《《格式化失败。》》res_sd =%d\r\n",res_sd);
 
-                 while(1);
 
-             }
 
-         }
 
-       else if(res_sd!=FR_OK)
 
-       {
 
-         printf("!!SD卡挂载文件系统失败。(%d)\r\n",res_sd);
 
-         printf("!!可能原因:SD卡初始化不成功。\r\n");
 
-             while(1);
 
-       }
 
-       else
 
-       {
 
-         printf("》文件系统挂载成功,可以进行读写测试\r\n");
 
-       }
 
-         /*----------------------- 文件系统测试:写测试 -----------------------------*/
 
-             /* 打开文件,如果文件不存在则创建它 */
 
-             printf("\r\n****** 即将进行文件写入测试... ******\r\n");
 
-             res_sd = f_open(&fnew, "0:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
 
-             if ( res_sd == FR_OK )
 
-             {
 
-                 printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");
 
-             /* 将指定存储区内容写入到文件内 */
 
-                 res_sd=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);
 
-             if(res_sd==FR_OK)
 
-             {
 
-               printf("》文件写入成功,写入字节数据:%d\n",fnum);
 
-               printf("》向文件写入的数据为:\r\n%s\r\n",WriteBuffer);
 
-             }
 
-             else
 
-             {
 
-               printf("!!文件写入失败:(%d)\n",res_sd);
 
-             }
 
-                 /* 不再读写,关闭文件 */
 
-             f_close(&fnew);
 
-             }
 
-             else
 
-             {
 
-                 printf("!!打开/创建文件失败。\r\n");
 
-             }
 
 
-         while(1)
 
-     {
 
-         }
 
- }
 
 
4、下载验证
将编译好的程序下载到开发板并复位,当未插入SD卡时,串口打印情况具体如下:
 
插入SD卡并复位后,串口打印情况如下:
