7059|3

238

帖子

2

TA的资源

纯净的硅(高级)

楼主
 

第八章CDC设备 [复制链接]

小川工作室编写,本书为LM3S的USB芯片编写,上传的均为草稿还有没修改,可能还有很多地方不足,希望各位网友原谅!

QQ:2609828265

TEL:15882446438

E-mail:paulhyde@126.com

第八章CDC设备

8.1 CDC设备介绍

USB的CDC类是USB通信设备类(Communication Device Class)的简称。CDC类是USB组织定义的一类专门给各种通信设备(电信通信设备和中速网络通信设备)使用的USB子类。根据CDC类所针对通信设备的不同,CDC类又被分成以下不同的模型:USB传统纯电话业务(POTS)模型,USB ISDN模型和USB网络模型。通常一个CDC类又由两个接口子类组成通信接口类(Communication Interface Class)和数据接口类(Data Interface Class)。通信接口类对设备进行管理和控制,而数据接口类传送数据。这两个接口子类占有不同数量和类型的终端点(Endpoints),不同CDC类模型,其所对应的接口的终端点需求也是不同的。

8.2 CDC数据类型

usbdcdc.h中已经定义好CDC设备类中使用的所有数据类型和函数,同时也会使用Buffer数据类型及API函数,第7章有介绍Buffer数据类型及API函数,下面只介绍CDC设备类使用的数据类型。

typedef enum

{

    //CDC 状态没定义

    CDC_STATE_UNCONFIGURED,

    //空闲状态

    CDC_STATE_IDLE,

    //等待数据发送或者结束

    CDC_STATE_WAIT_DATA,

    //等待数据处理.

    CDC_STATE_WAIT_CLIENT

} tCDCState;

tCDCState,定义CDC端点状态。定义在usbdcdc.h。用于端点状态标记与控制,可以保证数据传输不相互冲突。

typedef struct

{

//USB基地址

    unsigned long ulUSBBase;

//设备信息

    tDeviceInfo *psDevInfo;

//配置信息

    tConfigDescriptor *psConfDescriptor;

//CDC 接收端点状态

    volatile tCDCState eCDCRxState;

//CDC 发送端点状态

    volatile tCDCState eCDCTxState;

//CDC 请求状态

    volatile tCDCState eCDCRequestState;

//CDC中断状态

    volatile tCDCState eCDCInterruptState;

//请求更新标志

volatile unsigned char ucPendingRequest;

//暂时结束 

unsigned short usBreakDuration;

//控制

unsigned short usControlLineState;

//UART状态

unsigned short usSerialState;

//标志位

    volatile unsigned short usDeferredOpFlags;

    //最后一次发送数据大小

    unsigned short usLastTxSize;

    //UART控制参数

tLineCoding sLineCoding;

//接收数据

volatile tBoolean bRxBlocked;

//控制数据

volatile tBoolean bControlBlocked;

//连接是否成功

    volatile tBoolean bConnected;

//控制端点

unsigned char ucControlEndpoint;

//Bulk IN端点

    unsigned char ucBulkINEndpoint;

// Bulk Out端点

    unsigned char ucBulkOUTEndpoint;

//接口控制

    unsigned char ucInterfaceControl;

//接口数据

    unsigned char ucInterfaceData;

}

tCDCInstance;

tCDCInstance,CDC设备类实例。定义了CDC设备类的USB基地址、设备信息、IN端点、OUT端点等信息。

typedef struct

{

    //VID

    unsigned short usVID;

    //PID

    unsigned short usPID;

    //最大耗电量 

    unsigned short usMaxPowermA;

    //电源属性

    unsigned char ucPwrAttributes;

    //控制回调函数

    tUSBCallback pfnControlCallback;

    //控制回调函数的第一个参数

    void *pvControlCBData;  

    //接收回调函数

    tUSBCallback pfnRxCallback;

//接收回调函数的第一个参数

    void *pvRxCBData;

    //发送回调函数

    tUSBCallback pfnTxCallback;

    //发送回调函数的第一个参数

    void *pvTxCBData;

    //字符串描述符集合

    const unsigned char * const *ppStringDescriptors;

    //字符串描述符个数

    unsigned long ulNumStringDescriptors;

    //CDC类实例

    tCDCSerInstance *psPrivateCDCSerData;

}

tUSBDCDCDevice;

tUSBDCDCDevice,CDC设备类,定义了VID、PID、电源属性、字符串描述符等,还包括了一个CDC设备类实例。其它设备描述符、配置信息通过API函数储入tCDCSerInstance定义的CDC设备实例中。

8.3 API函数

在CDC设备类API库中定义了13个函数,完成USB CDC设备初始化、配置及数据处理。以及 11个Buffer操作函数,Buffer第7章有介绍。下面为usbdcdc.h中定义的API函数:

void *USBDCDCInit(unsigned long ulIndex,

                         const tUSBDCDCDevice *psCDCDevice);

void * USBDCDCCompositeInit(unsigned long ulIndex,

                                   const tUSBDCDCDevice *psCDCDevice);

unsigned long USBDCDCTxPacketAvailable(void *pvInstance);

unsigned long USBDCDCPacketWrite(void *pvInstance,

                                        unsigned char *pcData,

                                        unsigned long ulLength,

                                        tBoolean bLast);

unsigned long USBDCDCRxPacketAvailable(void *pvInstance);

unsigned long USBDCDCPacketRead(void *pvInstance,

                                       unsigned char *pcData,

                                       unsigned long ulLength,

                                       tBoolean bLast);

void USBDCDCSerialStateChange(void *pvInstance,

                                     unsigned short usState);

void USBDCDCTerm(void *pvInstance);

void *USBDCDCSetControlCBData(void *pvInstance, void *pvCBData);

void *USBDCDCSetRxCBData(void *pvInstance, void *pvCBData);

void *USBDCDCSetTxCBData(void *pvInstance, void *pvCBData);

void USBDCDCPowerStatusSet(void *pvInstance, unsigned char ucPower);

tBoolean USBDCDCRemoteWakeupRequest(void *pvInstance);

 

void *USBDCDCInit(unsigned long ulIndex,

                         const tUSBDCDCDevice *psCDCDevice);

作用:初始化CDC设备硬件、协议,把其它配置参数填入psCDCDevice实例中。

参数:ulIndex,USB模块代码,固定值:USB_BASE0。psDevice,CDC设备类。

返回:指向配置后的tUSBDCDCDevice

void * USBDCDCCompositeInit(unsigned long ulIndex,

                                   const tUSBDCDCDevice *psCDCDevice);

作用:初始化CDC设备协议,本函数在USBDCDCInit中已经调用。

