通常我們使用STM32進(jìn)行串口通信會(huì)選擇其硬件串口,但在某些情況下串口會(huì)不夠用,這個(gè)時(shí)候就可以選擇USB的虛擬串口,這樣可以增加一個(gè)串口。
USB是非常復(fù)雜的一個(gè)設(shè)備,要想完全搞懂它需要花費(fèi)不少時(shí)間和精力。但去使用它卻相對(duì)簡(jiǎn)單。這里我們使用STM32CubeMX構(gòu)建一個(gè)初始工程,然后實(shí)現(xiàn)將我們從電腦發(fā)下來的東西原封不動(dòng)地發(fā)回電腦,使用的芯片是STM32F103zet6。
USB需要配置兩個(gè)地方,一個(gè)是Connectivity下勾選USB,在Mode下勾選Device,下面的參數(shù)保持默認(rèn)即可。其他芯片類型的選項(xiàng)可能不同,選擇有Device字樣的就OK。
第二在Middleware下選擇USB_DEVICE,在右邊的下拉菜單選擇Communication Device Class(Virtual Port Com),下面的參數(shù)設(shè)置可以保持默認(rèn),除非你了解各個(gè)參數(shù)是干什么的,否則不建議修改。這些參數(shù)涉及到了USB的設(shè)備描述符、字符串描述符、緩存等等。
其他配置包括時(shí)鐘、工程路徑、工具鏈、驅(qū)動(dòng)設(shè)置等等就不羅嗦了,配置好后點(diǎn)擊生成代碼,我使用gcc編譯。
USB虛擬串口涉及的文件有下面三類:
底層
中間層
應(yīng)用層
實(shí)際使用的時(shí)候只需要關(guān)心應(yīng)用層即可。
在編譯下載之前,我們需要在電腦安裝STM32提供的虛擬串口驅(qū)動(dòng),這在他們的官網(wǎng)可以下載到。
驅(qū)動(dòng)安裝好后,接下來看看如何實(shí)現(xiàn)數(shù)據(jù)的收發(fā)。
在usb_device.c文件下實(shí)現(xiàn)了USB設(shè)備的初始化,只需要調(diào)用它就完成了所有的USB初始化工作。
通過在main中調(diào)用這個(gè)函數(shù),電腦就已經(jīng)可以將芯片的USB識(shí)別為一個(gè)串口了。進(jìn)一步詳細(xì)內(nèi)容就不展開了,以后會(huì)專門發(fā)文介紹USB。
上面的VID和PID可以在文件usbd_desc.c中找到,設(shè)備描述符就在這個(gè)文件中。
OK,現(xiàn)在虛擬串口正確識(shí)別了,下面就是數(shù)據(jù)的收發(fā)了。
數(shù)據(jù)收發(fā)的接口在usbd_cdc_if.c文件下。
這里可以看到接收用了static關(guān)鍵字,說明它只能在本文件中使用,不可以外部調(diào)用。發(fā)送我們可以直接調(diào)用。這里先介紹發(fā)送吧。
發(fā)送
如果是發(fā)送原始數(shù)據(jù),可以直接將數(shù)據(jù)打包成數(shù)組,然后調(diào)用函數(shù)發(fā)送即可。但通常我們用串口打log,所以這里可以構(gòu)造一個(gè)printf函數(shù)。
這樣使用USB虛擬串口打印東西就非常方便了。這里要注意buff要夠大,否則會(huì)出現(xiàn)發(fā)送亂碼或不全的問題。
接收
USB虛擬串口的接收采用了中斷方式,芯片接收到數(shù)據(jù)后中斷回調(diào)函數(shù)會(huì)調(diào)用CDC_Receive_FS()函數(shù)接收數(shù)據(jù),然后將數(shù)據(jù)放到接收緩存中。但是軟件沒有提供直接獲得數(shù)據(jù)和個(gè)數(shù)的接口。所以我采取了一種簡(jiǎn)單暴力的方式來獲取數(shù)據(jù)和數(shù)據(jù)個(gè)數(shù)。
收到數(shù)據(jù)后,數(shù)據(jù)的緩存指針通過參數(shù)Buf傳進(jìn)來,數(shù)據(jù)個(gè)數(shù)通過參數(shù)Len傳進(jìn)來。上面三個(gè)extern的變量在main文件中定義,get_data_flag標(biāo)志是否收到數(shù)據(jù),buf存放數(shù)據(jù),data_nums存放數(shù)據(jù)個(gè)數(shù)。由于USB虛擬串口一次最多接收64字節(jié),如果收到的數(shù)據(jù)多于64字節(jié),會(huì)連續(xù)調(diào)用多次接收函數(shù),上圖中的方法理論上可以任意接收不超過buf大小個(gè)字節(jié)。
在main.c中的情況如下所示:
運(yùn)行效果如下圖所示:
使用虛擬串口波特率不起作用,任何波特率都可以用。
在main中我們還發(fā)現(xiàn)有一個(gè)USB_Status_Init()函數(shù),這個(gè)函數(shù)用來復(fù)位USB口。如果沒有這個(gè)函數(shù),每次下載完程序后需要重新插拔usb線電腦才能識(shí)別到,有了它就可以不用拔插線了。
原理也很簡(jiǎn)單,就是讓USB的兩個(gè)Pin都是低電平持續(xù)幾個(gè)毫秒即可。
OK,關(guān)于STM32的USB虛擬串口就介紹到這里了,很多細(xì)節(jié)我也不甚了解,希望看到本文的小伙伴能指正補(bǔ)充。
-
usb
+關(guān)注
關(guān)注
60文章
7936瀏覽量
264465 -
STM32
+關(guān)注
關(guān)注
2270文章
10895瀏覽量
355727 -
串口
+關(guān)注
關(guān)注
14文章
1551瀏覽量
76421 -
虛擬串口
+關(guān)注
關(guān)注
3文章
62瀏覽量
13876 -
stm32cubemx
+關(guān)注
關(guān)注
5文章
283瀏覽量
14791
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論