99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何讓CDC類(lèi)USB設(shè)備批量接收64字節(jié)以上數(shù)據(jù)

茶話MCU ? 來(lái)源:茶話MCU ? 作者:茶話MCU ? 2022-10-31 10:54 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

很多STM32開(kāi)發(fā)者在實(shí)現(xiàn)CDC類(lèi)虛擬串口與PC主機(jī)通信過(guò)程中,有時(shí)會(huì)遇到點(diǎn)麻煩而不得其解。那就是當(dāng)主機(jī)端單次發(fā)送的數(shù)據(jù)不超過(guò)64字節(jié)時(shí),接收正常。一旦發(fā)送數(shù)據(jù)量大于64字節(jié)時(shí)就接收失敗,總是出現(xiàn)丟包現(xiàn)象,似乎只能接收64字節(jié)以?xún)?nèi)的數(shù)據(jù)。網(wǎng)上有人干脆建議主機(jī)每次發(fā)送不要超過(guò)64字節(jié),當(dāng)然,也有人提及要作分包處理但沒(méi)具體實(shí)現(xiàn)代碼可以參考。

2af41bee-572c-11ed-a3b6-dac502259ad0.png

作為CDC類(lèi)的USB設(shè)備,到底能不能正確接收來(lái)自主機(jī)64字節(jié)以上的批量數(shù)據(jù)呢?

其實(shí)是可以的,只是當(dāng)我們一次傳輸?shù)臄?shù)據(jù)大于當(dāng)前端點(diǎn)所支持的最大包長(zhǎng)時(shí)【這里端點(diǎn)使用BULK傳輸,一般最大包長(zhǎng)默認(rèn)設(shè)置為64字節(jié)】,USB模塊會(huì)做分包傳輸,將一批數(shù)據(jù)傳輸分成多個(gè)處理[或稱(chēng)事務(wù)],即多個(gè)transaction來(lái)完成,每個(gè)Transaction里的數(shù)據(jù)包傳輸?shù)淖畲髷?shù)據(jù)量為64字節(jié)。

2b16214e-572c-11ed-a3b6-dac502259ad0.png

原理性的東西,這里不多啰嗦了,網(wǎng)上有成堆的介紹資料【當(dāng)然,或許有點(diǎn)亂】。當(dāng)我們弄清整個(gè)原理后,就可以自行組織接收處理代碼了。下面我利用HAL庫(kù),基于STM32F429芯片演示實(shí)現(xiàn)過(guò)程,重點(diǎn)在接收處理代碼。我使用STM32F429Discovery開(kāi)發(fā)板,使用HSUSB模塊并令其工作在FSMODE,這樣我們就可以方便地使用片內(nèi)USBFS PHY。

2b888d4c-572c-11ed-a3b6-dac502259ad0.png

我使用STM32CubeMx工具進(jìn)行配置,生成基于STM32 HAL庫(kù)的工程。使用ST提供的STM32CubeIDE進(jìn)行編譯調(diào)試。有關(guān)配置就不截圖了。

另外,我還配置了1個(gè)按鍵并開(kāi)啟相應(yīng)外部中斷。每發(fā)生按鍵事件時(shí),F(xiàn)429USB設(shè)備向PC主機(jī)發(fā)送一段打招呼的字符串,并通過(guò)串口助手顯示出來(lái)。如下圖所示:

2bcd1674-572c-11ed-a3b6-dac502259ad0.png

我在main.c文件里額外定義了下面幾個(gè)變量:

2bfc75f4-572c-11ed-a3b6-dac502259ad0.png

其中,F(xiàn)lag_KeyPressed和Flag_DataReceived分別表示按鍵操作和收到從主機(jī)發(fā)過(guò)來(lái)的數(shù)據(jù)的情況。Rx_buffer【】數(shù)組用來(lái)存放接收來(lái)自主機(jī)的全部數(shù)據(jù),這里的定義長(zhǎng)度為512字節(jié)【你具體使用時(shí)按需設(shè)置】。下圖是Main.c里的主循環(huán)代碼截圖:

2c18ee14-572c-11ed-a3b6-dac502259ad0.png

