敞开生长之旅!这是我参与「日新计划 2 月更文挑战」的第 22 天,点击查看活动详情

一、USB简介

USB(Universal Serial BUS)通用串行总线,是一个外部总线规范,用于规范电脑与外部设备的衔接和通讯。是应用在 PC 范畴的接口技术。USB 接口支撑设备的即插即用和热插拔功用。USB 是在 1994 年底由英特尔、康柏、IBM、Microsoft 等多家公司联合提出的。

USB 发展到现在已经有 USB1.0/1.1/2.0/3.0 等多个版本。现在用的最多的便是 USB1.1 和 USB2.0,USB3.0 现在已经开始遍及。STM32F103 自带的 USB 契合 USB2.0 规范,不过 STM32F103 的 USB 都只能用来做设备,而不能用作主机。

规范 USB 共四根线组成,除 VCC/GND 外,别的为 D+,D-; 这两根数据线选用的是差分电压的方式进行数据传输的。在 USB 主机上,D-和 D+都是接了 15K 的电阻到低的,所以在没有设备接入的时分,D+、D-均是低电平。而在 USB 设备中,假如是高速设备,则会在 D+上接一个 1.5K 的电阻到 VCC,而假如是低速设备,则会在 D-上接一个 1.5K 的电阻到 VCC。这样当设备接入主机的时分,主机就能够判别是否有设备接入,并能判别设备是高速设备还是低速设备。

STM32F103 的 MCU 自带 USB 从控制器,契合 USB 规范的通讯衔接;PC 主机和微控制器之间的数据传输是经过共享一专用的数据缓冲区来完结的,该数据缓冲区能被 USB 外设直接拜访。这块专用数据缓冲区的巨细由所运用的端点数目和每个端点最大的数据分组巨细所决定,每个端点最大可运用 512 字节缓冲区(专用的 512 字节,和 CAN 共用),最多可用于 16 个单向或 8 个双向端点。USB 模块同 PC 主机通讯,依据 USB 规范实现令牌分组的检测,数据发送/接收的处理,和握手分组的处理。整个传输的格局由硬件完结,其间包括 CRC 的生成和校验。

1.1 USB MSC简介

USB大容量存储设备类(The USB mass storage device class)是一种核算机和移动设备之间的传输协议,它答应一个通用串行总线(USB)设备来拜访主机的核算设备,使两者之间进行文件传输。经过这个规范的核算机衔接到的设备包括:移动硬盘、移动光驱、U盘、SD、TF等储存卡读卡器、数码相机、各种数字音频播放器和便携式媒体播放器、智能卡阅读器、掌上电脑和手机。 MSC的通用性和操作简略使他成为移动设备上最常见的文件体系,USB MSC并不需求任何特定的文件体系, 相反,它提供了一个简略的界面来读写接口用于拜访任何硬盘驱动器。操作体系能够把MSC像本地硬盘相同格局化,并能够与他们喜欢的任何文件体系格局它,当然也能够创立多个分区。

1.2 SDIO简介

SD 卡(Secure Digital Memory Card) 在咱们生活中已经非常遍及了,控制器对 SD 卡进行读写通讯操作一般有两种通讯接口可选,一种是 SPI 接口,别的一种便是 SDIO 接口。

SDIO 全称是安全数字输入/输出接口,多媒体卡(MMC)、SD 卡、SD I/O 卡都有 SDIO 接口。 MMC 卡能够说是 SD 卡的前身,现阶段已经用得很少。STM32F10x 系列控制器有一个 SDIO 主机接口,它能够与 MMC 卡、SD 卡、SD I/O 卡以及 CE-ATA 设备进行数据传输。别的,STM32F10x 系列控制器的 SDIO 是不支撑 SPI 通讯形式的,假如需求用到 SPI 通讯只能运用 SPI 外设。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

1.3 SD卡简介

SD卡除了SD-Micro卡之外,还有两种分别是SD和mini-SD,他们分别长这样:

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

SD卡的四个角有一个是没有的,以便咱们认识正反来运用它,SD卡的一侧还有一个能够扳动的读写维护开关,这三种卡里边SD卡最大,SD-Micro最小。

依据SD卡的容量,可划分为SDSC(SD Standard Capacity)、SDHC(SD High Capacity)、SDXC(SD Extended Capacity)三种规范。现今,商场的主流SD产品是SDHC和SDXC这两种较大容量的存储卡,而SDSC卡因容量过小,已逐渐被商场筛选。SD卡(三种卡的总称)的存储空间是由一个一个扇区组成的,SD卡的扇区巨细是固定的,为512byte(这一点很重要) ,若干个扇区又能够组成一个分配单元(也被成为簇),分配单元常见的巨细为4K、8K、16K、32K、64K。

需求留意的是,SD-Micro只要8个引脚,而SD卡是有九个引脚的,这两种都能够直线4线通讯。

二、新建工程

