This paper introduces the porting process of USB CDC driver in detail.
1. According to STM32F4 development note 8: solve the USB CDC "the device can not be started" problem After generating the driver, find the file as shown in the figure below to add to your project project.
2. Open the usbd CDC if. C file, you can see that there are four functions as follows, among which Init, DeInit and Control functions do not need to be changed, and the key is the Receive function.
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. Check the CDC receive FS function, and you can see clearly that you want to write the receive logic to this function. However, we usually want the receiving logic written in our own functions, so we need to move the functions to our own files.
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. Mask the CDC receive FS function and its prototype declaration.
5. In the usbd CDC if. H file, add the function declaration again, as shown below.
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
6. Build your own USB driver, as shown in the figure below.
7. The usb.h code is as follows:
#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. The code of usb.cpp is as follows, in which the driver service program is called.
#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. Don't forget to change the stm32f4xx? It. H file, which has been mentioned in the previous log.
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. Finish the main function logic and write a simple one.
int main(void) { MX_ADC1_Init(); MX_SPI1_Init(); MX_USB_DEVICE_Init(); while (1) { if (Target.IsbMilliSecond_1000() == TRUE) { //¹¤×÷ָʾµÆ 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. Take a look at the effect, hair and back.
Such a USB driver should be relatively perfect.
Original article, reprint please indicate the source CSDN: http://blog.csdn.net/qingwufeiyang12346.