参数:ulIndex,USB模块代码,固定值:USB_BASE0。psDevice,CDC设备类。

返回:指向配置后的tUSBDCDCDevice

unsigned long USBDCDCTxPacketAvailable(void *pvInstance);

作用:获取可用发送数据长度。

参数:pvInstancetUSBDCDCDevice设备指针。

返回:发送包大小,用发送数据长度。

unsigned long USBDCDCPacketWrite(void *pvInstance,

                                        unsigned char *pcData,

                                        unsigned long ulLength,

                                        tBoolean bLast);

作用:通过CDC传输发送一个包数据,底层驱动,在Buffer中使用。

参数:pvInstancetUSBDCDCDevice设备指针。pcData,待写入的数据指针。ulLength,待写入数据的长度。bLast,是否传输结束包。

返回:成功发送长度,可能与ulLength长度不一样。

unsigned long USBDCDCRxPacketAvailable(void *pvInstance);

作用:获取接收数据长度。

参数:pvInstancetUSBDCDCDevice设备指针。

返回:可用接收数据个数,可读取的有效数据。

unsigned long USBDCDCPacketRead(void *pvInstance,

                                       unsigned char *pcData,

                                       unsigned long ulLength,

                                       tBoolean bLast);

作用:通过CDC传输接收一个包数据,底层驱动,在Buffer中使用。

参数:pvInstancetUSBDCDCDevice设备指针。pcData,读出数据指针。ulLength,读出数据的长度。bLast,是否是束包。

返回:成功接收长度,可能与ulLength长度不一样。

void USBDCDCSerialStateChange(void *pvInstance,

                                     unsigned short usState);

作用:UART收到数据后,调用此函数进行数据处理。

参数:pvInstancetUSBDCDCDevice设备指针。usState,UART状态。

返回:无。

void USBDCDCTerm(void *pvInstance);

作用:结束CDC设备。

参数:pvInstance,指向tUSBDCDCDevice

返回:无。

void *USBDCDCSetControlCBData(void *pvInstance, void *pvCBData);

作用:改变控制回调函数的第一个参数。

参数:pvInstance,指向tUSBDCDCDevicepvCBData,用于替换的参数

返回:旧参数指针。

void *USBDCDCSetRxCBData(void *pvInstance, void *pvCBData);

作用:改变接收回调函数的第一个参数。

参数:pvInstance,指向tUSBDCDCDevicepvCBData,用于替换的参数

返回:旧参数指针。

void *USBDCDCSetTxCBData(void *pvInstance, void *pvCBData);

作用:改变发送回调函数的第一个参数。

参数:pvInstance,指向tUSBDCDCDevicepvCBData,用于替换的参数

返回:旧参数指针。

void USBDCDCPowerStatusSet(void *pvInstance, unsigned char ucPower);

作用:修改电源属性、状态。

参数:pvInstance,指向tUSBDCDCDeviceucPower,电源属性。

返回:无。

tBoolean USBDCDCRemoteWakeupRequest(void *pvInstance);

作用:唤醒请求。

参数:pvInstance,指向tUSBDCDCDevice

返回:无。

在这些函数中USBDCDCInitUSBDCDCPacketWriteUSBDCDCPacketReadUSBDCDCTxPacketAvailableUSBDCDCRxPacketAvailable函数最重要并且使用最多,USBDCDCInit第一次使用CDC设备时,用于初始化CDC设备的配置与控制。USBDCDCPacketReadUSBDCDCPacketWriteUSBDCDCTxPacketAvailableUSBDCDCRxPacketAvailable为CDC传输数据的底层驱动函数用于驱动Buffer。

在CDC类中也会使用到11个Buffer处理函数,用于Buffer数据接收、发送及处理。在CDC传输中大量使用。使用方法在第7章有讲解。

8.4 CDC设备开发

CDC设备开发只需要4步就能完成。如图2所示,CDC设备配置(主要是字符串描述符)、callback函数编写、USB处理器初始化、数据处理。


图2

下面以“USB转UART”实例说明使用USB库开发USB CDC类过程:

第一步:CDC设备配置(主要是字符串描述符),按字符串描述符标准完成串描述符配置,进而完成CDC设备配置。

#include "inc/hw_ints.h"

#include "inc/hw_memmap.h"

#include "inc/hw_types.h"

#include "inc/hw_uart.h"

#include "inc/hw_gpio.h"

#include "driverlib/debug.h"

#include "driverlib/gpio.h"

#include "driverlib/interrupt.h"

#include "driverlib/sysctl.h"

#include "driverlib/systick.h"

#include "driverlib/timer.h"

#include "driverlib/uart.h"

#include "driverlib/usb.h"

#include "usblib/usblib.h"

#include "usblib/usbcdc.h"

#include "usblib/usb-ids.h"

#include "usblib/device/usbdevice.h"

#include "usblib/device/usbdcdc.h"

#define UART_BUFFER_SIZE 256

volatile unsigned long g_ulUARTTxCount = 0;

volatile unsigned long g_ulUARTRxCount = 0;

// UART设置.

#define USB_UART_BASE           UART0_BASE

#define USB_UART_PERIPH         SYSCTL_PERIPH_UART0

#define USB_UART_INT            INT_UART0

#define TX_GPIO_BASE            GPIO_PORTA_BASE

#define TX_GPIO_PERIPH          SYSCTL_PERIPH_GPIOA

#define TX_GPIO_PIN             GPIO_PIN_1

#define RX_GPIO_BASE            GPIO_PORTA_BASE

#define RX_GPIO_PERIPH          SYSCTL_PERIPH_GPIOA

#define RX_GPIO_PIN             GPIO_PIN_0

#define DEFAULT_BIT_RATE        115200

#define DEFAULT_UART_CONFIG     (UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | \

                                 UART_CONFIG_STOP_ONE)

// 发送中断标志.

static tBoolean g_bSendingBreak = false;

//系统时钟

volatile unsigned long g_ulSysTickCount = 0;

// g_ulFlags使用的标志位.

#define COMMAND_PACKET_RECEIVED 0x00000001

#define COMMAND_STATUS_UPDATE   0x00000002

// 全局标志

volatile unsigned long g_ulFlags = 0;

//状态

char *g_pcStatus;

// 全局USB配置标志.

static volatile tBoolean g_bUSBConfigured = false;

unsigned long RxHandler(void *pvCBData, unsigned long ulEvent,

                        unsigned long ulMsgValue, void *pvMsgData);

unsigned long TxHandler(void *pvCBData, unsigned long ulEvent,

                        unsigned long ulMsgValue, void *pvMsgData);

unsigned long ControlHandler(void *pvCBData, unsigned long ulEvent,

                             unsigned long ulMsgValue, void *pvMsgData);

