GD32F30x移植FatFs文件系统到单片机

一、工具

1、硬件:GD32F30x系列单片机

2、编译环境:KEIL

3、Flash芯片:GD25Q256DF

二、移植FatFs文件系统到单片机

关于外部Flash的驱动程序,请看链接:https://www.cnblogs.com/wenhao-Web/p/14052266.html

关于USB设备模式下把外部Flash模拟成U盘的程序,请看链接:https://www.cnblogs.com/wenhao-Web/p/14052863.html

1、找到官方提供的固件库中的FatFs文件夹,整体拷贝到自己工程中,如下图所示:

2、打开自己的工程,创建一个“Fatfs”文件夹并添加上面拷贝的文件夹的部分文件,如下图所示:

ff.c文件包含了FatFs文件系统的整个核心内容,包含了操作文件系统的功能函数,不用修改;

fattime.c文件是用于获取当前的时间的,该时间用于设定文件的创建或修改时间,有需求的可以进去添加获取实时时间的操作;

diskio.c文件属于接口文件,用于和底层读写函数进行衔接的地方,是移植Fatfs文件系统重点修改的地方;

ccsbcs.c文件用于不同编码的转换,不用修改;

ffconf.h文件是FatFs文件系统的配置文件,用户可根据需求对文件系统进行配置,也是移植Fatfs文件系统重点修改的地方。

3、修改diskio.c文件

这三个宏定义代表着三个不同的设备,我只用一个,故删掉。

修改初始化设备函数,我要放在外面进行初始化,这里就默认初始化成功,如下所示:

/*-----------------------------------------------------------------------*//* Inicializes a Drive                                                    */DSTATUS disk_initialize (BYTE drv)    /* Physical drive nmuber (0..) */{   DSTATUS stat = STA_NOINIT;        stat &= ~STA_NOINIT;  return stat;  }

修改获取状态函数,通过读取外部Flash的ID判断其状态,因为只有一个设备,设备号可以不用管,如下所示:

/*-----------------------------------------------------------------------*//* Return Disk Status                                                    */DSTATUS disk_status (     BYTE drv        /* Physical drive nmuber (0..) */) {     DSTATUS stat;if(gd25q256df_read_id() == 0xC84019)     {         stat = RES_OK;     }else{         stat = RES_ERROR;     }return stat; }

修改磁盘读函数,因为只有一个设备,设备号可以不用管,如下所示:

/*-----------------------------------------------------------------------*//* Read Sector(s)                                                        */DRESULT disk_read (     BYTE drv,        /* Physical drive nmuber (0..) */BYTE *buff,        /* Data buffer to store read data */DWORD sector,    /* Sector address (LBA) */BYTE count        /* Number of sectors to read (1..255) */) {     DRESULT res;     gd25q256df_read_data(buff, sector*512, count*512);     res = RES_OK;return res; }

修改磁盘写函数,因为只有一个设备,设备号可以不用管,如下所示:

/*-----------------------------------------------------------------------*//* Write Sector(s)                                                       */#if _READONLY == 0 DRESULT disk_write (     BYTE drv,            /* Physical drive nmuber (0..) */const BYTE *buff,    /* Data to be written */DWORD sector,        /* Sector address (LBA) */BYTE count            /* Number of sectors to write (1..255) */) {     DRESULT res;          gd25q256df_write_data(buff, sector*512, count*512);          res = RES_OK;return res; }

修改磁盘I/O控制函数,因为只有一个设备,设备号可以不用管,如下所示:

/*-----------------------------------------------------------------------*//* Miscellaneous Functions                                               */DRESULT disk_ioctl (     BYTE drv,        /* Physical drive nmuber (0..) */BYTE ctrl,        /* Control code */void *buff        /* Buffer to send/receive control data */) {   DRESULT res;  switch(ctrl)   {      case GET_SECTOR_COUNT:           *(DWORD *)buff = 65536;          break;      case GET_SECTOR_SIZE:           *(WORD *)buff = 512;          break;      case GET_BLOCK_SIZE:          /* 暂时未用 */  break;   }   res = RES_OK;  return res; }

4、文件系统读写测试

相关变量定义

uint32_t flash_id; FATFS fs; FIL file; FRESULT res_flash; uint8_t g_TestBuf1[] = "12345hello world 今天是个好日子,123456\r\n"; uint8_t g_TestBuf2[] = "hello world\r\n"; uint8_t g_ReadBuf[128]; uint32_t bw;

主函数中实现文件的创建和读取,验证FatFs移植是否成功

