打印
[应用相关]

USB CDC驱动程序的详细移植过程(转载)

[复制链接]
1824|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

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


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


使用特权

评论回复
沙发
heimaojingzhang|  楼主 | 2019-6-18 13:18 | 只看该作者
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);


使用特权

评论回复
板凳
heimaojingzhang|  楼主 | 2019-6-18 13:18 | 只看该作者
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 */
}


使用特权

评论回复
地板
heimaojingzhang|  楼主 | 2019-6-18 13:19 | 只看该作者
4、屏蔽掉CDC_Receive_FS函数及其原型声明。

使用特权

评论回复
5
heimaojingzhang|  楼主 | 2019-6-18 13:19 | 只看该作者

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
heimaojingzhang|  楼主 | 2019-6-18 13:20 | 只看该作者

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


使用特权

评论回复
7
heimaojingzhang|  楼主 | 2019-6-18 13:20 | 只看该作者
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
heimaojingzhang|  楼主 | 2019-6-18 13:20 | 只看该作者
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
heimaojingzhang|  楼主 | 2019-6-18 13:21 | 只看该作者
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
heimaojingzhang|  楼主 | 2019-6-18 13:21 | 只看该作者
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
heimaojingzhang|  楼主 | 2019-6-18 13:22 | 只看该作者

11、看一下效果,发什么,回什么。


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


使用特权

评论回复
12
wakayi| | 2019-7-8 11:51 | 只看该作者

非常感谢楼主分享

使用特权

评论回复
13
wowu| | 2019-7-8 11:54 | 只看该作者

非常感谢楼主分享

使用特权

评论回复
14
木木guainv| | 2019-7-8 11:57 | 只看该作者

非常感谢楼主分享

使用特权

评论回复
15
OTG326| | 2019-7-9 13:12 | 只看该作者
谢谢分享,楼主辛苦!

使用特权

评论回复
16
wangjiahao88| | 2019-7-9 14:46 | 只看该作者
这个 非常的好

速度能达到多少啊?

使用特权

评论回复
17
xdzys2008| | 2019-7-31 17:45 | 只看该作者
速度应该可以的吧,符合USB-CDC类设备的以太网能达到将近100M  如SR9900 DM9621 这类产品

使用特权

评论回复
18
heimaojingzhang|  楼主 | 2019-8-6 11:11 | 只看该作者
非常感谢各位支持

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

74

主题

3882

帖子

4

粉丝