void USBUARTPrimeTransmit(unsigned long ulBase);

void CheckForSerialStateChange(const tUSBDCDCDevice *psDevice, long lErrors);

void SetControlLineState(unsigned short usState);

tBoolean SetLineCoding(tLineCoding *psLineCoding);

void GetLineCoding(tLineCoding *psLineCoding);

void SendBreak(tBoolean bSend);

const tUSBBuffer g_sTxBuffer;

const tUSBBuffer g_sRxBuffer;

const tUSBDCDCDevice g_sCDCDevice;

unsigned char g_pucUSBTxBuffer[];

unsigned char g_pucUSBRxBuffer[];

//*****************************************************************************

// 设备语言描述符.

//*****************************************************************************

const unsigned char g_pLangDescriptor[] =

{

    4,

    USB_DTYPE_STRING,

    USBShort(USB_LANG_EN_US)

};

//*****************************************************************************

// 制造商 字符串 描述符

//*****************************************************************************

const unsigned char g_pManufacturerString[] =

{

    (17 + 1) * 2,

    USB_DTYPE_STRING,

    'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,

    't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,

};

//*****************************************************************************

//产品 字符串 描述符

//*****************************************************************************

const unsigned char g_pProductString[] =

{

    2 + (16 * 2),

    USB_DTYPE_STRING,

    'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0,

    'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0

};

//*****************************************************************************

//  产品 序列号 描述符

//*****************************************************************************

const unsigned char g_pSerialNumberString[] =

{

    2 + (8 * 2),

    USB_DTYPE_STRING,

    '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '9', 0

};

//*****************************************************************************

// 设备接口字符串描述符

//*****************************************************************************

const unsigned char g_pControlInterfaceString[] =

{

    2 + (21 * 2),

    USB_DTYPE_STRING,

    'A', 0, 'C', 0, 'M', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0,

    'r', 0, 'o', 0, 'l', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0,

    'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0

};

//*****************************************************************************

//  设备配置字符串描述符

//*****************************************************************************

const unsigned char g_pConfigString[] =

{

    2 + (26 * 2),

    USB_DTYPE_STRING,

    'S', 0, 'e', 0, 'l', 0, 'f', 0, ' ', 0, 'P', 0, 'o', 0, 'w', 0,

    'e', 0, 'r', 0, 'e', 0, 'd', 0, ' ', 0, 'C', 0, 'o', 0, 'n', 0,

    'f', 0, 'i', 0, 'g', 0, 'u', 0, 'r', 0, 'a', 0, 't', 0, 'i', 0,

    'o', 0, 'n', 0

};

//*****************************************************************************

// 字符串描述符集合

//*****************************************************************************

const unsigned char * const g_pStringDescriptors[] =

{

    g_pLangDescriptor,

    g_pManufacturerString,

    g_pProductString,

    g_pSerialNumberString,

    g_pControlInterfaceString,

    g_pConfigString

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

                                sizeof(unsigned char *))

//*****************************************************************************

// 定义CDC设备实例

//*****************************************************************************

tCDCSerInstance g_sCDCInstance;

//*****************************************************************************

// 定义CDC设备

//*****************************************************************************

const tUSBDCDCDevice g_sCDCDevice =

{

    0x1234,

    USB_PID_SERIAL,

    0,

    USB_CONF_ATTR_SELF_PWR,

    ControlHandler,

    (void *)&g_sCDCDevice,

    USBBufferEventCallback,

    (void *)&g_sRxBuffer,

    USBBufferEventCallback,

    (void *)&g_sTxBuffer,

    g_pStringDescriptors,

    NUM_STRING_DESCRIPTORS,

    &g_sCDCInstance

};

//*****************************************************************************

// 定义Buffer

//*****************************************************************************

unsigned char g_pcUSBRxBuffer[UART_BUFFER_SIZE];

unsigned char g_pucRxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

unsigned char g_pcUSBTxBuffer[UART_BUFFER_SIZE];

unsigned char g_pucTxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

const tUSBBuffer g_sRxBuffer =

{

    false,                          // This is a receive buffer.

    RxHandler,                      // pfnCallback

    (void *)&g_sCDCDevice,          // Callback data is our device pointer.

    USBDCDCPacketRead,              // pfnTransfer

    USBDCDCRxPacketAvailable,       // pfnAvailable

    (void *)&g_sCDCDevice,          // pvHandle

    g_pcUSBRxBuffer,                // pcBuffer

    UART_BUFFER_SIZE,               // ulBufferSize

    g_pucRxBufferWorkspace          // pvWorkspace

};

const tUSBBuffer g_sTxBuffer =

{

    true,                           // This is a transmit buffer.

    TxHandler,                      // pfnCallback

    (void *)&g_sCDCDevice,          // Callback data is our device pointer.

    USBDCDCPacketWrite,             // pfnTransfer

    USBDCDCTxPacketAvailable,       // pfnAvailable

    (void *)&g_sCDCDevice,          // pvHandle

    g_pcUSBTxBuffer,                // pcBuffer

    UART_BUFFER_SIZE,               // ulBufferSize

    g_pucTxBufferWorkspace          // pvWorkspace

};

第二步:完成Callback函数。Callback函数用于处理输出端点、输入端点数据事务。CDC设备接收回调函数包含以下事务:USB_EVENT_RX_AVAILABLEUSB_EVENT_DATA_REMAININGUSB_EVENT_REQUEST_BUFFER;CDC设备发送回调函数包含了以下事务:USB_EVENT_TX_COMPLETE;CDC设备控制回调函数包含了以下事务:USB_EVENT_CONNECTED、USB_EVENT_DISCONNECTED、USBD_CDC_EVENT_GET_LINE_CODING、USBD_CDC_EVENT_SET_LINE_CODING、USBD_CDC_EVENT_SET_CONTROL_LINE_STATE、USBD_CDC_EVENT_SEND_BREAK、USBD_CDC_EVENT_CLEAR_BREAK、USB_EVENT_SUSPEND、USB_EVENT_RESUME。如下表:

名称

属性

说明

USB_EVENT_RX_AVAILABLE

接收

有数据可接收

USB_EVENT_DATA_REMAINING

接收

剩余数据

USB_EVENT_REQUEST_BUFFER

接收

请求Buffer

USB_EVENT_TX_COMPLETE

发送

发送完成

USB_EVENT_RESUME

控制

唤醒

USB_EVENT_SUSPEND

控制

挂起

USBD_CDC_EVENT_CLEAR_BREAK

控制

清除Break信号

USBD_CDC_EVENT_SEND_BREAK

控制

发送Break信号

