中级会员
 
- 积分
- 394
- 金钱
- 394
- 注册时间
- 2015-1-7
- 在线时间
- 101 小时
|
本帖最后由 zhang062061 于 2021-1-10 17:04 编辑
硬件环境:STM32F429IGT6
软件环境:STM32CubeMX v5.5.0
HAL库版本:STM32CubeF4 Firmware Package V1.24.0
01 STM32CubeMX配置
时钟等基础配置参考之前的文章,配置USB部分如下:
该单片机有两个USB接口,一个支持USB2.0全速(12M),另一个支持USB2.0高速(480M),但高速接口需要外部PHY芯片的支持。选择一个USB,用内部PHY全速接口,模式选择为主机模式Host Only,速度为全速12M(Host Full Speed 12MBit/s)。 使能USB中断:
选择USB的工作模式为大容量存储主机类,配置为默认即可。
FATFS配置选择USB Disk,可根据自己需要进行功能删减。
这里使能了RTC作为文件系统的时钟。
02 代码编写
生成代码之后,可以看到,主循环中已经自动添加了一个函数:
打开函数定义,发现这是一个判断U盘连接状态的函数,用户可以在该函数内添加自定义的功能,也可以在函数外编写其它函数实现功能。
在主循环中添加以下代码对U盘读写功能进行测试:- if(Appli_state == APPLICATION_READY)//U盘已经加载完成
- {
- if(status == 0)//U盘加载后只运行一次
- {
- status = 1;
- retUSBH=f_mount(&USBHFatFS, (TCHAR const*)USBHPath, 1);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"挂载U盘成功!\r\n",14,100);
- }
- //写入文件测试
- HAL_UART_Transmit(&huart2,(uint8_t*)"写入文件测试!\r\n",15,100);
- retUSBH = f_open(&USBHFile,(const char*)"测试.txt",FA_CREATE_ALWAYS|FA_WRITE);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"打开文件"测试.txt"成功!\r\n",25,100);
- }
- retUSBH = f_write(&USBHFile,FileBuf,17,&bw);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"写入文件成功!\r\n",15,100);
- }
- retUSBH = f_close(&USBHFile);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"关闭文件成功!\r\n\r\n",17,100);
- }
- //读取文件测试
- HAL_UART_Transmit(&huart2,(uint8_t*)"读取文件测试!\r\n",15,100);
- retUSBH = f_open(&USBHFile,(const char*)"测试.txt",FA_OPEN_EXISTING|FA_READ);//打开文件
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"打开文件"测试.txt"成功!\r\n",25,100);
- }
- retUSBH = f_read(&USBHFile,FileBuf,17,&bw);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"读取文件成功!文件内容:",23,100);
- HAL_UART_Transmit(&huart2,FileBuf,bw,100);
- }
- retUSBH = f_close(&USBHFile);
- if(retUSBH==FR_OK)
- {
- HAL_UART_Transmit(&huart2,(uint8_t*)"关闭文件成功!\r\n",15,100);
- }
- }
- }
复制代码
观察串口打印的信息,把U盘插入电脑查看文件内容,U盘读写测试成功:
同时这里会发现,文件的修改时间是空的,这是因为FatFS文件系统中没有移植时钟的函数,这里需要用户自己编写。
FatFs中的时间格式用一个32位数据表示年月日时分秒,其中:
- bit31:25:表示年,这里的年是指文件最近一次修改的年份与1980年的差值。
- bit24:21:表示月(1~12)。
- bit20:16:表示日(1~31)。
- bit15:11:表示时 (0~23)。
- bit10:5:表示分(0~59)。
- bit4:0:表示 秒/ 2 的值 (0~29)。
在fatfs.c文件中找到DWORD get_fattime(void)函数,添加以下程序:
- DWORD get_fattime(void)
- {
- /* USER CODE BEGIN get_fattime */
- DWORD time_buff=0;
- RTC_TimeTypeDef fTime = {0};
- RTC_DateTypeDef fDate = {0};
- //获取当前日期时间
- HAL_RTC_GetTime(&hrtc, &fTime, RTC_FORMAT_BIN);
- HAL_RTC_GetDate(&hrtc, &fDate, RTC_FORMAT_BIN);
-
- //按照FatFs的时间格式组合
- time_buff |= ((fDate.Year + 2000 - 1980)<<25); //年
- time_buff |= (fDate.Month<<21); //月
- time_buff |= (fDate.Date<<16); //日
- ​
- time_buff |= (fTime.Hours<<11); //时
- time_buff |= (fTime.Minutes<<5); //分
- time_buff |= (fTime.Seconds/2); //秒
- return time_buff;
- //return 0;
- /* USER CODE END get_fattime */
- }
复制代码
重新编译程序进行测试,发现有了文件修改时间:
03 总结
这里测试了3个U盘,分别是金士顿4G、金士顿8G和三星32G的(其中8G的为金士顿8G SD卡+读卡器),均能正常读写,不过32G的U盘加载速度要慢一些,其它U盘的兼容性待测试。
欢迎关注公众号"嵌入式技术开发",大家可以后台给我留言沟通交流。如果觉得该公众号对你有所帮助,也欢迎推荐分享给其他人。
|
|