主循環(huán)里檢查按鍵標(biāo)志和收到數(shù)據(jù)的標(biāo)志,如有按鍵發(fā)生,則向主機(jī)發(fā)送前面提到的打招呼的字符串;如有收到來(lái)自主機(jī)的數(shù)據(jù),則向主機(jī)回送過(guò)去。

今天的重點(diǎn)是討論USB設(shè)備如何從主機(jī)接收64字節(jié)以上的數(shù)據(jù)。基于現(xiàn)有HAL庫(kù),對(duì)于USB設(shè)備的接收,我們只需關(guān)注一個(gè)USB中斷接收回調(diào)函數(shù),那就是CDC_Receive_HS()函數(shù)。該函數(shù)在usbd_cdc_if.c文件里。我具體編寫(xiě)的函數(shù)代碼如下面兩幅截圖所示。

2c40952c-572c-11ed-a3b6-dac502259ad0.png

2c7e56e6-572c-11ed-a3b6-dac502259ad0.png

代碼很簡(jiǎn)單。 我在庫(kù)代碼的基礎(chǔ)上增加了橙色方框內(nèi)的代碼?;竟δ芫褪牵茸x取當(dāng)前收到的數(shù)據(jù)長(zhǎng)度【SinglePackLength】,分整包和非整包兩種情況鑒別后再處理。若是接收的整包數(shù)據(jù),繼續(xù)等待接收下一包;若是非整包,視為此次傳輸結(jié)束,并設(shè)置收到標(biāo)志Flag_DataReceived為非0值,然后在主循環(huán)里將收到的數(shù)據(jù)回送給主機(jī)。

其中,Max_Pack_Size是當(dāng)前CDC類(lèi)BULK傳輸端點(diǎn)的最大傳輸包長(zhǎng),這里為64字節(jié)。

Num_Rx_Data表示接收到數(shù)據(jù)個(gè)數(shù),Num_Out_Pack表示接收到的數(shù)據(jù)包個(gè)數(shù),Num_Packet跟Num_Out_Pack內(nèi)容一樣,不過(guò),Num_Packet等于0還表示準(zhǔn)備開(kāi)始新一輪傳輸?shù)慕邮?。這里多定義Num_Out_Pack,一個(gè)重要目的是便于調(diào)試時(shí)查看結(jié)果。

基于上面的接收處理代碼,我們來(lái)驗(yàn)證結(jié)果:

2cdbacb0-572c-11ed-a3b6-dac502259ad0.png

借助PC端的串口助手向STM32F429 USB設(shè)備發(fā)送了5個(gè)字符,我們通過(guò)STM32CubeIDE調(diào)試環(huán)境可以清晰地從上圖看到設(shè)備收到的數(shù)據(jù)個(gè)數(shù)為5,數(shù)據(jù)包個(gè)數(shù)為1。顯然沒(méi)問(wèn)題。那個(gè)Rx_buffer數(shù)組是我用來(lái)存放接收數(shù)據(jù)的,若在調(diào)試窗口打開(kāi),數(shù)據(jù)較多列表顯示會(huì)很長(zhǎng),這里就沒(méi)打開(kāi)了。事實(shí)上接收的數(shù)據(jù)內(nèi)容也是沒(méi)問(wèn)題的。

下圖是借助PC端的串口助手向STM32F429 USB設(shè)備發(fā)送了305個(gè)字符的接收情況:

2cfe83b6-572c-11ed-a3b6-dac502259ad0.png

顯然,對(duì)于305個(gè)字符,PC主機(jī)端要分成5包才能發(fā)送完畢,即4整包【每包64字節(jié)】再加1個(gè)非完整包。所以USB設(shè)備接收結(jié)果也正好是5包,即上圖中Num_Out_pack的數(shù)據(jù),接收到的數(shù)據(jù)量為305,即上圖中Num_Rx_Data的數(shù)據(jù)。同樣,結(jié)果OK。

下圖是PC端剛好發(fā)送一個(gè)完整包64字節(jié)數(shù)據(jù)的USB設(shè)備接收情況,也一切正常。