USBD_CDC_EVENT_SET_CONTROL_LINE_STATE

控制

控制信号

USBD_CDC_EVENT_SET_LINE_CODING

控制

配置UART通信参数

USBD_CDC_EVENT_GET_LINE_CODING

控制

获取UART通信参数

USB_EVENT_DISCONNECTED

控制

断开

USB_EVENT_CONNECTED

控制

连接

2. CDC事务

根据以上事务编写Callback函数:

//*****************************************************************************

//CDC设备类控制回调函数

//*****************************************************************************

unsigned long  ControlHandler(void *pvCBData, unsigned long ulEvent,

               unsigned long ulMsgValue, void *pvMsgData)

{

    unsigned long ulIntsOff;

    // 判断处理事务

    switch(ulEvent)

    {

        //连接成功

        case USB_EVENT_CONNECTED:

            g_bUSBConfigured = true;

            //清空Buffer。

            USBBufferFlush(&g_sTxBuffer);

            USBBufferFlush(&g_sRxBuffer);

            // 更新状态.

            ulIntsOff = IntMasterDisable();

            g_pcStatus = "Host connected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            if(!ulIntsOff)

            {

                IntMasterEnable();

            }

            break;

        //断开连接.

        case USB_EVENT_DISCONNECTED:

            g_bUSBConfigured = false;

            ulIntsOff = IntMasterDisable();

            g_pcStatus = "Host disconnected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            if(!ulIntsOff)

            {

                IntMasterEnable();

            }

            break;

        // 获取UART通信参数.

        case USBD_CDC_EVENT_GET_LINE_CODING:

            GetLineCoding(pvMsgData);

            break;

        //设置UART通信参数。

        case USBD_CDC_EVENT_SET_LINE_CODING:

            SetLineCoding(pvMsgData);

            break; 

        // 设置 RS232 RTS 和 DTR.

        case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE:

            SetControlLineState((unsigned short)ulMsgValue);

            break;

        // 发送Break信号

        case USBD_CDC_EVENT_SEND_BREAK:

            SendBreak(true);

            break;

        // 清除Break信号

        case USBD_CDC_EVENT_CLEAR_BREAK:

            SendBreak(false);

            break;

        // 挂起与唤醒事务

        case USB_EVENT_SUSPEND:

        case USB_EVENT_RESUME:

            break;

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

//CDC设备类 发送回调函数

//*****************************************************************************

unsigned long TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    switch(ulEvent)

    {

//发送结束,在此不用处理数据

        case USB_EVENT_TX_COMPLETE:

            break;

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

//CDC设备类 发送回调函数

//*****************************************************************************

unsigned long TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    switch(ulEvent)

    {

//发送结束,在此不用处理数据

        case USB_EVENT_TX_COMPLETE:

            break;

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

//CDC设备类 接收回调函数

//*****************************************************************************

unsigned long RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    unsigned long ulCount;

    //判断事务类型

    switch(ulEvent)

    {

        //接收数据

        case USB_EVENT_RX_AVAILABLE:

        {

            //UART接收数据并能过USB发给主机。

            USBUARTPrimeTransmit(USB_UART_BASE);

            UARTIntEnable(USB_UART_BASE, UART_INT_TX);

            break;

        }

        // 检查剩余数据

        case USB_EVENT_DATA_REMAINING:

        {

            ulCount = UARTBusy(USB_UART_BASE) ? 1 : 0;

            return(ulCount);

        }

        //请求Buffer

        case USB_EVENT_REQUEST_BUFFER:

        {

            return(0);

        }

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

// 设置 RS232 RTS 和 DTR.

//*****************************************************************************

void SetControlLineState(unsigned short usState)

{

    // 根据MCU引脚自行添加。

}

//*****************************************************************************

// 设置UART通信参数

//*****************************************************************************

tBoolean SetLineCoding(tLineCoding *psLineCoding)

{

    unsigned long ulConfig;

    tBoolean bRetcode;

    bRetcode = true;

    // 数据长度

    switch(psLineCoding->ucDatabits)

    {

        case 5:

        {

            ulConfig = UART_CONFIG_WLEN_5;

            break;

        } 

        case 6:

        {

            ulConfig = UART_CONFIG_WLEN_6;

            break;

        } 

        case 7:

        {

            ulConfig = UART_CONFIG_WLEN_7;

            break;

        }  

        case 8:

        {

            ulConfig = UART_CONFIG_WLEN_8;

            break;

        } 

        default:

        {

            ulConfig = UART_CONFIG_WLEN_8;

            bRetcode = false;

            break;

        }

    }

    // 效验位

    switch(psLineCoding->ucParity)

    {

        case USB_CDC_PARITY_NONE:

        {

            ulConfig |= UART_CONFIG_PAR_NONE;

            break;

        }

        case USB_CDC_PARITY_ODD:

        {

            ulConfig |= UART_CONFIG_PAR_ODD;

            break;

        }  

        case USB_CDC_PARITY_EVEN:

        {

            ulConfig |= UART_CONFIG_PAR_EVEN;

            break;

        }

        case USB_CDC_PARITY_MARK:

        {

            ulConfig |= UART_CONFIG_PAR_ONE;

            break;

        } 

        case USB_CDC_PARITY_SPACE:

        {

            ulConfig |= UART_CONFIG_PAR_ZERO;

            break;

        } 

        default:

        {

            ulConfig |= UART_CONFIG_PAR_NONE;

            bRetcode = false;

            break;

        }

    }

    //停止位

    switch(psLineCoding->ucStop)

    {

        case USB_CDC_STOP_BITS_1:

        {

            ulConfig |= UART_CONFIG_STOP_ONE;

            break;

        }

        case USB_CDC_STOP_BITS_2:

        {

            ulConfig |= UART_CONFIG_STOP_TWO;

            break;

        }

        default:

        {

            ulConfig = UART_CONFIG_STOP_ONE;

            bRetcode |= false;

            break;

        }

    }

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlClockGet(), psLineCoding->ulRate,

                        ulConfig);

    return(bRetcode);

}

//*****************************************************************************

// 获取UART通信参数.

//*****************************************************************************

void GetLineCoding(tLineCoding *psLineCoding)

{

    unsigned long ulConfig;

    unsigned long ulRate;

    UARTConfigGetExpClk(USB_UART_BASE, SysCtlClockGet(), &ulRate,

                        &ulConfig);

    psLineCoding->ulRate = ulRate;

    //发送数据长度

    switch(ulConfig & UART_CONFIG_WLEN_MASK)

    {

        case UART_CONFIG_WLEN_8:

        {

            psLineCoding->ucDatabits = 8;

            break;

        }

        case UART_CONFIG_WLEN_7:

        {

            psLineCoding->ucDatabits = 7;

            break;

        }

        case UART_CONFIG_WLEN_6:

        {

            psLineCoding->ucDatabits = 6;

            break;

        }  

        case UART_CONFIG_WLEN_5:

        {

            psLineCoding->ucDatabits = 5;

            break;

        }

    }

    // 校验位

    switch(ulConfig & UART_CONFIG_PAR_MASK)

    {

        case UART_CONFIG_PAR_NONE:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_NONE;

            break;

        }

        case UART_CONFIG_PAR_ODD:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_ODD;

            break;

        }

        case UART_CONFIG_PAR_EVEN:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_EVEN;

            break;

        }

        case UART_CONFIG_PAR_ONE:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_MARK;

            break;

        } 

        case UART_CONFIG_PAR_ZERO:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_SPACE;

            break;

        }

    }    

    //停止位

    switch(ulConfig & UART_CONFIG_STOP_MASK)

    {

        case UART_CONFIG_STOP_ONE:

        {

            psLineCoding->ucStop = USB_CDC_STOP_BITS_1;

            break;

        }

        case UART_CONFIG_STOP_TWO:

        {

            psLineCoding->ucStop = USB_CDC_STOP_BITS_2;

            break;

        }

    }

}

