利用STM32CUBE创建一个虚拟串口由于现在的PC机大多都没有串口了,但PC机上的很多应用程序却使用串口,为了让PC机与STM32处理器进行通信,可以让STM32处理器,以串行方式与外界进行通信,再用CH340等芯片,实现USB转串口的功能,实现虚拟串口。不过这样做需要额外的芯片和相关电路,不很理想。利用STM32处理器自身的USB功能,就可以实现虚拟串口。由于USB是一个很复杂的东西,所对应的代码很多,如果采用操作寄存器或标准库的方式,都要编写很多代码,也容易出错,而采用STM32CUBE就方便多了。首先要利用STM32CUBE,选择芯片,比如芯片型号为STM32F103ZET6,如下图所示:然后在Pinout选项页中,先选择“RCC”项,按下图设置:再选择“USB”选项,按下图设置:这一步的最后再选择“USB_DEBICE”,按下图设置:下面要设置时钟,进入“ClockConfiguration”选项页,按下图设置:请注意:上图的设置必须保障给USB模块的时钟信号是精准的48MHz,不允许有偏差。然后进行工程设置,点击菜单项“Porject→Settings...”,这时将弹出一个对话框窗口如下:在该对话框窗口上,输入工程名、工程存放的文件夹、所用的开发工具之后,点击“OK”按键,关闭该对话框。最后点击菜单项“Porject→GenerateCode”,生成工程。本人用的开发工具是IAR,打开该工程,如下图所示:这个工程已经包含了不少文件,建立了基本的程序框架和初始化代码,只要进一步添加应用程序代码就可以了。下面将围绕虚拟串口进一步编写程序:在这个工程中,有一个“usbd_cdc_if.c”文件,进行USB虚拟串口进行数据的发送和接收时,首先要在usbd_cdc_if.c文件中修改“APP_RX_DATA_SIZE”、“APP_TX_DATA_SIZE”两个宏,它们用于数据的接收和发送缓冲区的大小;然后要声明一个结构体(并初始化),其代码如下:USBD_CDC_LineCodingTypeDefLineCoding={115200,/*baudrate*/0x00,/*stopbits-1*/0x00,/*parity-none*/0x08,/*nb.ofbits8*/};这段代码用于指示串口的基本设置。在该文件的“CDC_Control_FS”函数中,在“CDC_SET_LINE_CODING:”下面,添加如下代码:pbuf[0]=(uint8_t)(LineCoding.bitrate);pbuf[1]=(uint8_t)(LineCoding.bitrate8);pbuf[2]=(uint8_t)(LineCoding.bitrate16);pbuf[3]=(uint8_t)(LineCoding.bitrate24);pbuf[4]=LineCoding.format;pbuf[5]=LineCoding.paritytype;pbuf[6]=LineCoding.datatype;这样之后,就可以使用虚拟串口了!当需要发送数据时,先将要发送的数据放入一个数组中(假设该数组名为a,要发送的n个字节),然后用如下代码就可以发送数据:CDC_Transmit_FS(a,n);如果还需要读取上位机传来的数据,要修改usbd_cdc_if.c文件中的CDC_Receive_FS函数,该函数原本为:staticint8_tCDC_Receive_FS(uint8_t*Buf,uint32_t*Len){/*USERCODEBEGIN6*/USBD_CDC_SetRxBuffer(hUsbDevice_0,&Buf[0]);USBD_CDC_ReceivePacket(hUsbDevice_0);return(USBD_OK);/*USERCODEEND6*/}该函数在收到数据时,将被系统调用,它的两个参数分别指向接收缓冲区和接收到的数据字节长度。显然我们可以编写一段代码,将接收到的数据送到应用程序指定的内存区,比如进行如下修改:staticint8_tCDC_Receive_FS(uint8_t*Buf,uint32_t*Len){/*USERCODEBEGIN6*/uint8_ti;USBD_CDC_SetRxBuffer(hUsbDevice_0,&Buf[0]);USBD_CDC_ReceivePacket(hUsbDevice_0);for(i=0;i*Len;i++)app_rx_buf[i]=Buf[i];//将收到的数据转移到app_rx_buf数组中rx_f=TRUE;//将收到数据标志位置位,用以通知应用程序return(USBD_OK);/*USERCODEEND6*/}这样就可以进行数据的上传和下传了。