/*!     \brief      main function     \param[in]  none     \param[out] none     \retval     none*/int main(void) {/* configure 4 bits pre-emption priority */nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);          bsp_spi1_init();     gd25q256df_init();              flash_id = gd25q256df_read_id();if(flash_id == 0xC84019)     {    /* 挂载设备 */res_flash = f_mount (1, &fs);if (res_flash == FR_OK)         {/* 打开或者创建文件 */res_flash = f_open(&file, "1:test1.txt", FA_CREATE_ALWAYS | FA_WRITE);if(res_flash == FR_OK)             {/* 向文件件中写数据 */res_flash = f_write(&file, g_TestBuf1, sizeof(g_TestBuf1), &bw);if (res_flash != FR_OK)                 {while(1);                 }/* 关闭文件 */f_close(&file);                 }            /* 打开或者创建文件 */res_flash = f_open(&file, "1:test2.txt", FA_CREATE_ALWAYS | FA_WRITE);if(res_flash == FR_OK)             {/* 向文件件中写数据 */res_flash = f_write(&file, g_TestBuf2, sizeof(g_TestBuf2), &bw);if (res_flash != FR_OK)                 {while(1);                 }/* 关闭文件 */f_close(&file);                 }/* 以读的方式打开文件 */res_flash = f_open(&file, "1:test2.txt", FA_OPEN_EXISTING | FA_READ);     if(res_flash == FR_OK)             {                 res_flash = f_read(&file, g_ReadBuf, sizeof(g_ReadBuf), &bw); if(res_flash != FR_OK)                 {while(1);                 }    /* 关闭文件 */f_close(&file);                 }             }/* 卸载文件 */res_flash = f_mount (1, NULL);         }     }

通过调试,可以发现是能够成功读取前面创建的文件中的内容,如下图所示:

四、扩展功能

为了能够更直观看到文件系统创建的文件和写入的内容,我结合了单片机的USB设备模式,把外部Flash模拟成一个U盘,能够直接在电脑查看创建的文件。

USB相关变量定义及初始化

usb_core_handle_struct usbhs_core_dev = {     .dev =      {         .dev_desc = (uint8_t *)&device_descripter,         .config_desc = (uint8_t *)&configuration_descriptor,             .strings = usbd_strings,                                         .class_init = msc_init,                                             .class_deinit = msc_deinit,                                         .class_req_handler = msc_req_handler,                             .class_data_handler = msc_data_handler     },     .udelay = delay_us,     .mdelay = delay_ms };void usb_clock_config(void);void usb_gpio_config(void);void usb_interrupt_config(void); uint8_t timer_prescaler = 0; uint32_t usbfs_prescaler = 0;

主函数中实现文件的创建并写入数据,写入完成后初始化并启动USB设备

/*!     \brief      main function     \param[in]  none     \param[out] none     \retval     none*/int main(void) {/* configure 4 bits pre-emption priority */nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);          bsp_spi1_init();     gd25q256df_init();              flash_id = gd25q256df_read_id();if(flash_id == 0xC84019)     {    /* 挂载设备 */res_flash = f_mount (1, &fs);if (res_flash == FR_OK)         {/* 打开或者创建文件 */res_flash = f_open(&file, "1:test1.txt", FA_CREATE_ALWAYS | FA_WRITE);if(res_flash == FR_OK)             {/* 向文件件中写数据 */res_flash = f_write(&file, g_TestBuf1, sizeof(g_TestBuf1), &bw);if (res_flash != FR_OK)                 {while(1);                 }/* 关闭文件 */f_close(&file);                 }            /* 打开或者创建文件 */res_flash = f_open(&file, "1:test2.txt", FA_CREATE_ALWAYS | FA_WRITE);if(res_flash == FR_OK)             {/* 向文件件中写数据 */res_flash = f_write(&file, g_TestBuf2, sizeof(g_TestBuf2), &bw);if (res_flash != FR_OK)                 {while(1);                 }/* 关闭文件 */f_close(&file);                 }                     }/* 卸载文件 */res_flash = f_mount (1, NULL);         }         /* configure USB clock */usb_clock_config();    /* USB timer configure */timer_nvic_init();/* USB device stack configure */usbd_init(&usbhs_core_dev, USB_FS_CORE_ID);/* USB interrupt configure */usb_interrupt_config();         /* check if USB device is enumerated successfully */while (usbhs_core_dev.dev.status != USB_STATUS_CONFIGURED) {}             while(1); }

测试结果如下图所示:

#endif

(0)

相关推荐