STM32F4的USB接口学习笔记-虚拟U盘

实现STM32使用全速USB接口的自定义HID与PC通讯的功能

1 STM32CubeMX配置

1.1 配置时钟

先设置好时钟,我用的外部8M晶振,但USB接口要使用48MHz时钟,所以主频只能到168Mhz
在这里插入图片描述

1.2 配置SD card

参数页如下配置,时钟分频比选择0,实际为2分频
在这里插入图片描述
配置DMA,给SDIO分配两个DMA通道,注意数据宽度选择Byte
在这里插入图片描述
打开SDIO和DMA的中断使能
在这里插入图片描述
另外GPIO要注意,如果硬件上这几个端口没有上拉电阻,这里开启内部上拉就好了
在这里插入图片描述

1.3 配置USB接口

模式选择Device_Only,下面的参数保持默认即可,其它页的参数不需要修改,中断已默认打开
在这里插入图片描述

1.4 设置中断优先级

注意中断优先级,SDIO的优先级要高一些,SDIO>DMA>USB
在这里插入图片描述

1.4 配置FATFS

上面模式页勾选SD Card,下面只需要修改长文件名的设置,使用动态堆
在这里插入图片描述
高级设置页,注意选择使用DMA
在这里插入图片描述
最后一页中,需要选择一下SD信号的引脚
在这里插入图片描述

1.5 配置USB设备

IP选择MSC,参数页不需要修改,MSC_MEDIA_PACKET需要跟SD卡的扇区大小一致,一般是512字节
在这里插入图片描述
这里可以设置自己的VID、PID等产品信息
在这里插入图片描述
配置完成,可以生成代码了

2 修改代码

找到《sd_diskio.h》文件,添加一个头文件的引用:#include “ff_gen_drv.h”
在这里插入图片描述
找到《usbd_storage_if.c》文件,添加一个头文件的引用:#include “sd_diskio.h”
在这里插入图片描述
接下来还是这个文件,添加SD卡对象的声明:

/* USER CODE BEGIN EXPORTED_VARIABLES */

extern 	SD_HandleTypeDef 			hsd;

/* USER CODE END EXPORTED_VARIABLES */

然后再修改几个函数,首先在初始化函数中添加一条初始化语句:

int8_t STORAGE_Init_FS(uint8_t lun)
{
  /* USER CODE BEGIN 2 */
	SD_Driver.disk_initialize(1);
  return (USBD_OK);
  /* USER CODE END 2 */
}

修改获取容量的函数:

int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
//  *block_num  = STORAGE_BLK_NBR;
//  *block_size = STORAGE_BLK_SIZ;
	*block_num  = hsd.SdCard.BlockNbr;
	*block_size = hsd.SdCard.BlockSize;
  return (USBD_OK);
  /* USER CODE END 3 */
}

修改获取卡状态的函数:

int8_t STORAGE_IsReady_FS(uint8_t lun)
{
  /* USER CODE BEGIN 4 */
  return (SD_Driver.disk_status(lun));
  /* USER CODE END 4 */
}

修改读卡函数:

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
	return (SD_Driver.disk_read(lun, buf, blk_addr, blk_len));
  /* USER CODE END 6 */
}

修改读卡、写卡函数:

/**
  * @brief  .
  * @param  lun: .
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 6 */
	return (SD_Driver.disk_read(lun, buf, blk_addr, blk_len));
  /* USER CODE END 6 */
}

/**
  * @brief  .
  * @param  lun: .
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
  /* USER CODE BEGIN 7 */
	return (SD_Driver.disk_write(lun, buf, blk_addr, blk_len));
  /* USER CODE END 7 */
}

其它就不需要改了,也不需要自己写程序,作为USB Device单片机是被动的,所有的工作都在中断中执行。

3 测试

编译下载,可以看到电脑上出现了一个U盘盘符,用一个400多M的压缩包测试了存取速度,写入:355KB/s,读取:710KB/s。

一直想弄USB来着,今天就调试了下读U程序,自己测试了三个U和一个读卡器(U为4G、16G、16G,内存卡为2G)均可正常读取。废话不多说,介绍下实现的功能(各功能通过User键切换): 首先来张靓照,屏幕摔了两块,不敢买第三块了,索性拆了以前山寨机上的屏幕,自己做了个转接板,驱动成功(嘿嘿!) 1、读U信息,包括PID、VID和制造商等信息,如图: 2、读取U容量,用电脑看了下,容量一点不错。还有就是读取文件目录(这里暂时只做了两级显示) 3、创建一个TXT文件,并写入“STM32 Connectivity line Host Demo application using FAT_FS ”,在电脑端打开该TXT文件,其写入字符串正确。 4、显示一张BMP格式的图片(BMP图片显示最直接,就先弄它了),来自于ST 可实际发现,其图片竟然被镜像了,原因还在寻找中(估计是驱动有问题)。不管怎样,U读成功之后,以后玩Discovery就爽多了,各种图片、音乐甚至是AVI视屏都有可能实现啦!还是那句老话,独乐乐不如众乐乐,代码必须得传上来,嘿嘿! 总结: 欢迎各位坛友在此基础之上完成新的功能,例如MP3格式音乐解码播放(WAV格式音乐毕竟非主流,播放一会主芯片还发热,就不搞WAV了)。还有emWin,我目前只是移植成功了,还没学会如何结合自己的需求进行应用,并且FPU功能的异常中断问题还没解决,只能不使用FPU演示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值