2d42e57e-572c-11ed-a3b6-dac502259ad0.png

也就是說(shuō),使用我上面編寫(xiě)的接收處理代碼,對(duì)主機(jī)發(fā)送的數(shù)據(jù)的個(gè)數(shù)不再局限于64字節(jié)以?xún)?nèi)了。當(dāng)然,具體應(yīng)用時(shí)我們還可以根據(jù)主機(jī)端單次傳輸數(shù)據(jù)的大小情況及提取數(shù)據(jù)的方式適當(dāng)調(diào)整這里的Rx_buffer[]數(shù)組大小?!咀ⅲ荷厦鏈y(cè)試時(shí)我臨時(shí)關(guān)閉了設(shè)備端的數(shù)據(jù)回送功能,是為了避免截圖里的數(shù)據(jù)混亂,讓人分不清原數(shù)據(jù)和回顯數(shù)據(jù)】

有人可能在上面的接收代碼里看到了一個(gè)變量Wait_Rx_Dly。剛開(kāi)始,代碼里是沒(méi)有這個(gè)變量的。后來(lái)我在測(cè)試主機(jī)發(fā)送64字節(jié)整包數(shù)據(jù)時(shí),發(fā)現(xiàn)了一個(gè)小問(wèn)題【最終到底算不算問(wèn)題,或許要視具體應(yīng)用場(chǎng)景而定,我這里稍作了點(diǎn)處理】。

問(wèn)題是這樣的:

主機(jī)每發(fā)送1包64字節(jié)數(shù)據(jù)時(shí),設(shè)備端接收沒(méi)有問(wèn)題,但只要主機(jī)端每次發(fā)送64字節(jié)完整數(shù)據(jù)包過(guò)來(lái),不論相隔時(shí)間多久,設(shè)備端依然接收,且總在前次結(jié)果上累加,除非主機(jī)端發(fā)一個(gè)非64字節(jié)數(shù)據(jù)包過(guò)來(lái),設(shè)備接收就總是視為同一次傳輸。比方像下面截圖所示:

2d76b58e-572c-11ed-a3b6-dac502259ad0.png

上圖就是PC主機(jī)端借助串口助手分四次且每次發(fā)送64字節(jié)數(shù)據(jù)時(shí)USB設(shè)備的接收情況。從圖上不難看出,4次數(shù)據(jù)都匯集在一起了,關(guān)鍵還沒(méi)完,還在等待后續(xù)數(shù)據(jù)過(guò)來(lái)。我是希望一次傳輸做一次處理,于是我讓設(shè)備每收到一個(gè)完整數(shù)據(jù)包,就重新給定一個(gè)延時(shí),比方3~5ms,用變量Wait_Rx_Dly來(lái)記錄延時(shí)值,在某毫秒定時(shí)中斷里對(duì)該變量做減1操作。若延時(shí)到了還沒(méi)有收到數(shù)據(jù)或延時(shí)過(guò)程中收到非完整包則視為本次傳輸結(jié)束,然后去處理剛才收到的數(shù)據(jù)。

2d9c6158-572c-11ed-a3b6-dac502259ad0.png

我順便使用了HAL庫(kù)里自帶的systick中斷函數(shù)來(lái)做這個(gè)延時(shí)管理。當(dāng)接收處理代碼加上這個(gè)延時(shí)管理后,就不會(huì)出現(xiàn)不同傳輸批次的數(shù)據(jù)擠在一塊了。問(wèn)題得以解決。

另外,我上面分享的接收處理代碼也有很好的通用性,并不局限于Bulk傳輸。我們知道,不同傳輸類(lèi)型的端點(diǎn)的最大包長(zhǎng)往往并不一樣,如果使用上面的參考代碼,我們只需調(diào)整那個(gè)最大包長(zhǎng)參數(shù)【Max_Pack_Size】,并適當(dāng)調(diào)整Rx_buffer[]數(shù)組的大小就可以使用了。數(shù)據(jù)個(gè)數(shù)、傳輸包個(gè)數(shù)這些變量都可以保留使用。

