基于STM32F103的USB学习笔记30 - 虚拟串口之完善USB请求

1. usbClassGetInterfaceSetting中接口数量改为1,因为这里有2个接口

RESULT usbClassGetInterfaceSetting(uint8_t Interface, uint8_t AlternateSetting)
{
    if (AlternateSetting > 0)
    {
        return USB_UNSUPPORT;
    }
    else if (Interface > 1)
    {
        return USB_UNSUPPORT;
    }
    return USB_SUCCESS;
}

2. CDC类的请求说明

#define SEND_ENCAPSULATED_COMMAND   0x00
#define GET_ENCAPSULATED_RESPONSE   0x01
#define SET_COMM_FEATURE            0x02
#define GET_COMM_FEATURE            0x03
#define CLEAR_COMM_FEATURE          0x04
#define SET_LINE_CODING             0x20
#define GET_LINE_CODING             0x21
#define SET_CONTROL_LINE_STATE      0x22
#define SEND_BREAK                  0x23

a) SEND_ENCAPSULATED_COMMAND 

此请求用于发出通信类接口支持的控制协议格式的命令。不用支持。

b) GET_ENCAPSULATED_RESPONSE  

此请求用于以通信类接口支持的控制协议的格式请求响应。不用支持。

c) SET_COMM_FEATURE

此请求设置特定目标的特定通信功能的特性

具体解释与GET_COMM_FEATURE一样。

d) GET_COMM_FEATURE

此请求返回所选通信功能的当前设置

wValue表示特征值,有2个有效值,分别为

0x01: ABSTRACT_STATE,wLength = 2, Data描述这个抽象模型通信设备的多路复用状态和空闲状态,即仅对抽象模型通信设备有效。这2个字节数据的含义如下:

bit 描述
D15:D2 保留位
D1

数据复用状态:

1:在数据类上启用呼叫管理命令的多路复用。

0:禁止复用

D0

空闲设定

1:这个接口上的所有端点将不再接受或发送数据

0:关闭空闲模式

0x02: COUNTRY_SETTING,wLength = 2,  2字节数据是ISO 3166中定义的十六进制国家代码。

e) CLEAR_COMM_FEATURE

此请求将选定功能设置为其默认状态。参考GET_COMM_FEATURE

d) SET_LINE_CODING

此请求允许主机指定一些应用程序可能需要的异步行字符格式属性。对于虚拟串口就是设置波特率之类的参数。具体参考GET_LINE_CODING。

e) GET_LINE_CODING

此请求允许主机找出当前配置的行编码。

行编码的结构如下:

Offset Filed Size Value Description
0 dwDTERate 4 Number 数据终端速率,单位为位/秒。这里是波特率
4 bCharFormat 1 Number

停止位:

0 - 1个停止位

1 - 1.5个停止位

2 - 2个停止位

5 bParityType 1 Number

校验位:

0 - None

1 - Odd

2 - Even

3 - Mark

4 - Space 

6 bDataBits 1 Number

数据位

5, 6, 7, 8或16

f) SET_CONTROL_LINE_STATE

此请求生成RS-232的RTS和DTR。

wValue是控制信号位图。

Bit position Description
D15..D2 预留
D1

半双工调制解调器的载波控制。该信号对应RTS。

0:停用载波

1:激活载波

在全双工模式下操作时,设备忽略此位的值。

D0

向DCE指示DTE是否存在。该信号对应DTR。

0:不存在

1:存在

g) SEND_BREAK

此请求发送特殊的载波调制,生成RS-232型中断。

wValue字段是中断信号的时间长度(以毫秒为单位)。如果wValue等于FFFFh,设备将发送中断,直到收到另一个wValue为0000h的send break请求。

3. DataSetup中添加GET_LINE_CODING和SET_LINE_CODING的处理

RESULT usbClassDataSetup(uint8_t RequestNo)
{
    uint8_t *(*CopyRoutine)(uint16_t);
    CopyRoutine = NULL;

    if (RequestNo == GET_LINE_CODING)
    {
        if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
        {
            CopyRoutine = usbVComGetLineCoding;
        }
    }
    else if (RequestNo == SET_LINE_CODING)
    {
        if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
        {
            CopyRoutine = usbVComSetLineCoding;
        }
        Request = SET_LINE_CODING;
    }

    if (CopyRoutine == NULL)
    {
        return USB_UNSUPPORT;
    }

    pInformation->Ctrl_Info.CopyData = CopyRoutine;
    pInformation->Ctrl_Info.Usb_wOffset = 0;
    (*CopyRoutine)(0);
    return USB_SUCCESS;
}

获取LINE_CODING就是返回串口的设定

uint8_t* usbVComGetLineCoding(uint16_t Length)
{
    if (Length == 0)
    {
        pInformation->Ctrl_Info.Usb_wLength = sizeof(stUartConfig);
        return NULL;
    }
    return(uint8_t *)&stUartConfig;
}

其中结构体变量stUartConfig是全局变量,记录串口的波特率等参数。

lineCoding_st stUartConfig =
{
    115200, /* baud rate*/
    0x00,   /* stop bits-1*/
    0x00,   /* parity - none*/
    0x08    /* no. of bits 8*/
};

设定串口的参数,这里只是更新了变量里面的值。

uint8_t* usbVComSetLineCoding(uint16_t Length)
{
    if (Length == 0)
    {
        pInformation->Ctrl_Info.Usb_wLength = sizeof(stUartConfig);
        return NULL;
    }
    return(uint8_t *)&stUartConfig;
}

在statusin里面设定uart参数

void usbClassStatusIn(void)
{
    if (Request == SET_LINE_CODING)
    {
        uartConfig(UART_VCOM, &stUartConfig);
        Request = 0;
    }
}

4. 修改NoData_Setup

RESULT usbClassNoDataSetup(uint8_t RequestNo)
{
    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
    {
        if (RequestNo == SET_COMM_FEATURE)
        {
            return USB_SUCCESS;
        }
        else if (RequestNo == SET_CONTROL_LINE_STATE)
        {
            return USB_SUCCESS;
        }
    }
    return USB_UNSUPPORT;
}

基本功能OK,可以短接RxD和TxD,然后用一个串口工具验证功能。

碰到一个问题,记录一下:

PC端的串口工具有时候打开会提示串口被占用,原因是USB中断中加了一部分打印,去掉所有打印后恢复正常。

你可能感兴趣的:(MCU编程,USB)