1. 翻开 STM32CubeMX 软件,点击“新建工程”

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

2. 挑选 MCU 和封装

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

3. 装备时钟 RCC 设置,挑选 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
挑选 Clock Configuration,装备体系时钟 SYSCLK 为 72MHz 修正 HCLK 的值为 72 后,输入回车,软件会自动修正一切装备
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

4. 装备调试形式 非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器 SYS 设置,挑选 Debug 为 Serial Wire

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

三、USB

3.1 参数装备

Connectivity 中挑选 USB 设置,并勾选 Device(FS) 激活 USB 设备。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

Parameter Settings 进行具体参数装备。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

  • Speed: Full Speed 12MBit/s(固定为全速)
  • Low Power: 默许 Disabled(在任何不需求运用usb模块的时分,经过写控制寄存器总能够使usb模块置于低功耗形式(low power mode ,suspend形式)。在这种形式下,不发生任何静态电流耗费,一起usb时钟也会减慢或停止。经过对usb线上数据传输的检测,能够在低功耗形式下唤醒usb模块。也能够将一特定的中止输入源直接衔接到唤醒引脚上,以使体系能当即康复正常的时钟体系,并支撑直接启动或停止时钟体系。)

3.2 引脚装备

USB 的 DP 引脚有必要上拉 1.5K 欧的电阻,电脑才干检测到 USB,否则检测不到。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
查看野火指南者开发板原理图可知,需求将 PD6 装备为低电平使能 USB。
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

在右边图中找到 PD6 引脚,挑选 GPIO_Output

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

GPIO output level 中挑选 Low 输出低电平。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

3.3 装备时钟

挑选 Clock Configuration,USB 时钟装备为 48MHz,且来源最好是外部晶振分频得到。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

3.4 USB Device

USB有主机(Host)和设备(Device)之分。一般电脑的USB接口为主机接口,而键盘、鼠标、U盘等则为设备。

部分类型的STM32芯片有1~2个USB接口。像STM32F103系列的有一个USB Device接口,STM32F407系列的有2个USB接口,既能够作为HOST,又能够作为Device,还能够作为OTG接口。

Middleware 中挑选 USB_DEVICE 设置,在 Class For FS IP 设备类别挑选 Mass Storage Class(HID) 大容量存储设备类。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
参数装备坚持默许(或依据存储介质的最小存储单元修正缓冲区巨细)。
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

  • MSC_MEDIA_PACKET (Media I/O buffer Size)(读写缓冲区巨细): 512(默许为512,这个的巨细关于USB读写速度会有一些影响,最好和存储介质的最小存储单元共同)

本实验板运用的SD卡(三种卡的总称)的存储空间是由一个一个扇区组成的,SD卡的扇区巨细是固定的,为512byte(这一点很重要) ,若干个扇区又能够组成一个分配单元(也被成为簇),分配单元常见的巨细为4K、8K、16K、32K、64K。

设备描绘符坚持默许。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

四、SDIO

STM32 控制器能够控制运用单线或 4 线传输,本开发板规划运用 4 线传输。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

4.1 参数装备

Connetivity 中挑选 SDIO 设置,并挑选 SD 4 bits Wide bus 四线SD形式

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
此刻 SDIO 对应的管脚也被选中。
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
Parameter Settings 进行具体参数装备。

Clock transition on which the bit capture is made: Rising transition。主时钟 SDIOCLK 发生 CLK 引脚时钟有效沿挑选,可选上升沿或下降沿,它设定 SDIO 时钟控制寄存器(SDIO_CLKCR)的 NEGEDGE 位的值,一般挑选设置为上升沿

SDIO Clock divider bypass: Disable。时钟分频旁路运用,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 BYPASS 位。假如使能旁路,SDIOCLK 直接驱动 CLK 线输出时钟;假如禁用,运用 SDIO_CLKCR 寄存器的 CLKDIV 位值分频 SDIOCLK,然后输出到 CLK 线。一般挑选禁用时钟分频旁路

SDIO Clock output enable when the bus is idle: Disable the power save for the clock。节能形式挑选,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 PWRSAV 位的值。假如使能节能形式,CLK 线只要在总线激活时才有时钟输出;假如禁用节能形式,始终使能 CLK 线输出时钟。

SDIO hardware flow control: The hardware control flow is disabled。硬件流控制挑选,可选使能或禁用,它设定 SDIO_CLKCR 寄存器的 HWFC_EN 位的值。硬件流控制功用能够避免 FIFO 发送上溢和下溢错误。

SDIOCLK clock divide factor: 6。时钟分频系数,它设定 SDIO_CLKCR 寄存器的 CLKDIV 位的值,设置 SDIOCLK 与 CLK 线输出时钟分频系数:CLK 线时钟频率=SDIOCLK/([CLKDIV+2])。