那段接收處理代碼很簡(jiǎn)單,看懂了都可以自行組織編寫(xiě)。順便說(shuō)下,我使用的STM32F4系列的Cube庫(kù)版本為STM32F4xx HALV1.8.1。好,今天的話題就分享到這里,希望幫到有需要的人。祝君好運(yùn)!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    8166

    瀏覽量

    271971
  • STM32
    +關(guān)注

    關(guān)注

    2291

    文章

    11026

    瀏覽量

    363776
  • CDC
    CDC
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    18177

原文標(biāo)題:如何讓CDC類(lèi)USB設(shè)備批量接收64字節(jié)以上數(shù)據(jù)

文章出處:【微信號(hào):stmcu832,微信公眾號(hào):茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    做STM32f103 USB雙緩存的時(shí)候,發(fā)送4K數(shù)據(jù)里面前64字節(jié)是0,為什么?

    做STM32f103 USB 雙緩存的時(shí)候, 采取ENP3的TXaddr1和TXaddr0的雙緩存ping-pong發(fā)送機(jī)制,每次上位機(jī)接收完4K數(shù)據(jù), 4K數(shù)據(jù)
    發(fā)表于 04-28 07:07

    用ESP32發(fā)送數(shù)據(jù),串口最大接收120字節(jié)就進(jìn)入中斷了,如何才能接收2048字節(jié)數(shù)據(jù)

    請(qǐng)教一個(gè)問(wèn)題,我現(xiàn)在用ESP32發(fā)送數(shù)據(jù),串口最大接收120字節(jié)就進(jìn)入中斷了,我更改了uart_driver_install中.rxfifo_full_thresh
    發(fā)表于 06-20 06:43

    在進(jìn)行USB CDC類(lèi)開(kāi)發(fā)時(shí),無(wú)法發(fā)送64整數(shù)倍的數(shù)據(jù)

    ,就是是最多兩包數(shù)據(jù)。如果需要發(fā)送超過(guò)127個(gè)字節(jié)時(shí),又該如何做呢?查看USB協(xié)議棧內(nèi)核代碼,發(fā)現(xiàn)每次端點(diǎn)0發(fā)送數(shù)據(jù)時(shí),在發(fā)送代碼中固定每次最多可以傳輸
    發(fā)表于 03-28 13:30

    如何將配置端點(diǎn)緩沖區(qū)的大小配置為64字節(jié)

    你好,我在CyPress CY7C68013A高速控制器上工作。如何將配置端點(diǎn)緩沖區(qū)的大小配置為64字節(jié)(如全速),用于批量傳輸。我的主機(jī)還支持USB 2高速,但由于項(xiàng)目的典型性質(zhì),我
    發(fā)表于 05-09 16:07

    USBUART_PutData()不適用于64字節(jié)

    你好!我正在測(cè)試USB CDC示例項(xiàng)目,不能讓它發(fā)送64字節(jié)數(shù)據(jù),雖然這等于最大數(shù)據(jù)包大小,應(yīng)
    發(fā)表于 06-21 11:37

    如何解決傳輸64字節(jié)字符串時(shí)USB UART出現(xiàn)的問(wèn)題

    應(yīng)該發(fā)送64字節(jié)數(shù)據(jù)包后發(fā)送10數(shù)據(jù)包長(zhǎng)度。在PC的司機(jī)會(huì)知道該字符串只有在收到這個(gè)零長(zhǎng)度數(shù)據(jù)包的接收
    發(fā)表于 07-18 14:57

    如何使用Encore II的64字節(jié)控制傳輸字節(jié)?

    我在EnCORE 2中的USB組件控制端點(diǎn)大小只有8字節(jié)。在我的應(yīng)用程序中,我需要傳輸64字節(jié)。如何做到這一點(diǎn)?控制端點(diǎn)是一個(gè)雙向端點(diǎn),它使用相同的緩沖器(UBSI接口
    發(fā)表于 08-13 09:38

    USB CDC吞吐量問(wèn)題

    我從論壇上閱讀CDC的所有內(nèi)容中得知,我的申請(qǐng)應(yīng)該只是學(xué)術(shù)性的,并且遲疑不決。我的實(shí)時(shí)要求是在250毫秒內(nèi)傳輸115200字節(jié)(吞吐量460800字節(jié)/秒)。從PIC32到PC??蛻粜枰麄兊腜C
    發(fā)表于 10-14 15:52

    USB CDC數(shù)據(jù)損壞:傳輸?shù)?2被接收為0

    是:.(!{發(fā)送4096字節(jié)數(shù)據(jù)到微告訴微寫(xiě)數(shù)據(jù)到閃存}數(shù)據(jù)被精確地寫(xiě)入閃存,因此我知道我的閃存可以,但是看起來(lái)發(fā)送值32(0x20)被接收
    發(fā)表于 10-21 14:14

    大于64字節(jié)傳輸?shù)?b class='flag-5'>USB HID—描述符中要更改什么?

    ,如果需要的話,它將把一個(gè)事務(wù)分成多個(gè)64字節(jié)數(shù)據(jù)包。用這個(gè)?我仍然在Microchip應(yīng)用程序庫(kù)的版本2.9的USB堆棧上。謝謝。
    發(fā)表于 05-06 13:21

    為什么我在512字節(jié)數(shù)據(jù)緩沖區(qū)傳輸數(shù)據(jù)卻得到1536字節(jié)

    我正在使用 STM32L4R5ZI-P 開(kāi)發(fā)板。我已將 USB 配置為僅具有 CDC 類(lèi)設(shè)備,其中 APP_TX_DATA_SIZE 為 2048,USBD_MAX_STR_DESC
    發(fā)表于 12-19 07:13

    為什么無(wú)法從PC接收超過(guò)64字節(jié)數(shù)據(jù)?

    我正在全速模式下使用經(jīng)過(guò)修改的 CDC USB 設(shè)備,但我無(wú)法從 PC 接收64 字節(jié)
    發(fā)表于 01-16 07:22

    rt1052的usb屬于高速usb,hid設(shè)備最大不是可以支持到1024字節(jié)?

    數(shù)據(jù)一包的大小才8個(gè)字節(jié),后面我自己改成64個(gè)字節(jié),測(cè)試收發(fā)是可以的,但是我試著改成128字節(jié),最終收發(fā)就有問(wèn)題了 。rt1052的
    發(fā)表于 04-17 07:41

    網(wǎng)絡(luò)是否允許小于64字節(jié)的以太網(wǎng)幀或者報(bào)文傳輸?

    同學(xué)們?cè)趯W(xué)網(wǎng)絡(luò)課程的時(shí)候都知道,除巨幀外,常見(jiàn)的以太網(wǎng)幀的長(zhǎng)度范圍是64字節(jié)到1518字節(jié),并且因?yàn)樽畛蹩偩€型半雙工的組網(wǎng)原因,人們制定了CSMA/CD協(xié)議,規(guī)定了以太網(wǎng)中最短幀為64
    的頭像 發(fā)表于 09-05 11:46 ?8952次閱讀
    網(wǎng)絡(luò)是否允許小于<b class='flag-5'>64</b><b class='flag-5'>字節(jié)</b>的以太網(wǎng)幀或者報(bào)文傳輸?

    在進(jìn)行USB CDC類(lèi)開(kāi)發(fā)時(shí) 無(wú)法發(fā)送64整數(shù)倍的數(shù)據(jù)

    在進(jìn)行USB CDC類(lèi)開(kāi)發(fā)時(shí) 無(wú)法發(fā)送64整數(shù)倍的數(shù)據(jù)(通信電源技術(shù)審稿費(fèi)用)-在向客戶推STM32F4芯片的時(shí)候,客戶反饋使用
    發(fā)表于 08-04 17:57 ?18次下載
    在進(jìn)行<b class='flag-5'>USB</b> <b class='flag-5'>CDC</b><b class='flag-5'>類(lèi)</b>開(kāi)發(fā)時(shí) 無(wú)法發(fā)送<b class='flag-5'>64</b>整數(shù)倍的<b class='flag-5'>數(shù)據(jù)</b>