AT32F435模拟U盘操作W25Q128

0 评论
/
7 阅读
/
9597 字
06 2025-02
/*
 * usbfs/ufs.cpp - part of UniClock, a Clock for the Galactic Unicorn.
 *
 * UniClock is an enhanced clock/calendar display for the beautiful Galactic
 * Unicorn.
 *
 * usbfs is the subsystem that handles presenting a filesystem to the host
 * over USB; in this instance, it is used for managing configuration files.
 *
 * ufs is the actual filesystem management, which sits on top of the USB and
 * storage components.
 * 
 * Copyright (C) 2023 Pete Favelle <ahnlak@ahnlak.com>
 * Released under the MIT License; see LICENSE for details.
 */

/* System headers. */

#include <stdio.h>
#include <stdlib.h>

#include "stdlib.h"

/* Local headers. */
#include "flash_diskio.h"
#include "spi_flash.h"
#include "w25qxx.h"  /* SPI Flash driver file */

#include "ff.h"
#include "diskio.h"
#include "ufs.h"
extern const Diskio_drvTypeDef Flash_Driver;

/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
/* Module variables. */
static char USERPath[4];   /* SD logical drive path */
static FATFS USERFatFS;

#define _MIN_SS FF_MIN_SS
#define _MAX_SS FF_MAX_SS

/* Functions */
// 配置文件系统
void format_disk() {
    FATFS fs;
		MKFS_PARM opt = {
				.fmt = FM_FAT32,  // **改成 FAT16**
				.n_fat = 1,       
				.align = 0,    
				.n_root = 0,    
				.au_size = 512
		};
    BYTE work[4096];       // 工作缓冲区

    // 簇数量计算(示例)
    DWORD n_clst = (16 * 1024 * 1024) / opt.au_size; // 16MB存储大小

    // 格式化磁盘
    FRESULT res = f_mkfs("", &opt, work, sizeof(work));
    if (res == FR_OK) {
        printf("Disk formatted successfully.\n");
    } else {
        printf("Failed to format disk. Error code: %d\n", res);
    }

    // 装载文件系统
    res = f_mount(&fs, "", 1);
    if (res == FR_OK) {
        printf("File system mounted successfully.\n");
    } else {
        printf("Failed to mount file system. Error code: %d\n", res);
    }
}
void ufs_init(void) {
    FRESULT res;
    // 注册并链接Flash驱动
    FATFS_LinkDriver(&Flash_Driver, USERPath);
}

// Define workspace buffer for formatting
BYTE workBuffer[4 * User_Sector];