SDIO_CK 引脚的时钟信号在卡识别形式时要求不超越 400KHz,而在识别后的数据传输形式时则希望有更高的速度(最大不超越 25MHz),所以会针对这两种形式装备 SDIOCLK 的时钟。

这里参数描绘建议将SDIOCLK clock divede factor 参数运用默许值为0,SDIOCLK为72MHz,能够得到最大频率36MHz,但请留意,有些类型的SD卡或许不支撑36MHz这么高的频率,所以还是要以实际情况而定。

4.2 装备DMA

SDIO 外设支撑生成 DMA 恳求,运用 DMA 传输能够提高数据传输功率,因此在 SDIO 的控制代码中,能够把它设置为 DMA 传输形式或轮询形式,ST 规范库提供 SDIO 示例中针对这两个形式做了区别处理。应用中一般都运用DMA 传输形式。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

点击 DMA Settings 增加 SDIO 对应 DMA2 的通道4。DMA形式挑选循环形式,方向选为内存到外设。

  • Priority: 当发生多个 DMA 通道恳求时,就意味着有先后呼应处理的次序问题,这个就由裁定器也办理。裁定器办理 DMA 通道恳求分为两个阶段。第一阶段属于软件阶段,能够在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,假如两个或以上的 DMA 通道恳求设置的优先级相同,则他们优先级取决于通 道编号,编号越低优先权越高,比方通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。
  • ModeNormal 表明单次传输,传输一次后终止传输。 Circular 表明循环传输,传输完结后又重新开始持续传输,不断循环永不停止。
  • Increment AddressPeripheral 表明外设地址自增。 Memory 表明内存地址自增。
  • Data WidthByte 一个字节。 Half Word 半个字,等于两字节。 Word 一个字,等于四字节。

4.3 装备NVIC

首要SD能够敞开DMA读取或许单纯的SD的中止,但是其间优先级一定要为 SD > SD DMA Rx/Tx > USB,不然当SD卡在读写的时分被其他中止打断,会直接导致U盘掉盘,中途卡顿。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

五、生成代码

输入项目名和项目路径

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
挑选应用的 IDE 开发环境 MDK-ARM V5
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
每个外设生成独立的 ’.c/.h’ 文件 不勾:一切初始化代码都生成在 main.c 勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
点击 GENERATE CODE 生成代码
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

六、修正usbd_storage_if.c

翻开工程文件夹Application/User/USB_DEVICE/Appusbd_storage_if.c文件

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

6.1 声明SD卡句柄

/* USER CODE BEGIN EXPORTED_VARIABLES */
extern SD_HandleTypeDef hsd;
/* USER CODE END EXPORTED_VARIABLES */

6.2 修正获取SD卡容量信息函数

  • STORAGE_GetCapacity_FS
/**
  * @brief  .
  * @param  lun: .
  * @param  block_num: .
  * @param  block_size: .
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{
  /* USER CODE BEGIN 3 */
    HAL_SD_CardInfoTypeDef info;
	if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER)
	{
		HAL_SD_GetCardInfo(&hsd, &info);
		*block_num = info.LogBlockNbr;
		*block_size = info.LogBlockSize;
		return  USBD_OK;
	}
	return  USBD_FAIL;
  /* USER CODE END 3 */
}

6.3 修正存储读写函数

  • STORAGE_Read_FS
/**
  * @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 */
    int8_t ret = USBD_FAIL;
    if(HAL_SD_ReadBlocks(&hsd, buf, blk_addr,  blk_len, HAL_MAX_DELAY) == HAL_OK)
    {
    	ret = USBD_OK;
        while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY);
        while HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
    }
    return ret;
  /* USER CODE END 6 */
}
  • STORAGE_Write_FS
/**
  * @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 */
    int8_t ret = USBD_FAIL;
    if(HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK)
    {
    	ret = USBD_OK;
        while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY);
        while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
    }
    return ret;
  /* USER CODE END 7 */
}

七、查看作用

编译工程,下载到板子上,插上USB线衔接到电脑上,识别出为大容量存储设备

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

留意: 假如设备带有感叹号,则参阅下面九、留意事项

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

弹出格局化对话框,直接格局化就行

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

文件体系挑选FAT形式

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

新建一个文档测试.txt然后在文档中输入一些内容:

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

重新上电断开后再次翻开U盘看里边的内容和已用空间

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

八、工程代码

链接:pan.baidu.com/s/1b-C7dXod… 提取码:xy1z

九、留意事项

用户代码要加在 USER CODE BEGIN NUSER CODE END N 之间,否则下次运用 STM32CubeMX 重新生成代码后,会被删去。

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

假如USB端口出现感叹号设备无法启动的问题,可适当将堆改大,如0x400

STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)
STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)


• 由 Leung 写于 2022 年 11 月 30 日

• 参阅:STM32-USB学习系列(三):USB-MSC实现以SD卡为载体的U盘

    STM32&SD卡实现USB虚拟U盘(含源码)