STM32F407 CUBEMX RT-Thread USB虚拟串口(VCP)
记录一下STM32平台下使用RT-Thread使用VCP
- 首先确定HAL_Drivers下是否有RT-Thread提供的文件drv_usbd.c
- 使用notepad++ 打开HAL_Drivers文件夹下的SConscript会发现RT-Thread官网已经写好相关的代码了,我们只需要在menuconfig里面配置BSP_USING_USBD,相关代码就会加入到我们的项目里面
- 确定项目工程board文件夹下Kconfig是否有BSP_USING_USBD配置如果没有就加上,根据上面的名称而定有些版本可能存在差异
menuconfig BSP_USING_USBD
bool "Enable USB"
default y
- menuconfig配置
. cubemx配置
注意:这里时钟根据个人的外部晶振决定,USB时钟必须是48M!!!完成后生成项目
- 系统时钟函数和USB驱动部分移植(根据情况!!)
这里我使用的是最新版的cubemx文档结构可能有些不同,src和inc在Core文件夹下将他复制粘贴出来
这里注意我们可能也动了时钟这些,那么我们则需要把board/CubeMX_Config/Src下的main.c的系统时钟函数void SystemClock_Config(void)覆盖到board/board.c下
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
- USB部分
在这个文件夹下找到USB初始化部分,因为RT-Thread系统会调用相关初始化
usbd_conf.c文件下的代码复制到stm32f4xx_hal_msp.c下就可以了
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(pcdHandle->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
/* USER CODE END USB_OTG_FS_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
/* USER CODE END USB_OTG_FS_MspInit 1 */
}
}
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
{
if(pcdHandle->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */
/* USER CODE END USB_OTG_FS_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
/**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */
/* USER CODE END USB_OTG_FS_MspDeInit 1 */
}
}
- 下载
完成之后检查USB接口连接和相关驱动是否安装成功后就会显示COM口
以下都有说明串口驱动移植完成
接着在main.c文件添加如下代码
#include <rtthread.h>
#include <rtdevice.h>
int main(void)
{
rt_device_t dev = RT_NULL;
char buf[] = "hello world!\r\n";
dev = rt_device_find("vcom");
if (dev)
rt_device_open(dev, RT_DEVICE_FLAG_RDWR);
else
return -RT_ERROR;
while (1)
{
rt_device_write(dev, 0, buf, rt_strlen(buf));
rt_thread_mdelay(500);
}
return RT_EOK;
}