/* Mount the FatFs filesystem */
void Mount_FatFs(void) {
	  //format_disk();
    // Mount the filesystem
    FRESULT retUSER = f_mount(&User_FatFs, User_SDPath, 1);
    // If an error occurs
    if (retUSER != FR_OK) {
        // If no filesystem exists, format it
        if (retUSER == FR_NO_FILESYSTEM) {
            printf("\nNo filesystem found, starting format\n");
            format_disk();
        }
        // If another error occurs
        else {
            printf("An error occurred, error code = %d\n", retUSER);
        }
    }
    // If the filesystem already exists, mount successfully
    else {
			  //format_disk();
        printf("Filesystem mounted successfully\n");
    }
}
void FatFs_GetDiskInfo(void) {
    FATFS *FS;
    size_t Total = 0, Used = 0, Free = 0;
    DWORD FreeClusters, TotalSectors;

    // Step 1: 获取磁盘信息
    int Ret = f_getfree("0:", &FreeClusters, &FS);
    if (Ret != FR_OK) {
        printf("Error: f_getfree() failed! Code: %d\n", Ret);
        return;
    }

    // Step 2: 通过 GET_SECTOR_COUNT 获取实际的总扇区数
    if (disk_ioctl(0, GET_SECTOR_COUNT, &TotalSectors) != RES_OK) {
        printf("Error: GET_SECTOR_COUNT failed!\n");
        return;
    }

    // Step 3: 确保 FS->ssize 有效
    if (FS->ssize == 0) {
        printf("Error: Sector size is 0!\n");
        return;
    }

    // Step 4: 计算 FAT 结构占用的空间 (估算)
    DWORD ReservedSectors = FS->csize * 32;  // 估算 FAT 表占用的空间
    size_t SystemUsed = ReservedSectors * FS->ssize;

    // Step 5: 计算存储大小
    size_t FreeSectors = FreeClusters * FS->csize;    // 空闲扇区数
    size_t UsedSectors = TotalSectors - FreeSectors;  // 已用扇区数

    Total = TotalSectors * FS->ssize;  // 总容量 (字节)
    Free = FreeSectors * FS->ssize;    // 空闲容量 (字节)
    Used = UsedSectors * FS->ssize;    // 已用容量 (字节)

    // Step 6: 转换为 KB / MB
    size_t Total_KB = Total / 1024;
    size_t Free_KB = Free / 1024;
    size_t Used_KB = Used / 1024;
    
    size_t Total_MB = Total_KB / 1024;
    size_t Free_MB = Free_KB / 1024;
    size_t Used_MB = Used_KB / 1024;

    // Step 7: 打印容量信息
    printf("\n=== FAT File System Info ===\n");
    printf("Total Space:  %lu B  (%lu KB, %lu MB)\n", Total, Total_KB, Total_MB);
    printf("Used Space:   %lu B  (%lu KB, %lu MB)\n", Used, Used_KB, Used_MB);
    printf("Free Space:   %lu B  (%lu KB, %lu MB)\n", Free, Free_KB, Free_MB);
    printf("System Used (FAT Table + Root Dir): %lu B\n", SystemUsed);
}

/* 写入 TXT 文件 */
void FatFs_WriteTXTFile(TCHAR *filename) {
    FIL file;
    FATFS *fs;
    FRESULT res;

    printf("\n*** Creating TXT file: %s ***\n", filename);

    // Step 1: 检查是否已经挂载
    f_getfree("0:", NULL, &fs);
    if (fs == NULL) {  // 如果未挂载,执行挂载
        static FATFS fatfs;
        res = f_mount(&fatfs, "0:", 1);
        if (res != FR_OK) {
            printf("Error: f_mount() failed! Code: %d\n", res);
            return;
        }
    }

    // Step 2: 打开/创建文件
    res = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE);
    if (res != FR_OK) {
        printf("Open file error, error code: %d\n", res);
        return;
    }

    // Step 3: 写入内容
    TCHAR str[] = "Line1: Hello, FatFs with fixed date (2025/02/06)\n";  
    UINT bw;
    res = f_write(&file, str, sizeof(str) - 1, &bw);
    if (res == FR_OK) {
        printf("Write file successful: %s (%d bytes written)\n", filename, bw);
    } else {
        printf("Write file failed, error code: %d\n", res);
    }

    // Step 4: 关闭文件
    f_close(&file);
}
/* 判断文件是否存在 */
int FatFs_FileExists(const TCHAR *filename) {
    FILINFO fno;
    FRESULT res = f_stat(filename, &fno);
    
    if (res == FR_OK) {
        return 1;  // 文件存在
    } else if (res == FR_NO_FILE) {
        return 0;  // 文件不存在
    } else {
        return -1; // 发生错误
    }
}

/*读取一个文本文件的内容*/
void FatFs_ReadTXTFile(TCHAR *filename)
{
	printf("\r\n*** Reading TXT file: %s ***\r\n", filename);

	FIL	file;
	//以只读方式打开文件
	FRESULT res = f_open(&file, filename, FA_READ);  
	//打开成功
	if(res == FR_OK)
	{
		//读取缓存
		TCHAR str[100];
		//没有读到文件内容末尾
		while(!f_eof(&file))
		{
			//读取1个字符串,自动加上结束符”\0”
			//f_gets(str,100, &file);	
			//printf("%s", str);
		}
		printf("\r\n");
	}
	//如果没有该文件
	else if(res == FR_NO_FILE)
		printf("File does not exist\r\n");
	//打开失败
	else
		printf("f_open() error,error code: %d\r\n", res);
	//关闭文件
	f_close(&file);
}
#include "ff.h"
#include <stdio.h>

