上位机图像处理和嵌入式模块部署(h750 mcu和usb虚拟串口)

发布于:2024-06-19 ⋅ 阅读:(166) ⋅ 点赞:(0)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        对于mcu usb而言,大部分情况下,它和上位机之间的关系都是device的关系。一般usb,可以分成host和device。如果mcu是host,那么意味着它可以主动访问别的usb设备,比如u盘、相机之类的设备。如果是device呢,这种情况下,mcu就是被别人访问,也就是说mcu会把自己伪装成一个u盘、camera或者串口这样的设备。

        另外不知道大家注意没有,很多的usb模块,里面本身没有usb转232的芯片,但是照样被识别成了com设备,道理就在这。因为mcu固件里面把会usb虚拟成com设备。

1、usb cdc虚拟串口和传统usb转串口的区别

        差别之处其实比较好分辨,前者是通过固件代码的形式实现的;而后者,一般都是需要添加一个usb转232的芯片实现。

2、usb cdc虚拟串口的好处

        把mcu的usb虚拟成一个串口,不仅速度比较快,没有波特率的限制,使用上面也比较简单,也没有额外的成本困扰。

3、cdc的目录结构

        stm32目前大部分mcu都支持cdc结构,大家只需要把对应的代码copy过来,会使用即可,不用过度追究里面的原理。

4、main函数的启动流程

        这部分代码其实和之前其他mcu的代码没有区别。在进行了usb设备的初始化,即调用MX_USB_DEVICE_Init函数之后,就是打印数据和接收数据。当然,mcu启动之后,需要一个type c的线连接到电脑上面。这个时候电脑的设备管理器就会生成一个新的com节点。我们借助于上位机串口打印工具,open这个com点之后,就可以看到对应的发送内容,以及接收的内容。

int main(void)
{
	SCB_EnableICache();		
	SCB_EnableDCache();		
	HAL_Init();					
	SystemClock_Config();	
	LED_Init();					
	
	MX_USB_DEVICE_Init();	
	
	USB_printf("STM32H750 virtual usb test\r\n");	
	
	while (1)
	{
		USB_printf("1234567abcdefg\r\n");
		LED1_Toggle;
		HAL_Delay(1000);
		USB_getf();
	}
}

5、usb发送

        这里面发送的函数就是USB_printf,我们可以简单看下这个函数是怎么实现的。实现的文件来自于usbd_cdc_if.c,

void USB_printf(const char *format, ...)
{
	va_list args;					
	uint32_t length;			
	uint16_t	 USB_TimeOut;	
	uint32_t  Tickstart;			
	
	va_start(args, format);	
	length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args);
	va_end(args);					

	USB_TimeOut = 3;	
	if( hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED )		
	{
		USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;	
	
		Tickstart = HAL_GetTick();		
		while(hcdc->TxState !=0)		
		{
			if((HAL_GetTick() - Tickstart) > USB_TimeOut)
			{
				break;
			}
		}
	}		

	CDC_Transmit_FS(UserTxBufferFS, length); 
}

6、usb接收

        大家如果留心一下就会发现,刚才usb发送的时候,都是把数据copy到UserTxBufferFS里面的。其实接收数据也一样,整个接收区的内容,都是放在UserRxBufferFS缓存里面。这就意味着,我们检查UserRxBufferFS空间就可以拿到里面的内容,有数据可以打印出来,没有就算了。

void USB_getf(void)
{
	int num= strlen((const char*)UserRxBufferFS);
	if(num > 0)
	{
		USB_printf("%s", UserRxBufferFS);
		memset(UserRxBufferFS, 0, num+1);
	}
}

7、测试和验证

        和前面几次打印、测试不一样,这一次的打印是通过usb线虚拟的串口实现的。这样的话就不需要实际的usb转串口工具。一个st-link v2烧录器,一个type c的线,就可以和pc电脑之间实现数据通信了。最后,还是建议大家可以把重点放在如何使用cdc、如何使用usb虚拟串口上面。等到用起来,比较熟练了,再去看usb cdc和usb协议的实现细节,这样更加稳妥。


网站公告

今日签到

点亮在社区的每一天
去签到