【发布时间】:2021-11-23 14:35:18
【问题描述】:
我正在尝试弄清楚如何使基于 STM32F103 的 Blue Pill 板上的 USB VCP 功能在微控制器复位后运行,例如上传新代码后。
正如我现在所拥有的,VCP 一开始运行正常,但是在硬件重置后,PuTTY 停止从 VCP 报告任何新线路。不过,连接到UART1 的 FTDI 适配器继续工作。这是main.c的缩小版本:
#include "main.h"
#include "usb_device.h"
#include <string.h>
#include <usbd_cdc_if.h> // Necessary to avoid "warning: implicit declaration of function" for CDC_Transmit_FS()
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_USB_DEVICE_Init();
char msg[50];
HAL_StatusTypeDef ret_status = HAL_OK;
sprintf(msg, "Reset!\n");
ret_status = HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
uint8_t state = 0;
while (1) {
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
sprintf(msg, "Hello World! LED State: %d\n", state);
ret_status = HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
ret_status = CDC_Transmit_FS((uint8_t*)msg, strlen(msg));
HAL_Delay(500);
state = state == 1 ? 0 : 1;
}
}
在阅读 this SO Q/A 时,我了解到该问题可能是由于主机未识别客户端设备已重置(因此需要重新初始化),因为 D+ 行是从来没有拉下来。但是,我不明白在哪里/如何为此应用修复程序。我尝试将一对HAL_GPIO_WritePin 和HAL_Delay 指令插入MX_USB_DEVICE_Init() 函数,如下所示:
void MX_USB_DEVICE_Init(void)
{
/* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(100);
/* USER CODE END USB_DEVICE_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
{
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
/* USER CODE END USB_DEVICE_Init_PostTreatment */
}
但是没有效果。我还尝试更改指令以将引脚拉到GPIO_PIN_RESET,以防我误解了哪个常数对应于逻辑低,但它也没有任何效果。据我所知,这应该具有应用0___________'s answer 中描述的修复的效果,但我一定误解了这个问题。有谁知道如何解决这个问题?
解决方案(2021 年 10 月 22 日)
根据@Flexz's answer below,我在MX_USB_DEVICE_Init()函数的修改中添加了代码如下:
void MX_USB_DEVICE_Init(void)
{
/* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
/*Configure GPIO pin : PA12 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
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);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_Delay(100); // Actually unnecessary (from my testing) and can be removed without consequence.
/* USER CODE END USB_DEVICE_Init_PreTreatment */
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK)
{
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK)
{
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */
/* USER CODE END USB_DEVICE_Init_PostTreatment */
}
我根据 STM32CubeMX 生成的代码对此进行了修改,以配置 Blue Pill 的绿色 SMD LED (PC13)。至少对我来说,这使得 VCP 在 MCU 重置后再次起作用,尽管 PuTTY 仍然抱怨并且我必须手动重新启动它。 :)
【问题讨论】:
-
重置后需要强制主机开始枚举。这是通过设置线路上的信号电平来完成的(主机需要知道新设备已连接 - 而重置实际上是新设备的连接)
-
Heyo @0______,欢迎回来 :) 我不确定我是否按照您在此处描述的步骤...如何从 STM32 端转换为 GPIO 命令?
标签: c usb stm32 stm32cubeide