單片機(jī)型號:STM32F401
本文詳細(xì)介紹USB CDC驅(qū)動(dòng)程序的移植過程。
1、按照STM32F4 開發(fā)筆記8:解決USB CDC “該設(shè)備無法啟動(dòng)”問題介紹的過程生成驅(qū)動(dòng)程序后,找到如下圖所示的文件加入到自己的項(xiàng)目工程中。
2、打開usbd_cdc_if.c文件,可以看到其中有,如下4個(gè)函數(shù),其中Init、DeInit和Control函數(shù)都不需要改變,關(guān)鍵是Receive函數(shù)。
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
3、查看CDC_Receive_FS函數(shù),可以清楚的看到其是希望將接收邏輯寫到這個(gè)函數(shù)中。不過我們一般希望接收邏輯寫在我們自己的函數(shù)中,所以需要將函數(shù)移動(dòng)到自己的文件中去。
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
4、屏蔽掉CDC_Receive_FS函數(shù)及其原型聲明。
5、在usbd_cdc_if.h文件中,重新加入函數(shù)聲明,如下所示。
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
6、建立自己的USB驅(qū)動(dòng),如下圖所示。
7、usb.h的代碼如下:
#ifndef USB_H_
#define USB_H_
#ifdef __cplusplus
extern "C"{
class CUSB
{
public:
uint8_t Buffer[64];
uint32_t Length;
boolean bFlag;
public:
CUSB(void);
void SendData(uint8_t* pData, uint32_t u32_Size);
void ReceiveData(uint8_t* pData, uint32_t u32_Size);
boolean IsReceivedData(void);
uint8_t CalCheckSum(uint8_t* pData, uint8_t Length);
};
void USB_InterruptFunction(uint8_t* pBuffer, uint32_t* pLength);
}
#endif
#endif
8、usb.cpp的代碼如下,里面調(diào)用了驅(qū)動(dòng)服務(wù)程序。
#include "include.h"
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
CUSB::CUSB(void)
{
MX_USB_DEVICE_Init();
}
void CUSB::SendData(uint8_t* pData, uint32_t u32_Size)
{
CDC_Transmit_FS(pData, u32_Size);
}
void CUSB::ReceiveData(uint8_t* pData, uint32_t u32_Size)
{
uint32_t i;
for (i = 0; i < u32_Size; i++)
{
this->Buffer[i] = *pData++;
}
this->Length = u32_Size;
if (this->Length > 0)
{
this->bFlag = TRUE;
}
}
boolean CUSB::IsReceivedData(void)
{
if (this->bFlag == TRUE)
{
this->bFlag = FALSE;
return TRUE;
}
else
{
return FALSE;
}
}
uint8_t CUSB::CalCheckSum(uint8_t* pData, uint8_t Length)
{
uint8_t u8_CheckSum, i;
u8_CheckSum = 0x00;
for (i = 0; i < Length; i++)
{
u8_CheckSum = u8_CheckSum + pData[i];
}
return u8_CheckSum;
}
void OTG_FS_IRQHandler(void)
{
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
}
int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len)
{
USB_InterruptFunction(pbuf, Len);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &pbuf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
}
9、千萬別忘記更改stm32f4xx_it.h文件,這個(gè)已經(jīng)在前面的日志中提到。
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void TIM3_IRQHandler(void);
void OTG_FS_IRQHandler(void);
10、最后完成main函數(shù)邏輯,寫個(gè)簡單的。
int main(void)
{
MX_ADC1_Init();
MX_SPI1_Init();
MX_USB_DEVICE_Init();
while (1)
{
if (Target.IsbMilliSecond_1000() == TRUE)
{
//1¤×÷??ê?μ?
Target.HAL.LED.Turn();
//Target.HAL.UsbCommunication.SendData(data, 10);
}
if (Target.HAL.UsbCommunication.IsReceivedData() == TRUE)
{
Target.HAL.UsbCommunication.SendData(Target.HAL.UsbCommunication.Buffer, Target.HAL.UsbCommunication.Length);
}
}
}
11、看一下效果,發(fā)什么,回什么。
這樣的USB驅(qū)動(dòng),應(yīng)該算是比較完善的了。
上一篇:STM32開發(fā)筆記35:USB FS的枚舉方法
下一篇:STM32開發(fā)筆記33:解決USB CDC “該設(shè)備無法啟動(dòng)”問題
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 神經(jīng)形態(tài)芯片可能是革新機(jī)器人實(shí)時(shí)電機(jī)控制的未來
- 從三個(gè)方面理解ARM嵌入式系統(tǒng)
- 自動(dòng)報(bào)警 基于MCU的家庭防盜報(bào)警系統(tǒng)的設(shè)計(jì)
- 存儲控制器及其訪問外設(shè)的原理
- 基于51系列單片機(jī)的智能照明控制系統(tǒng)設(shè)計(jì)方案
- 基于STM32的四旋翼飛行器控制系統(tǒng)
- 單片機(jī)應(yīng)用編程技巧解析
- 基于89C52的教室智能節(jié)能照明系統(tǒng)設(shè)計(jì)
- 一種新型的雨量光照傳感器的設(shè)計(jì)
- 貿(mào)澤授權(quán)代理Texas Instruments 豐富多樣的產(chǎn)品
- 美國為何恢復(fù)英偉達(dá)H20對華銷售?白宮AI負(fù)責(zé)人回應(yīng)
- Cadence 率先推出業(yè)內(nèi)首款 LPDDR6/5X 14.4Gbps 內(nèi)存 IP,為新一代 AI 基礎(chǔ)架構(gòu)助力
- 手把手教你從零設(shè)計(jì)一款算力超過 1000Tops 的智能駕駛芯片
- OrangeBox汽車連接域控制器(CDC)開發(fā)平臺
- 采用反激式轉(zhuǎn)換器進(jìn)行高功率應(yīng)用設(shè)計(jì)
- Vishay推出PLCC-6封裝RGB LED通過獨(dú)立控制紅色、綠色和藍(lán)色芯片實(shí)現(xiàn)寬色域
- 芯對話 | CBMG719單刀雙擲模擬開關(guān):高精度信號切換低阻高速寬溫
- 大聯(lián)大詮鼎集團(tuán)推出基于Qualcomm和Thundercomm產(chǎn)品的AI電子圍欄方案
- AMD:AI加速卡MI308將恢復(fù)出貨,許可證申請將被推進(jìn)至審核流程
- EEworld獨(dú)家原創(chuàng)視頻:大話TI CC2650,邀你來看!
- 觀看TI IOT解決方案研討會 答題即可贏取更多精美好禮!
- 【EEWORLD第三十九屆】2012年06月社區(qū)明星人物揭曉!
- 永不過時(shí)的物聯(lián)網(wǎng)解決方案 Intel帶你6的飛起來!
- ADI有獎(jiǎng)下載活動(dòng)之25:ADI汽車傳感器和傳感器接口解決方案
- Vicor 更好的供電方式提升無人機(jī)飛行時(shí)間飛行半徑及有效載荷
- 考眼力:高速數(shù)字設(shè)計(jì)的秘籍 藏在哪里? 走近Keysight PATHWAVE,提升工作效率
- TI 最新電容式觸控套件,免費(fèi)嘗鮮中
- TI有獎(jiǎng)直播|借助Sitara™ AM263x MCU 創(chuàng)造電氣化的未來
- 蘋果發(fā)布macOS Mojave 10.14.6第五個(gè)開發(fā)者測試版
- 今天公布了紅米Redmi Note7系列全新配色
- DxOMark即將公布 網(wǎng)友猜測或?yàn)槿A碩ZenFone6
- 手機(jī)屏幕碎裂,如何判斷碎的是內(nèi)屏還是外屏?
- 蘋果面部識別不會泄露用戶隱私 是一種算法機(jī)制
- 在工業(yè)自動(dòng)化方面,PLC產(chǎn)業(yè)起著重要作用
- PLC在廢水脫鹽處理中的應(yīng)用
- 變頻器故障產(chǎn)生原因及處理辦法
- 工業(yè)設(shè)計(jì)BLDC系統(tǒng)的挑戰(zhàn):實(shí)現(xiàn)精確的扭矩控制
- 工業(yè)以太網(wǎng)知多少,工業(yè)以太網(wǎng)的 6 大類型解析