主機環(huán)境:Windows 7 SP1
開發(fā)環(huán)境:MDK5.14
目標板:STM32F103C8T6
開發(fā)庫:STM32F1Cube庫和STM32_USB_Device_Library
現(xiàn)在我們來分析VCP例程的最后一個文件USB設(shè)備類的usbd_cdc文件,該文件跟CDC類緊密相關(guān),看下其頭文件的一些定義:
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#define CDC_IN_EP 0x81 /* EP1 for data IN */
#define CDC_OUT_EP 0x01 /* EP1 for data OUT */
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */
#define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */
#define USB_CDC_CONFIG_DESC_SIZ 67
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
這些宏定義指明了CDC類使用的端點,以及最大包大小,對于STM32F103C8T6來說最大包大小是是64字節(jié),其中命令控制端點最大包大小為8字節(jié)。在頭文件中還有一個CDC類的結(jié)構(gòu)聲明,如下:
typedef struct
{
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */
uint8_t CmdOpCode;
uint8_t CmdLength;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t RxLength;
uint32_t TxLength;
__IO uint32_t TxState;
__IO uint32_t RxState;
}
USBD_CDC_HandleTypeDef;
該句柄管理著CDC類的數(shù)據(jù)信息,接著我們來查看usbd_cdc.c文件,該文件需要配合CDC1.20以及PSTN1.20協(xié)議文檔來查看,在usbd_cdc,c中有我們CDC類的具體實現(xiàn),如下:
/* CDC interface class callbacks structure */
USBD_ClassTypeDef USBD_CDC =
{
USBD_CDC_Init,
USBD_CDC_DeInit,
USBD_CDC_Setup,
NULL, /* EP0_TxSent, */
USBD_CDC_EP0_RxReady,
USBD_CDC_DataIn,
USBD_CDC_DataOut,
NULL,
NULL,
NULL,
USBD_CDC_GetHSCfgDesc,
USBD_CDC_GetFSCfgDesc,
USBD_CDC_GetOtherSpeedCfgDesc,
USBD_CDC_GetDeviceQualifierDescriptor,
};
其中EP0_TxSent、SOF、IsoINIncomplete、ISOOUTIncomplete為空。該文件中函數(shù)比較多,先從簡單的分析,首先看下注冊接口的函數(shù),如下:
/**
* @brief USBD_CDC_RegisterInterface
* @param pdev: device instance
* @param fops: CD Interface callback
* @retval status
*/
uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops)
{
uint8_t ret = USBD_FAIL;
if(fops != NULL)
{
pdev->pUserData= fops;
ret = USBD_OK;
}
return ret;
}
注冊接口很簡單,即把CDC接口指針鏈接到USB句柄中的UserData即可。接著是在CDC接口文件中提到的兩個設(shè)置緩存區(qū)的函數(shù),如下:
/**
* @brief USBD_CDC_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @retval status
*/
uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev,
uint8_t *pbuff,
uint16_t length)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
hcdc->TxBuffer = pbuff;
hcdc->TxLength = length;
return USBD_OK;
}
/**
* @brief USBD_CDC_SetRxBuffer
* @param pdev: device instance
* @param pbuff: Rx Buffer
* @retval status
*/
uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev,
uint8_t *pbuff)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
hcdc->RxBuffer = pbuff;
return USBD_OK;
}
給CDC句柄的相應(yīng)字段賦值即可。再有兩個是CDC接口文件中提到的數(shù)據(jù)發(fā)送和接收函數(shù),如下:
/**
* @brief USBD_CDC_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
if(pdev->pClassData != NULL)
{
if(hcdc->TxState == 0)
{
/* Tx Transfer in progress */
hcdc->TxState = 1;
/* Transmit next packet */
USBD_LL_Transmit(pdev,
CDC_IN_EP,
hcdc->TxBuffer,
hcdc->TxLength);
return USBD_OK;
}
else
{
return USBD_BUSY;
}
}
else
{
return USBD_FAIL;
}
}
/**
* @brief USBD_CDC_ReceivePacket
* prepare OUT Endpoint for reception
* @param pdev: device instance
* @retval status
*/
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
/* Suspend or Resume USB Out process */
if(pdev->pClassData != NULL)
{
if(pdev->dev_speed == USBD_SPEED_HIGH )
{
/* Prepare Out endpoint to receive next packet */
USBD_LL_PrepareReceive(pdev,
CDC_OUT_EP,
hcdc->RxBuffer,
CDC_DATA_HS_OUT_PACKET_SIZE);
}
else
{
/* Prepare Out endpoint to receive next packet */
USBD_LL_PrepareReceive(pdev,
CDC_OUT_EP,
hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
}
return USBD_OK;
}
else
{
return USBD_FAIL;
}
}
發(fā)送函數(shù)很簡單,檢測到發(fā)送狀態(tài)處于空閑時則執(zhí)行發(fā)送操作,并設(shè)置發(fā)送狀態(tài)有BUSY,這里這里使用的發(fā)送端點是0x81,不是端點0。而且數(shù)據(jù)的發(fā)送和發(fā)送數(shù)據(jù)的緩存區(qū)設(shè)置二者是成對使用的。接收函數(shù)也比較簡單只是區(qū)分了高速和全速模式下的最大包大小不同,這里使用的端點同樣不是端點0而是端點0x001。CDC類接口使用的函數(shù)補充完畢,現(xiàn)在來看CDC類各個函數(shù),依然從簡單的開始幾個描述符的獲取,這個有四個描述符的獲取,如下:
/**
* @brief USBD_CDC_GetFSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_CDC_CfgFSDesc);
return USBD_CDC_CfgFSDesc;
}
/**
* @brief USBD_CDC_GetHSCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_CDC_CfgHSDesc);
return USBD_CDC_CfgHSDesc;
}
/**
* @brief USBD_CDC_GetCfgDesc
* Return configuration descriptor
* @param speed : current device speed
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
{
*length = sizeof (USBD_CDC_OtherSpeedCfgDesc);
return USBD_CDC_OtherSpeedCfgDesc;
}
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
上一篇:直接通過寄存器地址操作控制LED燈(STM32_01)
下一篇:STM32 USB學習筆記8
推薦閱讀
史海拾趣
在電子行業(yè)的激烈競爭中,宜源科技公司始終將技術(shù)創(chuàng)新作為公司發(fā)展的核心驅(qū)動力。公司投入大量研發(fā)資源,成功開發(fā)出一系列具有自主知識產(chǎn)權(quán)的電子產(chǎn)品和解決方案。其中,其獨特的智能芯片技術(shù),不僅大幅提升了產(chǎn)品的性能,還降低了生產(chǎn)成本,使得宜源科技在市場中迅速脫穎而出。
隨著云計算技術(shù)的不斷發(fā)展,ECS公司意識到只有不斷創(chuàng)新才能保持競爭優(yōu)勢。他們投入大量研發(fā)資源,對ECS服務(wù)進行了多次技術(shù)升級和產(chǎn)品優(yōu)化。例如,他們引入了智能調(diào)度算法,實現(xiàn)了計算資源的自動分配和負載均衡;同時,他們還加強了數(shù)據(jù)安全性和隱私保護措施,確??蛻舻臄?shù)據(jù)安全。這些技術(shù)突破和產(chǎn)品升級使得ECS公司的服務(wù)更加穩(wěn)定、可靠和高效。
在追求技術(shù)創(chuàng)新的同時,ATOP Technologies也始終注重品質(zhì)管理和品牌建設(shè)。公司通過了ISO-9001認證,從產(chǎn)品的研發(fā)設(shè)計到生產(chǎn),所有的流程都嚴格遵循最佳品質(zhì)原則。此外,ATOP Technologies還注重品牌形象的塑造和推廣,通過參加行業(yè)活動、舉辦技術(shù)研討會等方式,不斷提升品牌知名度和影響力。
1958年,Bals Elektrotechnik公司迎來了一個重大突破——連接器開始批量生產(chǎn)。隨著技術(shù)的不斷進步,公司逐漸將材料從鋁轉(zhuǎn)向塑料,這不僅降低了生產(chǎn)成本,還提高了產(chǎn)品的性能和可靠性。這一創(chuàng)新舉措使得Bals在電氣連接器市場上占據(jù)了重要地位,為后續(xù)的發(fā)展奠定了堅實基礎(chǔ)。
AOTC公司起源于一個由幾位電子工程專家組成的小團隊,他們共同研發(fā)出了一種新型的光電轉(zhuǎn)換器,具有更高的轉(zhuǎn)換效率和更小的體積。這一技術(shù)突破迅速吸引了風險投資家的注意,公司得到了初始的資金支持,并開始了正式的商業(yè)化進程。
一.隨著計算機及網(wǎng)絡(luò)設(shè)備的普及化,計算機及網(wǎng)絡(luò)系統(tǒng)對企業(yè)的重要性愈來愈高,其配套的環(huán)境設(shè)備也日益增多。因此,機房的管理及 監(jiān)控是現(xiàn)代計算機及網(wǎng)絡(luò)通信機房非常重要的一個環(huán)節(jié)。ePowerSwitch是專為現(xiàn)代計算機及網(wǎng)絡(luò)通信機房而設(shè)計的遠程電源控 ...… 查看全部問答∨ |
|
一直都是以菜鳥身份出現(xiàn),從來不敢發(fā)貼.今天發(fā)個595控制4進8出的程序,希望大俠拍磚! 希望大俠能多多拍磚,我這是第一次在這人論壇發(fā)貼.一直都很喜歡這個論壇,只是一直都沒有勇氣(因為實在很菜)..今天我終于鼓起勇氣來,向你表達: /******************32個按鍵掃描控制4進8出信號************************** ******************* ...… 查看全部問答∨ |
|
出售:WINDOWS MOBILE下導(dǎo)航軟件(具備源代碼)。 WINDOWS MOBILE下導(dǎo)航軟件(具備源代碼)。 開發(fā)平臺:EVC4.0 使用平臺:WINDOWS MOBILE5,6 電子地圖格式:MM4 地圖轉(zhuǎn)換工具:MAPINFO格式轉(zhuǎn)到MM4(具備源代碼)。 該軟件是為臺灣使用編寫的,在大陸還沒有版本問題。 Email:ljycdw ...… 查看全部問答∨ |
|
blog中發(fā)表文章為什么有時候無法打開頁面,一直處于loading狀態(tài) blog中發(fā)表文章為什么有時候無法打開頁面,一直處于loading狀態(tài).其它的頁面能夠正常打開. 不知是什么原因, … 查看全部問答∨ |
通過注冊表實現(xiàn)dll inject的問題, 添加了"InjectDLL" 項卻無法被加載. wm5/wm6 ppc 模擬器環(huán)境下,寫了一個測試用的abc.dll,在dllmain函數(shù)中會MessageBox一個窗口. 然后按照msdn里的介紹, HKEY_LOCAL_MACHINE\\SYSTEM\\KERNEL "InjectDLL" = REG_MULTI_SZ : "MyDLL1.DLL","MyDLL2.DLL", .. ...… 查看全部問答∨ |
下載一個圖片轉(zhuǎn)換成的大數(shù)組到SDRAM提示錯誤 裸奔2440,在SDRAM中調(diào)試程序。下載一個圖片轉(zhuǎn)換成的大數(shù)組到SDRAM,數(shù)組是unsigned short型的,總共320×240×2 = 153600個字節(jié),總提示錯誤如下,無法下載,是怎么回事?而且每次提示的錯誤地址都不一樣。 … 查看全部問答∨ |
本人寫GPRS模塊通信遇到一點問題,希望大家有空幫忙分析一下,不甚感激。我用的是博創(chuàng)upnetarm2410的開發(fā)箱,模塊是通過pci插槽連接的,串口通過16c550和cpu相連的。調(diào)試程序一直不理想 ...… 查看全部問答∨ |
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級數(shù)字信號控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- 英特爾FPGA可編程加速平臺介紹,走近AI、數(shù)據(jù)中心、基因工程等大咖工程
- “搜器件”小程序又添新功能!
- 直播|基于英特爾® Agilex™ FPGA F-Tile的以太網(wǎng)硬核IP詳解及如何使用oneAPI對FPGA編程
- 報名抽取京東卡|2021慕尼黑華南電子展觀眾注冊進行中
- 下載有禮|終于找到秘籍,示波器探頭的選擇和使用就靠它了!
- 愛“拼”才會贏 英飛凌柵極驅(qū)動IC拼圖闖關(guān) 活動開始啦!
- Littelfuse 新品賦能電子產(chǎn)品安全可靠并高效, 10+挑戰(zhàn)等你探索!
- 速度與激情,為你私人訂制。R&S攜多功能基礎(chǔ)示波器帶你身臨其境!
- 樂享愜意春天,TI A8開源硬件平臺體驗季!
- 高可靠性、節(jié)省空間的降壓/反激式開關(guān)IC適合400 VDC電動汽車應(yīng)用
- 通用快速充電:電池供電應(yīng)用的未來趨勢
- Mentor Tessent Safety 生態(tài)系統(tǒng)助力Ambarella 的 AI 視覺處理器實現(xiàn)汽車安全目標
- IAR Systems宣布擴展RISC-V開發(fā)工具
- 案例分享:兆易創(chuàng)新GD32 MCU 在電機驅(qū)動的應(yīng)用
- STC12系列單片機的位變量
- STC12系列單片機的空閑模式、休眠模式
- STC12系列單片機冷啟動、熱啟動
- STC單片機下載不進程序及解決辦法
- 單片機匯編偽指令DATA和EQU的區(qū)別
- 哪有下載后能操作的模擬實驗電路板
- 重磅!!Stellaris系列漫畫(1)致命吸引力!(TI-EEWORLD聯(lián)合制作)
- 關(guān)于RC電路
- 關(guān)于Sate210-F 開源uboot 自動進入fastboot 燒寫狀態(tài)的解決辦法
- SPICE運算放大器的穩(wěn)定性
- 【EAGLE】基準標記(光學定位點、Fiducial Mark)的封裝繪制及使用。
- 80C51單片機Small RTOS源代碼
- JTAG供不供電對其他模塊有影響
- 請問,哪些廠商的DC-DC開關(guān)降壓芯片(buck)做得比較好一點?
- 求助:畢業(yè)設(shè)計 請加我QQ996475025 價格面議