/* 扫描和显示指定目录下的文件和目录 */
void FatFs_ScanDir(const TCHAR* PathName)
{
    FATFS fs;    // FAT 文件系统对象
    DIR dir;     // 目录对象
    FILINFO fno; // 文件信息
		FRESULT res;
//    // Step 1: 先挂载文件系统
//    FRESULT res = f_mount(&fs, "0:", 1);
//    if (res != FR_OK) {
//        printf("Error: f_mount() failed! Code: %d\n", res);
//        return;
//    }

    // Step 2: 打开目录
    res = f_opendir(&dir, PathName);
    if (res != FR_OK) {
        printf("Error: f_opendir() failed! Code: %d\n", res);
        f_mount(NULL, "0:", 0); // 卸载文件系统(可选)
        return;
    }

    printf("\n*** All entries in dir: %s ***\n", PathName);

    // Step 3: 读取目录中的文件
    while (1)
    {
        res = f_readdir(&dir, &fno);
        if (res != FR_OK || fno.fname[0] == 0) {
            break;  // 读取错误或到达目录末尾
        }

        // Step 4: 判断是文件还是目录
        if (fno.fattrib & AM_DIR) {
            printf("[DIR]  %s\n", fno.fname);
        } else {
            printf("[FILE] %s (%lu bytes)\n", fno.fname, fno.fsize);
        }
    }

    // Step 5: 关闭目录
    f_closedir(&dir);
   

    // Step 6: 卸载文件系统(可选)
    //f_mount(NULL, "0:", 0);
}

/*获取一个文件的文件信息*/
void FatFs_GetFileInfo(TCHAR *filename)
{
	printf("\r\n*** File info of: %s ***\r\n", filename);

	FILINFO fno;
	//检查文件或子目录是否存在
	FRESULT fr = f_stat(filename, &fno);
	//如果存在从fno中读取文件信息
	if(fr == FR_OK)
	{
		printf("File size(bytes) = %ld\r\n", fno.fsize);
		printf("File attribute = 0x%x\r\n", fno.fattrib);
		printf("File Name = %s\r\n", fno.fname);
		//输出创建/修改文件时的时间戳
		FatFs_PrintfFileDate(fno.fdate, fno.ftime);
	}
	//如果没有该文件
	else if (fr == FR_NO_FILE)
		printf("File does not exist\r\n");
	//发生其他错误
	else
		printf("f_stat() error,error code: %d\r\n", fr);
}

/*删除文件*/
void FatFs_DeleteFile(TCHAR *filename)
{
	printf("\r\n*** Delete File: %s ***\r\n", filename);
	FIL	file;
	//打开文件
	FRESULT res = f_open(&file, filename, FA_OPEN_EXISTING);  
	if(res == FR_OK)
	{
		//关闭文件
		f_close(&file);
		printf("open successfully!\r\n");
	}
	//删除文件
	res = f_unlink(filename);
	//删除成功
	if(res == FR_OK)
	{
		printf("The file was deleted successfully!\r\n");
	}
	//删除失败
	else
	{
		printf("File deletion failed, error code:%d\r\n", res);
	}
}

/*打印输出文件日期*/
void FatFs_PrintfFileDate(WORD date, WORD time)
{
	printf("File data = %d/%d/%d\r\n", ((date>>9)&0x7F)+1980, (date>>5)&0xF, date&0x1F);
	printf("File time = %d:%d:%d\r\n", (time>>11)&0x1F, (time>>5)&0x3F, time&0x1F);
}


标签:
    暂无数据