嵌入式STM32 USB通信

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

一、引言

在嵌入式系统开发中,USB(Universal Serial Bus)通信是一种广泛应用的通信方式。STM32微控制器系列提供了强大的USB外设支持,能够实现多种USB通信功能,如USB设备、USB主机等。本文将详细介绍STM32的USB通信,包括基本原理、硬件连接、软件实现以及代码示例。

二、STM32 USB通信基本原理

2.1 USB协议概述

USB是一种通用的串行通信协议,具有高速、可靠、易于使用等特点。USB协议定义了设备和主机之间的通信方式、数据传输格式以及设备的枚举过程。USB设备在连接到主机后,需要经过枚举过程,主机才能识别设备的类型和功能,并为其分配相应的驱动程序。

2.2 STM32 USB外设

STM32微控制器集成了USB外设,不同系列的STM32芯片可能支持不同的USB标准,如USB 2.0。USB外设主要包括USB控制器、端点(Endpoint)和缓冲区等部分。端点是USB通信的基本数据传输单元,每个端点有不同的方向(输入或输出)和类型(控制、批量、中断、同步)。

三、硬件连接

3.1 USB接口

STM32芯片通常具有专门的USB引脚,如D+和D-。这些引脚需要连接到USB接口,常见的USB接口有Mini - USB、Micro - USB等。在连接时,需要注意引脚的电平匹配和信号完整性。

3.2 上拉电阻

对于USB设备模式,需要在D+引脚上连接一个上拉电阻(通常为1.5KΩ),以便主机能够检测到设备的连接。

3.3 电源

USB接口可以为STM32芯片提供电源,同时也需要注意电源的稳定性和滤波处理。

四、软件实现

4.1 开发环境

使用STM32CubeMX工具进行工程配置和初始化代码生成,结合Keil MDK或GCC等编译器进行代码编译和调试。

4.2 配置USB外设

在STM32CubeMX中,选择相应的STM32芯片型号,然后在“Pinout & Configuration”选项卡中配置USB外设。选择USB设备模式,并配置端点的参数,如端点类型、缓冲区大小等。

4.3 生成代码

配置完成后,点击“Generate Code”生成初始化代码。生成的代码包含了USB外设的初始化、中断处理等基本功能。

4.4 编写应用代码

在生成的代码基础上,编写应用代码实现具体的USB通信功能。以下是一个简单的USB设备(虚拟串口)通信的代码示例:

#include "stm32f1xx_hal.h"
#include "usbd_cdc_if.h"

extern USBD_HandleTypeDef hUsbDeviceFS;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USB_DEVICE_Init(void);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();

  uint8_t buffer[] = "Hello, USB Communication!\r\n";
  uint16_t length = sizeof(buffer);

  while (1)
  {
    if (CDC_Transmit_FS(buffer, length) == USBD_OK)
    {
      HAL_Delay(1000);
    }
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

static void MX_USB_DEVICE_Init(void)
{
  USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
  USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
  USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
  USBD_Start(&hUsbDeviceFS);
}

void Error_Handler(void)
{
  while(1)
  {
  }
}

代码解释

  1. 初始化部分:在main函数中,首先调用HAL_Init进行HAL库的初始化,然后依次调用SystemClock_ConfigMX_GPIO_InitMX_USB_DEVICE_Init进行系统时钟、GPIO和USB设备的初始化。
  2. 数据发送:定义了一个包含字符串的缓冲区buffer,并在主循环中通过CDC_Transmit_FS函数将数据发送到主机。如果发送成功,程序会延时1秒后再次发送。
  3. USB设备初始化:在MX_USB_DEVICE_Init函数中,调用USBD_Init初始化USB设备,USBD_RegisterClass注册USB设备类(这里是虚拟串口类),USBD_CDC_RegisterInterface注册接口函数,最后调用USBD_Start启动USB设备。

五、USB设备枚举过程

当USB设备连接到主机后,会经历以下枚举过程:

  1. 设备连接检测:主机检测到USB设备的连接,通过D+和D-线上的电平变化判断设备的连接状态。
  2. 复位设备:主机向设备发送复位信号,设备接收到复位信号后进行复位操作,将所有寄存器和端点恢复到初始状态。
  3. 获取设备描述符:主机向设备发送请求,获取设备的描述符信息,包括设备的厂商ID、产品ID、设备版本等。
  4. 配置设备:主机根据设备描述符信息,为设备选择合适的配置,并向设备发送配置请求。
  5. 设备就绪:设备完成配置后,进入就绪状态,可以进行数据传输。

六、注意事项

  1. 电源管理:USB设备在通信过程中需要注意电源的稳定性,避免因电源波动导致通信错误。
  2. 数据传输速率:不同的USB设备类和端点类型支持不同的数据传输速率,需要根据实际需求进行选择。
  3. 中断处理:USB通信涉及到大量的中断处理,需要确保中断服务函数的执行时间尽可能短,避免影响系统的实时性。

七、总结

STM32的USB通信功能为嵌入式系统开发提供了强大的支持。通过合理配置硬件和编写软件代码,可以实现各种USB通信应用,如虚拟串口、USB存储设备等。在开发过程中,需要深入理解USB协议和STM32 USB外设的工作原理,同时注意电源管理、数据传输速率和中断处理等问题,以确保通信的稳定性和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值