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

发布者:SparklingStar最新更新时间:2025-02-11 来源: jianshu关键字:STM32CubeMX  USB接口  MSC  SD卡  模拟U盘 手机看文章 扫描二维码
随时随地手机看文章

一、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 外设。

1.3 SD卡简介

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

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 软件,点击“新建工程”


2. 选择 MCU 和封装


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


选择 Clock Configuration,配置系统时钟 SYSCLK 为 72MHz
修改 HCLK 的值为 72 后,输入回车,软件会自动修改所有配置


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


三、USB

3.1 参数配置

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


在 Parameter Settings 进行具体参数配置。


  • Speed: Full Speed 12MBit/s(固定为全速)

  • Low Power: 默认 Disabled(在任何不需要使用usb模块的时候,通过写控制寄存器总可以使usb模块置于低功耗模式(low power mode ,suspend模式)。在这种模式下,不产生任何静态电流消耗,同时usb时钟也会减慢或停止。通过对usb线上数据传输的检测,可以在低功耗模式下唤醒usb模块。也可以将一特定的中断输入源直接连接到唤醒引脚上,以使系统能立即恢复正常的时钟系统,并支持直接启动或停止时钟系统。)

3.2 引脚配置

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


查看野火指南者开发板原理图可知,需要将 PD6 配置为低电平使能 USB。


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


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


3.3 配置时钟

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


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) 大容量存储设备类。


参数配置保持默认(或根据存储介质的最小存储单元修改缓冲区大小)。


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

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

设备描述符保持默认。

四、SDIO

STM32 控制器可以控制使用单线或 4 线传输,本开发板设计使用 4 线传输。

4.1 参数配置

在 Connetivity 中选择 SDIO 设置,并选择 SD 4 bits Wide bus 四线SD模式


此时 SDIO 对应的管脚也被选中。


在 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 传输模式。

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

  • Priority:
    当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,DMA1 控制器拥有高于 DMA2 控制器的优先级。

  • Mode:
    Normal 表示单次传输,传输一次后终止传输。
    Circular 表示循环传输,传输完成后又重新开始继续传输,不断循环永不停止。

  • Increment Address:
    Peripheral 表示外设地址自增。
    Memory 表示内存地址自增。

  • Data Width:
    Byte 一个字节。
    Half Word 半个字,等于两字节。
    Word 一个字,等于四字节。

4.3 配置NVIC

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


五、生成代码

输入项目名和项目路径


选择应用的 IDE 开发环境 MDK-ARM V5


每个外设生成独立的 ’.c/.h’ 文件
不勾:所有初始化代码都生成在 main.c
勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。


点击 GENERATE CODE 生成代码


六、修改usbd_storage_if.c

打开工程文件夹Application/User/USB_DEVICE/App下usbd_storage_if.c文件


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线连接到电脑上,识别出为大容量存储设备

注意: 如果设备带有感叹号,则参考下面九、注意事项


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


文件系统选择FAT模式


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


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



八、工程代码

链接:https://pan.baidu.com/s/1b-C7dXodTB4plI999KWJMw?pwd=xy1z
提取码:xy1z

九、注意事项

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


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



关键字:STM32CubeMX  USB接口  MSC  SD卡  模拟U盘 引用地址:STM32CubeMX学习笔记(49)——USB接口使用(MSC基于SD卡模拟U盘)

上一篇:STM32CubeMX学习笔记(50)——USB接口使用(DFU固件升级)
下一篇:STM32CubeMX学习笔记(48)——USB接口使用(MSC基于外部Flash模拟U盘)

推荐阅读最新更新时间:2026-03-25 12:11

STM32 USB NAND Flash模拟U盘无法格式化问题的解决
前几天,一直在寻找NAND Flash模拟U盘程序无法格式化的问题。在中秋月圆之夜,还苦逼地在实验室调代码,也许是杭州大圆月的原因,今晚感觉整人特别亢奋,效率也特别高,灵感也多。终于,在不懈的努力下,找到代码中的害群之马,把无法格式的问题解决掉了。下面就来说说。 这几天一直在想问题出在哪里,不知道自己的代码跟官方的例程对照了多少次,把不一样的地方全都改了一遍,最终未果。今晚思路特别清晰,于是在想到格式化实际上就是向存储器写数据而已,而设计到写数据部分的代码就只在mass_mal.c、memory.c以及存储器的驱动文件。于是反复检查这几个文件,终于发现一点端倪了,问题出在memroy.c这个文件里。 memory.c这个文件只有两
[单片机]
泰昂能源推出MSC3060移动储能一体机
  为助力快速实现“双碳”目标和新型电力系统建设,加强“双碳”目标下的智能配电网技术研发布局,泰昂能源创新推出“MSC3060移动储能一体机”。   高度集成的移动储能充电创新设备,采用磷酸铁锂电池储能系统,配置40kW直流充电桩及应急照明灯具等,适用于光伏消纳、过载治理、低电压治理、削峰填谷、后备电源、移动充电桩、应急照明等多种场景,为客户提供安全智能、绿色高效的供配电保障设备与服务,适配新型电力系统背景下配网保供电场景。   泰昂能源的新能源研发团队从客户实际需求出发,在应用场景、系统结构、运行控制以及智能运维方面不断开拓创新,采用模块化结构设计“MSC3060移动储能一体机”,以一机多用的功能,