//*****************************************************************************

// UART发送Break信号

//*****************************************************************************

void SendBreak(tBoolean bSend)

{

    if(!bSend)

    {

        UARTBreakCtl(USB_UART_BASE, false);

        g_bSendingBreak = false;

    }

    else

    {

        UARTBreakCtl(USB_UART_BASE, true);

        g_bSendingBreak = true;

    }

}

第三步:系统初始化,配置内核电压、系统主频、使能端口、LED控制等,本例中使用4个LED进行指示数据传输。在这个例子中,CDC传输接收的数据发送给主机。原理图如图3所示:

图3

系统初始化:

    unsigned long ulTxCount;

    unsigned long ulRxCount;

    // char pcBuffer[16];

    //设置内核电压、主频 50Mhz

   SysCtlLDOSet(SYSCTL_LDO_2_75V);

   SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL  | SYSCTL_OSC_MAIN );

  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);

    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);

    HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;

   g_bUSBConfigured = false;

   //UART配置

    SysCtlPeripheralEnable(USB_UART_PERIPH);

    SysCtlPeripheralEnable(TX_GPIO_PERIPH);

    SysCtlPeripheralEnable(RX_GPIO_PERIPH);

    GPIOPinTypeUART(TX_GPIO_BASE, TX_GPIO_PIN);

    GPIOPinTypeUART(RX_GPIO_BASE, RX_GPIO_PIN);

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlClockGet(), DEFAULT_BIT_RATE,

                        DEFAULT_UART_CONFIG);

    UARTFIFOLevelSet(USB_UART_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    // 配置和使能UART中断.

    UARTIntClear(USB_UART_BASE, UARTIntStatus(USB_UART_BASE, false));

    UARTIntEnable(USB_UART_BASE, (UART_INT_OE | UART_INT_BE | UART_INT_PE |

                  UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX));

   // 初始化发送与接收Buffer.

    USBBufferInit((tUSBBuffer *)&g_sTxBuffer);

    USBBufferInit((tUSBBuffer *)&g_sRxBuffer);

   // 初始化CDC设备

    USBDCDCInit(0, (tUSBDCDCDevice *)&g_sCDCDevice);

    ulRxCount = 0;

    ulTxCount = 0;

    IntEnable(USB_UART_INT);

  

第四步:数据处理。主要使用11个Buffer处理函数,用于Buffer数据接收、发送及处理。在CDC传输中大量使用。

//*****************************************************************************

//CheckForSerialStateChange在接收到串行数据后,处理标志。

//*****************************************************************************

void CheckForSerialStateChange(const tUSBDCDCDevice *psDevice, long lErrors)

{

    unsigned short usSerialState;

    // 设置TXCARRIER (DSR)和 RXCARRIER (DCD)位.

    usSerialState = USB_CDC_SERIAL_STATE_TXCARRIER |

                    USB_CDC_SERIAL_STATE_RXCARRIER;

    // 判断是什么标志

    if(lErrors)

    { 

        if(lErrors & UART_DR_OE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_OVERRUN;

        } 

        if(lErrors & UART_DR_PE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_PARITY;

        } 

        if(lErrors & UART_DR_FE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_FRAMING;

        }  

        if(lErrors & UART_DR_BE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_BREAK;

        }

        // 改变状态。

        USBDCDCSerialStateChange((void *)psDevice, usSerialState);

    }

}

//*****************************************************************************

//从UART中读取数据,并放在CDC设备Buffer中发送给USB主机

//*****************************************************************************

long ReadUARTData(void)

{

    long lChar, lErrors;

    unsigned char ucChar;

    unsigned long ulSpace;

    lErrors = 0;

    //检查有多少可用空间

    ulSpace = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer);

    //从UART中读取数据并写入到CDC设备类的Buffer中发送

    while(ulSpace && UARTCharsAvail(USB_UART_BASE))

    {

        //读一个字节

        lChar = UARTCharGetNonBlocking(USB_UART_BASE);

        //是不是控制或错误标志 。

        if(!(lChar & ~0xFF))

        {

            ucChar = (unsigned char)(lChar & 0xFF);

            USBBufferWrite((tUSBBuffer *)&g_sTxBuffer,

                           (unsigned char *)&ucChar, 1);

            ulSpace--;

        }

        else

        {

            lErrors |= lChar;

        }

        g_ulUARTRxCount++;

    }

    return(lErrors);

}

//*****************************************************************************

// 从Buffer中读取数据,通过UART发送

//*****************************************************************************

void USBUARTPrimeTransmit(unsigned long ulBase)

{

    unsigned long ulRead;

    unsigned char ucChar;

    if(g_bSendingBreak)

    {

        return;

    }

    //检查UART中可用空间

    while(UARTSpaceAvail(ulBase))

    {

        //从Buffer中读取一个字节.

        ulRead = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, &ucChar, 1);

        if(ulRead)

        {

            // 放在UART TXFIFO中发送.

            UARTCharPutNonBlocking(ulBase, ucChar);

    g_ulUARTTxCount++;

        }

        else

        {

            return;

        }

    }

}

//*****************************************************************************

// UART中断处理函数

//*****************************************************************************

void USBUARTIntHandler(void)

