STM32开发笔记34:USB CDC驱动程序的详细移植过程

发布者:RadiantSerenity最新更新时间:2019-07-16 来源: eefocus关键字:STM32  USB  CDC  驱动程序  移植过程 手机看文章 扫描二维码
随时随地手机看文章

单片机型号:STM32F401   


   本文详细介绍USB CDC驱动程序的移植过程。


    1、按照STM32F4 开发笔记8:解决USB CDC “该设备无法启动”问题介绍的过程生成驱动程序后,找到如下图所示的文件加入到自己的项目工程中。



    2、打开usbd_cdc_if.c文件,可以看到其中有,如下4个函数,其中Init、DeInit和Control函数都不需要改变,关键是Receive函数。


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函数,可以清楚的看到其是希望将接收逻辑写到这个函数中。不过我们一般希望接收逻辑写在我们自己的函数中,所以需要将函数移动到自己的文件中去。


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函数及其原型声明。


    5、在usbd_cdc_if.h文件中,重新加入函数声明,如下所示。


uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);

int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);

    6、建立自己的USB驱动,如下图所示。




    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的代码如下,里面调用了驱动服务程序。


#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文件,这个已经在前面的日志中提到。


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函数逻辑,写个简单的。


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、看一下效果,发什么,回什么。


    这样的USB驱动,应该算是比较完善的了。


关键字:STM32  USB  CDC  驱动程序  移植过程 引用地址:STM32开发笔记34:USB CDC驱动程序的详细移植过程

上一篇:STM32开发笔记35:USB FS的枚举方法
下一篇:STM32开发笔记33:解决USB CDC “该设备无法启动”问题

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved