说明:本文主要使用 USB的全速模式和FATFS实现对U盘的存储和读取。其中单片机作为主机,U盘为从机,需要为U盘进行供电。
1:cubemx配置:
(1)
如果想要支持给USB供电,点击“Activate_VBUS”,并在下图中配置供电的引脚
选择“Mass Storage Host Class”作为U盘存储,参数配置选择默认就可以。
(3)
FATFS中勾选USB Disk模式,CODE_PAGE用于设置语言类型。使用Latin1时 U盘文件名不能超过一定的字节,否则在读取U盘时候直接报错误。我没有使用“Simplified Chinese”因为在读取U盘时候频频出错。所以选择默认的语言标准
剩下的直接默认就可以
2 代码生成:
函数会生成“MX_FATFS_Init”,“MX_USB_HOST_Init”,“MX_USB_HOST_Process”
在while循环中加入自定义函数
while(1)
{
UDisk_IsOnline_Judge();
}
volatile uint8_t UDiskOnline = 0; /* 0:U盘不在线,1:U盘在线 */
/* 检查U盘是否在线 */
void UDisk_IsOnline_Judge(void)
{
if(Appli_state == APPLICATION_READY)
{
/* 挂载U盘 */
if(UDiskOnline == 0)
{
if(f_mount(&FatfsUDisk, (TCHAR const*)USBHPath, 0) != FR_OK)
{
Error_Handler(); //FatFs Initialization Error
}
UDiskOnline =1;
}
}
else if(Appli_state == APPLICATION_DISCONNECT)
{
if(UDiskOnline == 1)
{
f_mount(NULL, "", 0); /* 取消挂载U盘 */
UDiskOnline =0;
}
}
}
接下来就可以利用文件操作函数进行读写文件:
#define FILE_IMG "0:imgfile/img.bmp"
FIL fileopen;
FILINFO file_info;
FRESULT res;
uint8_t buf[2048];
int bytesRead;
f_stat(FILE_SPLASH,&file_info);
FileSize = file_info.fsize; /* 文件大小! */
res=f_open(&fileopen, FILE_IMG,FA_OPEN_EXISTING | FA_READ); /* 打开或创建文件 */
if(res== FR_OK) /* 打开文件成功 */
{
f_lseek (&fileopen,FileSize -2048); /* 移动到倒数2048个字节处 */
f_read(&fileopen, (char*)buf+512*3, FILE_BUF_LEN, (void *)&bytesRead); /* 读取512个字节 */
f_read(&fileopen, (char*)buf+512*2, FILE_BUF_LEN, (void *)&bytesRead); /* 读取512个字节 */
f_read(&fileopen, (char*)buf+512*1, FILE_BUF_LEN, (void *)&bytesRead); /* 读取512个字节 */
f_read(&fileopen, (char*)buf+512*0, FILE_BUF_LEN, (void *)&bytesRead); /* 读取512个字节 */
f_close(&fileopen); // 关闭文件
return 1;
}
f_close(&fileopen); // 关闭文件
return 0;
/* 创建目录 */
FRESULT MakeDir(char *Path)
{
DIR dir;
FRESULT res;
res = f_opendir(&dir, Path); /* Open the directory */
if ((res != FR_OK)&&(res != FR_DENIED) ) /* 没有打开文件夹。说明没有文件,而且内存不应该是满的,则需要创建文件夹 */
{
res = f_mkdir(Path); /* 建立目录 folder,创建成功为FR_OK */
}
f_closedir(&dir); /* close the directory */
return res;
}
/* 文件写入数据 */
uint8_t UsbSave(void) //RAW data save
{
char FileName[256];
FRESULT FHandle;
FIL fileopen;
int bytesWrite;
char FileHeader[]= /* 文件54字节 */
{
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x01e,0x1f,0x20,
0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,
0x31,0x32,0x33,0x34,0x35,0x36
};
sprintf(FileName,"0:\\USER");
FHandle = MakeDir(FileName);
if(FHandle == FR_OK) /* 目录存在 */
{
sprintf(FileName,"%s\\%s.BMP",FileName,filenamebuff);
FHandle = f_open(&fileopen,FileName,FA_CREATE_ALWAYS|FA_WRITE); /* 不存在则创建,存在也创建(覆盖) */
if(FHandle == FR_OK)
{
FHandle = f_write(&fileopen,FileHeader,sizeof(FileHeader),(void *)&bytesWrite);
if((FHandle != FR_OK) ||(bytesWrite