{

    unsigned long ulInts;

    long lErrors;

    //获取中断标志并清除

    ulInts = UARTIntStatus(USB_UART_BASE, true);

    UARTIntClear(USB_UART_BASE, ulInts);

    // 发送中断

    if(ulInts & UART_INT_TX)

    {

        // 从USB中获取数据并能过UART发送.

        USBUARTPrimeTransmit(USB_UART_BASE);

        // If the output buffer is empty, turn off the transmit interrupt.

        if(!USBBufferDataAvailable(&g_sRxBuffer))

        {

            UARTIntDisable(USB_UART_BASE, UART_INT_TX);

        }

    }

    // 接收中断.

    if(ulInts & (UART_INT_RX | UART_INT_RT))

    {

        //从UART中读取数据并通过Buffer发送给USB主机。

        lErrors = ReadUARTData();

        //检查是否有控制信号或者错误信号。

        CheckForSerialStateChange(&g_sCDCDevice, lErrors);

    }

}

 while(1)

    {

        if(g_ulFlags & COMMAND_STATUS_UPDATE)

        {

            //清除更新标志,有数据更新。

            IntMasterDisable();

            g_ulFlags &= ~COMMAND_STATUS_UPDATE;

            IntMasterEnable();

GPIOPinWrite(GPIO_PORTF_BASE,0x30,0x30);          

        }

// 发送完成

        if(ulTxCount != g_ulUARTTxCount)

        {

            ulTxCount = g_ulUARTTxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);

//usnprintf(pcBuffer, 16, " %d ", ulTxCount);

        }

        // 接收完成

        if(ulRxCount != g_ulUARTTxCount)

        {

            ulRxCount = g_ulUARTRxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

        }

    }

使用上面四步就完成CDC设备开发。CDC设备开发时要加入两个lib库函数: usblib.libDriverLib.lib,在启动代码中加入USB0DeviceIntHandler中断服务函数和USBUARTIntHandler中断服务程序。以上UARTàRS232开发完成,在Win xp下运行效果如下图所示:

驱动安装

在枚举过程中可以看出,在电脑右下脚可以看到“Virtual Com Port”字样,标示正在进行枚举,并手手动安装驱动。枚举成功后,在“设备管理器”的“端口”中看到“DESCRIPTION_0”设备,如下图。现在CDC设备可以正式使用。

CDC设备要配合上位机使用,上位机发送字符串通过USB>UART设备转换后通过UART发送给其它UART设备。运行图如下:

CDC设备USB-->UART开发源码较多,下面只列出一部分如下:

//*****************************************************************************

// 字符串描述符集合

//*****************************************************************************

const unsigned char * const g_pStringDescriptors[] =

{

    g_pLangDescriptor,

    g_pManufacturerString,

    g_pProductString,

    g_pSerialNumberString,

    g_pControlInterfaceString,

    g_pConfigString

};

#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) /                \

                                sizeof(unsigned char *))

//*****************************************************************************

// 定义CDC设备实例

//*****************************************************************************

tCDCSerInstance g_sCDCInstance;

//*****************************************************************************

// 定义CDC设备

//*****************************************************************************

const tUSBDCDCDevice g_sCDCDevice =

{

    0x1234,

    USB_PID_SERIAL,

    0,

    USB_CONF_ATTR_SELF_PWR,

    ControlHandler,

    (void *)&g_sCDCDevice,

    USBBufferEventCallback,

    (void *)&g_sRxBuffer,

    USBBufferEventCallback,

    (void *)&g_sTxBuffer,

    g_pStringDescriptors,

    NUM_STRING_DESCRIPTORS,

    &g_sCDCInstance

};

//*****************************************************************************

// 定义Buffer

//*****************************************************************************

unsigned char g_pcUSBRxBuffer[UART_BUFFER_SIZE];

unsigned char g_pucRxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

unsigned char g_pcUSBTxBuffer[UART_BUFFER_SIZE];

unsigned char g_pucTxBufferWorkspace[USB_BUFFER_WORKSPACE_SIZE];

const tUSBBuffer g_sRxBuffer =

{

    false,                          // This is a receive buffer.

    RxHandler,                      // pfnCallback

    (void *)&g_sCDCDevice,          // Callback data is our device pointer.

    USBDCDCPacketRead,              // pfnTransfer

    USBDCDCRxPacketAvailable,       // pfnAvailable

    (void *)&g_sCDCDevice,          // pvHandle

    g_pcUSBRxBuffer,                // pcBuffer

    UART_BUFFER_SIZE,               // ulBufferSize

    g_pucRxBufferWorkspace          // pvWorkspace

};

const tUSBBuffer g_sTxBuffer =

{

    true,                           // This is a transmit buffer.

    TxHandler,                      // pfnCallback

    (void *)&g_sCDCDevice,          // Callback data is our device pointer.

    USBDCDCPacketWrite,             // pfnTransfer

    USBDCDCTxPacketAvailable,       // pfnAvailable

    (void *)&g_sCDCDevice,          // pvHandle

    g_pcUSBTxBuffer,                // pcBuffer

    UART_BUFFER_SIZE,               // ulBufferSize

    g_pucTxBufferWorkspace          // pvWorkspace

};

//*****************************************************************************

//CheckForSerialStateChange在接收到串行数据后,处理标志。

//*****************************************************************************

void CheckForSerialStateChange(const tUSBDCDCDevice *psDevice, long lErrors)

{

    unsigned short usSerialState;

    // 设置TXCARRIER (DSR)和 RXCARRIER (DCD)位.

    usSerialState = USB_CDC_SERIAL_STATE_TXCARRIER |

                    USB_CDC_SERIAL_STATE_RXCARRIER;

    // 判断是什么标志

    if(lErrors)

    { 

        if(lErrors & UART_DR_OE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_OVERRUN;

        } 

        if(lErrors & UART_DR_PE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_PARITY;

        } 

        if(lErrors & UART_DR_FE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_FRAMING;

        }  

        if(lErrors & UART_DR_BE)

        {

            usSerialState |= USB_CDC_SERIAL_STATE_BREAK;

        }

        // 改变状态。

        USBDCDCSerialStateChange((void *)psDevice, usSerialState);

    }

}

//*****************************************************************************

//从UART中读取数据,并放在CDC设备Buffer中发送给USB主机

//*****************************************************************************

long ReadUARTData(void)

{

    long lChar, lErrors;

    unsigned char ucChar;

    unsigned long ulSpace;

    lErrors = 0;

    //检查有多少可用空间

    ulSpace = USBBufferSpaceAvailable((tUSBBuffer *)&g_sTxBuffer);

    //从UART中读取数据并写入到CDC设备类的Buffer中发送

    while(ulSpace && UARTCharsAvail(USB_UART_BASE))

    {

        //读一个字节

        lChar = UARTCharGetNonBlocking(USB_UART_BASE);

        //是不是控制或错误标志 。

        if(!(lChar & ~0xFF))

        {

            ucChar = (unsigned char)(lChar & 0xFF);

            USBBufferWrite((tUSBBuffer *)&g_sTxBuffer,

                           (unsigned char *)&ucChar, 1);

            ulSpace--;

        }

        else

        {

            lErrors |= lChar;

        }

        g_ulUARTRxCount++;

    }

    return(lErrors);

}

//*****************************************************************************

// 从Buffer中读取数据,通过UART发送

//*****************************************************************************

void USBUARTPrimeTransmit(unsigned long ulBase)

{

    unsigned long ulRead;

    unsigned char ucChar;

    if(g_bSendingBreak)

    {

        return;

    }

    //检查UART中可用空间

    while(UARTSpaceAvail(ulBase))

    {

        //从Buffer中读取一个字节.

        ulRead = USBBufferRead((tUSBBuffer *)&g_sRxBuffer, &ucChar, 1);

        if(ulRead)

        {

            // 放在UART TXFIFO中发送.

            UARTCharPutNonBlocking(ulBase, ucChar);

    g_ulUARTTxCount++;

        }

        else

        {

            return;

        }

    }

}

//*****************************************************************************

// 设置 RS232 RTS 和 DTR.

//*****************************************************************************

void SetControlLineState(unsigned short usState)

{

    // 根据MCU引脚自行添加。

}

//*****************************************************************************

// 设置UART通信参数

//*****************************************************************************

tBoolean SetLineCoding(tLineCoding *psLineCoding)

{

    unsigned long ulConfig;

    tBoolean bRetcode;

    bRetcode = true;

    // 数据长度

    switch(psLineCoding->ucDatabits)

    {

        case 5:

        {

            ulConfig = UART_CONFIG_WLEN_5;

            break;

        } 

        case 6:

        {

            ulConfig = UART_CONFIG_WLEN_6;

            break;

        } 

        case 7:

        {

            ulConfig = UART_CONFIG_WLEN_7;

            break;

        }  

        case 8:

        {

            ulConfig = UART_CONFIG_WLEN_8;

            break;

        } 

        default:

        {

            ulConfig = UART_CONFIG_WLEN_8;

            bRetcode = false;

            break;

        }

    }

    // 效验位

    switch(psLineCoding->ucParity)

    {

        case USB_CDC_PARITY_NONE:

        {

            ulConfig |= UART_CONFIG_PAR_NONE;

            break;

        }

        case USB_CDC_PARITY_ODD:

        {

            ulConfig |= UART_CONFIG_PAR_ODD;

            break;

        }  

        case USB_CDC_PARITY_EVEN:

        {

            ulConfig |= UART_CONFIG_PAR_EVEN;

            break;

        }

        case USB_CDC_PARITY_MARK:

        {

            ulConfig |= UART_CONFIG_PAR_ONE;

            break;

        } 

        case USB_CDC_PARITY_SPACE:

        {

            ulConfig |= UART_CONFIG_PAR_ZERO;

            break;

        } 

        default:

        {

            ulConfig |= UART_CONFIG_PAR_NONE;

            bRetcode = false;

            break;

        }

    }

    //停止位

    switch(psLineCoding->ucStop)

    {

        case USB_CDC_STOP_BITS_1:

        {

            ulConfig |= UART_CONFIG_STOP_ONE;

            break;

        }

        case USB_CDC_STOP_BITS_2:

        {

            ulConfig |= UART_CONFIG_STOP_TWO;

            break;

        }

        default:

        {

            ulConfig = UART_CONFIG_STOP_ONE;

            bRetcode |= false;

            break;

        }

    }

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlClockGet(), psLineCoding->ulRate,

                        ulConfig);

    return(bRetcode);

}

//*****************************************************************************

// 获取UART通信参数.

//*****************************************************************************

void GetLineCoding(tLineCoding *psLineCoding)

{

    unsigned long ulConfig;

    unsigned long ulRate;

    UARTConfigGetExpClk(USB_UART_BASE, SysCtlClockGet(), &ulRate,

                        &ulConfig);

    psLineCoding->ulRate = ulRate;

    //发送数据长度

    switch(ulConfig & UART_CONFIG_WLEN_MASK)

    {

        case UART_CONFIG_WLEN_8:

        {

            psLineCoding->ucDatabits = 8;

            break;

        }

        case UART_CONFIG_WLEN_7:

        {

            psLineCoding->ucDatabits = 7;

            break;

        }

        case UART_CONFIG_WLEN_6:

        {

            psLineCoding->ucDatabits = 6;

            break;

        }  

        case UART_CONFIG_WLEN_5:

        {

            psLineCoding->ucDatabits = 5;

            break;

        }

    }

    // 校验位

    switch(ulConfig & UART_CONFIG_PAR_MASK)

    {

        case UART_CONFIG_PAR_NONE:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_NONE;

            break;

        }

        case UART_CONFIG_PAR_ODD:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_ODD;

            break;

        }

        case UART_CONFIG_PAR_EVEN:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_EVEN;

            break;

        }

        case UART_CONFIG_PAR_ONE:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_MARK;

            break;

        } 

        case UART_CONFIG_PAR_ZERO:

        {

            psLineCoding->ucParity = USB_CDC_PARITY_SPACE;

            break;

        }

    }    

    //停止位

    switch(ulConfig & UART_CONFIG_STOP_MASK)

    {

        case UART_CONFIG_STOP_ONE:

        {

            psLineCoding->ucStop = USB_CDC_STOP_BITS_1;

            break;

        }

        case UART_CONFIG_STOP_TWO:

        {

            psLineCoding->ucStop = USB_CDC_STOP_BITS_2;

            break;

        }

    }

}

//*****************************************************************************

// UART发送Break信号

//*****************************************************************************

void SendBreak(tBoolean bSend)

{

    if(!bSend)

    {

        UARTBreakCtl(USB_UART_BASE, false);

        g_bSendingBreak = false;

    }

    else

    {

        UARTBreakCtl(USB_UART_BASE, true);

        g_bSendingBreak = true;

    }

}

//*****************************************************************************

//CDC设备类控制回调函数

//*****************************************************************************

unsigned long  ControlHandler(void *pvCBData, unsigned long ulEvent,

               unsigned long ulMsgValue, void *pvMsgData)

{

    unsigned long ulIntsOff;

    // 判断处理事务

    switch(ulEvent)

    {

        //连接成功

        case USB_EVENT_CONNECTED:

            g_bUSBConfigured = true;

            //清空Buffer。

            USBBufferFlush(&g_sTxBuffer);

            USBBufferFlush(&g_sRxBuffer);

            // 更新状态.

            ulIntsOff = IntMasterDisable();

            g_pcStatus = "Host connected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            if(!ulIntsOff)

            {

                IntMasterEnable();

            }

            break;

        //断开连接.

        case USB_EVENT_DISCONNECTED:

            g_bUSBConfigured = false;

            ulIntsOff = IntMasterDisable();

            g_pcStatus = "Host disconnected.";

            g_ulFlags |= COMMAND_STATUS_UPDATE;

            if(!ulIntsOff)

            {

                IntMasterEnable();

            }

            break;

        // 获取UART通信参数.

        case USBD_CDC_EVENT_GET_LINE_CODING:

            GetLineCoding(pvMsgData);

            break;

        //设置UART通信参数。

        case USBD_CDC_EVENT_SET_LINE_CODING:

            SetLineCoding(pvMsgData);

            break; 

        // 设置 RS232 RTS 和 DTR.

        case USBD_CDC_EVENT_SET_CONTROL_LINE_STATE:

            SetControlLineState((unsigned short)ulMsgValue);

            break;

        // 发送Break信号

        case USBD_CDC_EVENT_SEND_BREAK:

            SendBreak(true);

            break;

        // 清除Break信号

        case USBD_CDC_EVENT_CLEAR_BREAK:

            SendBreak(false);

            break;

        // 挂起与唤醒事务

        case USB_EVENT_SUSPEND:

        case USB_EVENT_RESUME:

            break;

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

//CDC设备类 发送回调函数

//*****************************************************************************

unsigned long TxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    switch(ulEvent)

    {

//发送结束,在此不用处理数据

        case USB_EVENT_TX_COMPLETE:

            break;

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

//CDC设备类 接收回调函数

//*****************************************************************************

unsigned long RxHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgValue,

          void *pvMsgData)

{

    unsigned long ulCount;

    //判断事务类型

    switch(ulEvent)

    {

        //接收数据

        case USB_EVENT_RX_AVAILABLE:

        {

            //UART接收数据并能过USB发给主机。

            USBUARTPrimeTransmit(USB_UART_BASE);

            UARTIntEnable(USB_UART_BASE, UART_INT_TX);

            break;

        }

        // 检查剩余数据

        case USB_EVENT_DATA_REMAINING:

        {

            ulCount = UARTBusy(USB_UART_BASE) ? 1 : 0;

            return(ulCount);

        }

        //请求Buffer

        case USB_EVENT_REQUEST_BUFFER:

        {

            return(0);

        }

        default:

            break;

    }

    return(0);

}

//*****************************************************************************

// UART中断处理函数

//*****************************************************************************

void USBUARTIntHandler(void)

{

    unsigned long ulInts;

    long lErrors;

    //获取中断标志并清除

    ulInts = UARTIntStatus(USB_UART_BASE, true);

    UARTIntClear(USB_UART_BASE, ulInts);

    // 发送中断

    if(ulInts & UART_INT_TX)

    {

        // 从USB中获取数据并能过UART发送.

        USBUARTPrimeTransmit(USB_UART_BASE);

        // If the output buffer is empty, turn off the transmit interrupt.

        if(!USBBufferDataAvailable(&g_sRxBuffer))

        {

            UARTIntDisable(USB_UART_BASE, UART_INT_TX);

        }

    }

    // 接收中断.

    if(ulInts & (UART_INT_RX | UART_INT_RT))

    {

        //从UART中读取数据并通过Buffer发送给USB主机。

        lErrors = ReadUARTData();

        //检查是否有控制信号或者错误信号。

        CheckForSerialStateChange(&g_sCDCDevice, lErrors);

    }

}

//*****************************************************************************

// 应用主函数.

//*****************************************************************************

int  main(void)

{

    unsigned long ulTxCount;

    unsigned long ulRxCount;

// char pcBuffer[16];

    //设置内核电压、主频 50Mhz

SysCtlLDOSet(SYSCTL_LDO_2_75V);

SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL  | SYSCTL_OSC_MAIN );

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);

GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);

HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;

g_bUSBConfigured = false;

//UART配置

    SysCtlPeripheralEnable(USB_UART_PERIPH);

    SysCtlPeripheralEnable(TX_GPIO_PERIPH);

    SysCtlPeripheralEnable(RX_GPIO_PERIPH);

    GPIOPinTypeUART(TX_GPIO_BASE, TX_GPIO_PIN);

    GPIOPinTypeUART(RX_GPIO_BASE, RX_GPIO_PIN);

    UARTConfigSetExpClk(USB_UART_BASE, SysCtlClockGet(), DEFAULT_BIT_RATE,

                        DEFAULT_UART_CONFIG);

    UARTFIFOLevelSet(USB_UART_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    // 配置和使能UART中断.

    UARTIntClear(USB_UART_BASE, UARTIntStatus(USB_UART_BASE, false));

    UARTIntEnable(USB_UART_BASE, (UART_INT_OE | UART_INT_BE | UART_INT_PE |

                  UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX));

// 初始化发送与接收Buffer.

    USBBufferInit((tUSBBuffer *)&g_sTxBuffer);

    USBBufferInit((tUSBBuffer *)&g_sRxBuffer);

// 初始化CDC设备

    USBDCDCInit(0, (tUSBDCDCDevice *)&g_sCDCDevice);

ulRxCount = 0;

    ulTxCount = 0;

    IntEnable(USB_UART_INT);   

    while(1)

    {

        if(g_ulFlags & COMMAND_STATUS_UPDATE)

        {

            //清除更新标志,有数据更新。

            IntMasterDisable();

            g_ulFlags &= ~COMMAND_STATUS_UPDATE;

            IntMasterEnable();

GPIOPinWrite(GPIO_PORTF_BASE,0x30,0x30);          

        }

// 发送完成

        if(ulTxCount != g_ulUARTTxCount)

        {

            ulTxCount = g_ulUARTTxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);

//usnprintf(pcBuffer, 16, " %d ", ulTxCount);

        }

        // 接收完成

        if(ulRxCount != g_ulUARTTxCount)

        {

            ulRxCount = g_ulUARTRxCount;

GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);

        }

    }

}

08 CDC设备.pdf (224.7 KB, 下载次数: 417)


最新回复

MARK 下,回去慢慢看!  详情 回复 发表于 2012-8-9 10:31
 
点赞 关注
个人签名QQ:1795100002
E-mail:paulhyde@qq.com

回复
举报

1729

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
MARK 下,回去慢慢看!
 
 

回复

400

帖子

0

TA的资源

五彩晶圆(中级)

板凳
 
好贴哦,楼主很给力
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

4
 
MARK 下,回去慢慢看!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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