[新能源]
基于MSC1210的网络化数据采集系统的设计
  MSC1210采用增强型8051内核,时钟频率高达33MHz,它有3个独立的16位定时/计数器,1个片内看门狗、2个通用异步收发器,片内存储器包括闪速程序存储器、FLASH存储器(可以分区成程序存储器或数据存储器)、静态数据存储器等。另外,MSC1210还在片内固化了2KB的BOOT ROM,可以引导程序的写入,免去了程序写入时使用编程器的麻烦,MSC1210片内FLASH存储器的烧写寿命高达100万次,程序保存时间长达100年之久。该芯片已经在内部将数字和模拟电源分隔开来,两者都可以在2.7V~5.5V之间选取,这样用户可以将模拟部分和数字部分分开供电,可以有效地降低系统的噪声,提高A/D转换精度。   MSC1210是一
[单片机]
基于<font color='red'>MSC</font>1210的网络化数据采集系统的设计
MSC-51单片机的3字节和4字节浮点数计算程序分析
MSC-51 3字节和4字节浮点数计算程序,主要用于数据采集及上传,经过IEEE转换,在上位机直接显示。 ;这是本人使用的MSC-51 3字节和4字节浮点数计算程序,主要用于数据采集及上传,经过IEEE转换,在上位机直接显示。 ; FLOATING PROGRAM ;########################################## ;########################################## ;----------------------------------------------- ; IEEE754 FLOAT CONVERT TO 4 BYTES FLOAT ; IN
[单片机]
<font color='red'>MSC</font>-51单片机的3字节和4字节浮点数计算程序分析
基于MSC51系列的LCD1602通用程序
#include reg52.h #define PORT P2 sbit RS = P3^5; //1602的数据/指令选择控制线 sbit RW = P3^6; //1602的读写控制线 sbit EN = P3^7; //1602的使能控制线 unsigned char code table = LCD1602 check ok ; //要显示的内容1放入数组tablel unsigned char code table1 = study up ; //要显示的内容2放入数组table1 void DelayXms(unsigned int time) //延时程序,大约1ms {
[单片机]
基于MSC1210Y5的多通道数据采集系统
1 引言 以MSC1210Y5为核心的数据采集部分在工作时投放与水下、工作在无人值守的自容方式。由于海洋环境恶劣,所以仪器必须具有很好的可靠性及精确度,否则,就有可能给航行在测点附近海域的船舶提供不准确的海洋环境参数,笔者在灯船水文气象实测数据自动显示助航系统水下分机的设计中,成功应用了具有增强型8051内核微控制器和闪存的精密模数转换器MSC1210Y5,避免了微控制器和AD转换电路的单独分立设计,简化了电路,降低了功耗,增强了可靠性,提高了整个系统的工作速度。 2 MSC1210Y5的特性 MSC1210Y5是TQFP-64封装的低功耗完全集成混合信号IC,供电电压为2.7V-5.25V,它具有高精度的积分型模数转换器,ADC
[单片机]
基于<font color='red'>MSC</font>1210Y5的多通道数据采集系统
MSC Software一体化疲劳寿命预测解决方案
在市场竞争日益激烈的今天,各公司都在寻求既提高产品质量、性能以及耐久性,还能缩短产品开发周期的方法。现代产品的复杂性要求使用计算机工程分析来优化产品设计,从而提高其市场竞争力。 通过在计算机里快速有效地改变结构的设计参数,而不用建造试验模型,这样的分析大大降低了产品的开发成本。对于目标是预测应力或应变的结构分析,这些典型参数包括几何外形的改变、外载、材料的选择。然而,应力的预测仅仅是产品结构优化设计的一部分。在产品设计过程中,计算机工程分析的另一主要需求是估算产品的使用寿命。因此,通过分析法来预测疲劳寿命是一重要工具。 在方案设计阶段,设计者和工程师们经常使用简单手册的计算结果来评价产品的耐久性。然而,经常在开发周期的测试阶段或
[测试测量]
MSC51单片机交通灯程序
/*************************************************************** * 程序名称:MSC51单片机交通灯 晶振:12.00 P1口 * 实验对象:HC6800单片机学习开发板 * 单 片 机:AT89S52或STC89C52 时间:红绿灯各亮10s * * 更多的资料和程序共享请关注51hei.com ****************************************************************/ /#include reg52.h #define uchar unsigned char /*宏定义 */ #defin
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved