700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > USB自定义HID设备实现-LPC1768

USB自定义HID设备实现-LPC1768

时间:2021-07-17 11:01:42

相关推荐

USB自定义HID设备实现-LPC1768

首先在之前鼠标的基础上修改设备描述符

#include "usbdesc.h"

//usb标准设备描述符

const U8 USB_DeviceDescriptor[]={

USB_DEVICE_DESC_SIZE,//bLength字段。设备描述符的长度为18(0x12)字节

USB_DEVICE_DESCRIPTOR_TYPE,//bDescriptorType字段。设备描述符的编号为0x01

WBVAL(0x0110),//bcdUSB字段。这里设置版本为USB1.1,即0x0110。

0x00,//bDeviceClass字段。我们不在设备描述符中定义设备类,

0x00,//bDeviceSubClass字段。bDeviceClass字段为0时,该字段也为0。

0x00,//bDeviceProtocol字段。bDeviceClass字段为0时,该字段也为0。

USB_MAX_PACKET0,//bMaxPacketSize0字段。端点0的最大包长度。

WBVAL(0x8888),//idVender字段。厂商ID号,我们这里取0x8888,仅供实验用。

WBVAL(0x8877),//idProduct字段。产品ID号,由于是第一个实验,我们这里取0x0001。\。

WBVAL(0x0100),// 设备的版本

0x01,//iManufacturer字段。厂商字符串的索引值,为了方便记忆和管理

0x02,//iProduct字段。产品字符串的索引值。刚刚用了1,这里就取2吧。

0x03,//iSerialNumber字段。设备的序列号字符串索引值。

0x01 //bNumConfigurations字段。该设备所具有的配置数。

};

//USB报告描述符的定义

const u8 HID_ReportDescriptor[]=

{

0x06,0xA0,0xFF,//用法页(FFA0h, vendor defined)

0x09,0x01,//用法(vendor defined)

0xA1,0x01,//集合(Application)

0x09,0x02,//用法(vendor defined)

0xA1,0x00,//集合(Physical)

0x06,0xA1,0xFF,//用法页(vendor defined)

//输入报告

0x09,0x03,//用法(vendor defined)

0x09,0x04,//用法(vendor defined)

0x15,0x80,//逻辑最小值(0x80 or -128)

0x25,0x7F,//逻辑最大值(0x7F or 127)

0x35,0x00,//物理最小值(0)

0x45,0xFF,//物理最大值(255)

0x75,0x08,//报告长度Report size (8位)

0x95,0x40,//报告数值(64 fields)

0x81,0x02,//输入(data, variable, absolute)

//输出报告

0x09,0x05,//用法(vendor defined)

0x09,0x06,//用法(vendor defined)

0x15,0x80,//逻辑最小值(0x80 or -128)

0x25,0x7F,//逻辑最大值(0x7F or 127)

0x35,0x00,//物理最小值(0)

0x45,0xFF,//物理最大值(255)

0x75,0x08,//报告长度(8位)

0x95,0x40,//报告数值(64 fields)

0x91,0x02,//输出(data, variable, absolute)

0xC0,//集合结束(Physical)

0xC0//集合结束(Application)

};

//通过上面的报告描述符的定义,我们知道返回的输入报告具有8字节。

//输出报告也有64字节。至于这64字节的数据是干什么用的,就要由用户

//自己来决定了。

///报告描述符完毕

const U16 HID_ReportDescSize=sizeof(HID_ReportDescriptor);

//usb配置描述符

const U8 USB_ConfigDescriptor[]={

/***************配置描述符***********************/

USB_CONFIGUARTION_DESC_SIZE,//bLength字段。配置描述符的长度为9字节。

USB_CONFIGURATION_DESCRIPTOR_TYPE,//bDescriptorType字段。配置描述符编号为0x02。

//wTotalLength字段。配置描述符集合的总长度,

//包括配置描述符本身、接口描述符、类描述符、端点描述符等。

WBVAL(

USB_CONFIGUARTION_DESC_SIZE+//配置描述符

USB_INTERFACE_DESC_SIZE+//接口1描述符

9+//hid描述符

USB_ENDPOINT_DESC_SIZE+//端点描述符

USB_ENDPOINT_DESC_SIZE //端点描述符

),

0x01,//bNumInterfaces字段。该配置包含的接口数,只有一个接口。

0x01,//bConfiguration字段。该配置的值为1。

0x00,//iConfigurationz字段,该配置的字符串索引。这里没有,为0。

USB_CONFIG_BUS_POWERED,//bmAttributes字段,该设备的属性

USB_CONFIG_POWER_MA(500),//bMaxPower字段,该设备需要的最大电流量

/*********************第一个接口描述符,hid设备**********************/

USB_INTERFACE_DESC_SIZE,//bLength字段。接口描述符的长度为9字节。

USB_INTERFACE_DESCRIPTOR_TYPE,//bDescriptorType字段。接口描述符的编号为0x04。

0x00,//bInterfaceNumber字段。该接口的编号,第一个接口,编号为0。

0x00,//bAlternateSetting字段。该接口的备用编号,为0。

0x02,//bNumEndpoints字段。非0端点的数目。该接口有2个批量端点

USB_DEVICE_CLASS_HUMAN_INTERFACE,//bInterfaceClass字段。该接口所使用的类。大容量存储设备接口类的代码为0x08。,

0x00,//bInterfaceSubClass字段。该接口所使用的子类。在HID1.1协议中,

//只规定了一种子类:支持BIOS引导启动的子类。

//USB键盘、鼠标属于该子类,子类代码为0x01。

//但这里我们是自定义的HID设备,所以不使用子类。

0x00,//bInterfaceProtocol字段。如果子类为支持引导启动的子类,

//则协议可选择鼠标和键盘。键盘代码为0x01,鼠标代码为0x02。

//自定义的HID设备,也不使用协议。

0x00,//iConfiguration字段。该接口的字符串索引值。这里没有,为0。

/*********************HID报告描述符*************************/

//bLength字段。本HID描述符下只有一个下级描述符。所以长度为9字节。

0x09,

//bDescriptorType字段。HID描述符的编号为0x21。

0x21,

//bcdHID字段。本协议使用的HID1.1协议。注意低字节在先。

0x10,

0x01,

//bCountyCode字段。设备适用的国家代码,这里选择为美国,代码0x21。

0x21,

//bNumDescriptors字段。下级描述符的数目。我们只有一个报告描述符。

0x01,

//bDescriptorType字段。下级描述符的类型,为报告描述符,编号为0x22。

0x22,

//bDescriptorLength字段。下级描述符的长度。下级描述符为报告描述符。

sizeof(HID_ReportDescriptor)&0xFF,

(sizeof(HID_ReportDescriptor)>>8)&0xFF,

/*********************端点描述符**********************************/

/* 端点描述符 */

USB_ENDPOINT_DESC_SIZE,//bLength字段。端点描述符长度为7字节。

USB_ENDPOINT_DESCRIPTOR_TYPE,//bDescriptorType字段。端点描述符编号为0x05。

USB_ENDPOINT_IN(1),//bEndpointAddress字段。端点的地址。我们使用D12的输入端点1。

USB_ENDPOINT_TYPE_INTERRUPT,//bmAttributes字段。D1~D0为端点传输类型选择。

WBVAL(0x0040),//wMaxPacketSize字段。该端点的最大包长。最大包长为64字节。

0x01,//bInterval字段。端点查询的时间,端点查询的时间,此处无意义。

/***********************端点描述符*******************************************/

USB_ENDPOINT_DESC_SIZE,//bLength字段。端点描述符长度为7字节。

USB_ENDPOINT_DESCRIPTOR_TYPE,//bDescriptorType字段。端点描述符编号为0x05。

USB_ENDPOINT_OUT(1),//bEndpointAddress字段。端点的地址。我们使用D12的输入端点1。

USB_ENDPOINT_TYPE_INTERRUPT,//bmAttributes字段。D1~D0为端点传输类型选择。

WBVAL(0x0040),//wMaxPacketSize字段。该端点的最大包长。最大包长为64字节。

0x01,//bInterval字段。端点查询的时间,端点查询的时间,此处无意义。

//配置描述符扩充

0x00

};

//usb字符串描述符

const U8 USB_StringDescriptor[]={

0x04,/* bLength */

USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */

WBVAL(0x0409),/* US English */ /* wLANGID */

/* Index 0x04: Manufacturer */

0x1C,/* bLength */

USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */

'C',0,

'E',0,

'W',0,

'A',0,

'Y',0,

' ',0,

'T',0,

'E',0,

'C',0,

' ',0,

' ',0,

' ',0,

' ',0,

/* Index 0x20: Product */

0x28,/* bLength */

USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */

'S',0,

'Y',0,

'S',0,

'T',0,

'E',0,

'M',0,

'T',0,

'E',0,

'S',0,

'T',0,

' ',0,

' ',0,

'G',0,

'R',0,

'O',0,

'U',0,

'P',0,

'1',0,

' ',0,

/* Index 0x48: Serial Number */

0x1A,/* bLength */

USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */

'D',0,

'E',0,

'N',0,

'G',0,

'X',0,

'I',0,

'A',0,

'O',0,

'J',0,

'U',0,

'N',0,

'0',0,

/* Index 0x62: Interface 0, Alternate Setting 0 */

0x0E,/* bLength */

USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */

'D',0,

'E',0,

'V',0,

'I',0,

'C',0,

'E',0,

};

然后直接就可以在端点处理函数中处理数据了usbep1.c

#include "usbep1.h"

//发送完成置1 发送未完成置0

u8 sendOk=1;

//接收到数据该设置为1,数据处理完成之后修改为0

u8 ReceiveOk=0;

void usb_ep1_in_process(void)

{

//设备向主机发送数据的回调函数

sendOk=1;//发送成功为1

}

void usb_ep1_out_process(void)

{

ReceiveOk=1;//有数据标志为1

}

发送数据和接收数据的函数如下

#include "usb_data_process.h"

//HID发送数据

//返回1发送失败 返回0发送成功

u8 HID_Send_Data(u8*buffer,u8 length)

{

if(sendOk==1)

{

if(length==0)

{

}

else

{

USB_WriteEP(HID_EP_IN,(u8*)buffer,length);

sendOk=0;//设置发送未完成状态,等待发送回调函数将数据发送到主机

}

return0;

}

else

{

return1;//上一次的数据还没发送出去,所以这次发送失败

}

}

//HID接收数据处理

u8 HID_Receive_Data(u8*buffer)

{

u16 length=0;//获取接收到的数据长度

u8 i=0;

if(ReceiveOk==1)//有数据

{

length=USB_ReadEP(HID_EP_OUT,buffer);

if(length==0)return0;

else

{

ReceiveOk=0;

printf("hid receive : ");

for(i=0;i<length;i++)

{

printf("%c ",buffer[i]);

}

printf("\r\n");

returnlength;//返回接收到的数据

}

}

else

{

//没有数据,直接为0

return0;

}

}

具体代码见链接

/detail/dengrengong/8523433

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。