stm32f103 usb 修改成自定义复合设备教程
2017-03-10 10:14
1051 查看
单片机型号 STM32F103C8T6
软件 KEIL5
将现有的 HID设备 改成 有HID设备和 鼠标(或者键盘)的复合设备
HID设备 使用端点1和端点2
键盘 (或者鼠标)使用端点3
使用最小系统板 亲测 可以实现 HID设备 接收34字节每次
键盘可以使用
鼠标也可以使用
修改 usb_desc.c 文件 如下
设备描述符不用动 基本没有什么用
重要的是 配置描述符
HID报告描述符如下
//HID描述符
const u8 KeyboardReportDescriptor[KP_ReportDescriptor_Size]=
{
0x05, 0x8c,
0x09, 0x01,
0xa1, 0x01,
0x09,0x03,
0x15,0x00,
0x26,0x00, 0xFF,
0x75,0x08,
0x95,34,
0x81,0x02,
0x09,0x04,
0x15,0x00,
0x26,0x00,0xFF,
0x75,0x08,
0x95,34,
0x91,0x02,
0xc0
键盘报告描述符如下
usb_prop.c 文件中 需要修改的地方如下
usb_conf.h 修改如下
usb_endp.c 文件中 添加EP1接收函数
main函数中添加 发送数据函数
EP2上传数据的函数 发送一个
键盘上传的函数 发送一个键值0x04 按键a 然后再发送8个字节0 就是按下a后再松开
Transi_Buffer[0] = 0x00;
Transi_Buffer[1] = 0x00;
Transi_Buffer[2] = 0x04;
Transi_Buffer[3] = 0x00;
Transi_Buffer[4] = 0x00;
Transi_Buffer[5] = 0x00;
Transi_Buffer[6] = 0x00;
Transi_Buffer[7] = 0x00;
UserToPMABufferCopy(Transi_Buffer, GetEPTxAddr(ENDP3), 8);
SetEPTxCount(ENDP3, 8);
SetEPTxValid(ENDP3);
Delay(1000000);
Transi_Buffer[0] = 0x00;
Transi_Buffer[1] = 0x00;
Transi_Buffer[2] = 0x00;
Transi_Buffer[3] = 0x00;
Transi_Buffer[4] = 0x00;
Transi_Buffer[5] = 0x00;
Transi_Buffer[6] = 0x00;
Transi_Buffer[7] = 0x00;
UserToPMABufferCopy(Transi_Buffer, GetEPTxAddr(ENDP3), 8);
SetEPTxCount(ENDP3, 8);
SetEPTxValid(ENDP3);
承接USB开发 QQ727341554 TEL13810175694
软件 KEIL5
将现有的 HID设备 改成 有HID设备和 鼠标(或者键盘)的复合设备
HID设备 使用端点1和端点2
键盘 (或者鼠标)使用端点3
使用最小系统板 亲测 可以实现 HID设备 接收34字节每次
键盘可以使用
鼠标也可以使用
修改 usb_desc.c 文件 如下
设备描述符不用动 基本没有什么用
const u8 Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC] = { 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,//64 0x47,//Vid 0x20, 0x01,//Pid 0x03, 0x00, 0x02, 1, 2, 3, 0x01 } ;
重要的是 配置描述符
const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] = { 0x09, //bLength字段 USB_CONFIGURATION_DESCRIPTOR_TYPE, JOYSTICK_SIZ_CONFIG_DESC,//长度 0x00, 0x02, //接口数目 总共两个接口 接口和端点是不用的 0x01, //??????????????????????? 0x00, // 0x80, // 0x32, // //接口描述符--------------------------------- 0x09, 0x04,// 0x00,//接口编号 0x00,// 0x01,//端点数量 0x03,//该接口所使用的类 键盘属于HID 0x00,//子类 0x00,//键盘是1 鼠标是2 0是自定义设备 0, //HID描述符------------------------------------ 0x09, 0x21,//HID是21 0x10,//HID 1.0协议 是0x0100 0x01, 0x00,//国家代码 0x01,//-----------------下一级描述符的数目????????????????? 0x22,//-----------------下一级的描述符的类型是报告描述符 报告描述符编号0x22 sizeof(KeyboardReportDescriptor)&0xFF, //下级描述符的长度。下级描述符为键盘报告描述符。 (sizeof(KeyboardReportDescriptor)>>8)&0xFF, //端点描述符------------------------------------- 0x07, 0x05,//端点描述符编号 0x82, //地址 D7 1:输入 0:输出 D3-D0 是地址 0x03, //中断端点编号 34%256, //最大包长度 2字节 34/256, 0x01,//端点查询时间 //端点描述-------------------------------------- 0x07, 0x05,//端点描述符编号 0x01, //地址 D7 1:输入 0:输出 D3-D0 是地址 0x03, //中断端点编号 34%256,//最大包长度 2字节 34/256, 0x01, //端点查询时间 //第二个接口描述符-------键盘用的 0x09, 0x04, 0x01, //接口编号 是1 0x00, // 0x01, //1个端点 0x03, // 0 4000 x01, // 0x01, //1是键盘 2是鼠标 0x00, // //HID描述符 0x09, // 0x21, // 0x10, // 0x01, 0x21, // 0x01, // 0x22, // sizeof(MouseReportDescriptor)&0xFF, (sizeof(MouseReportDescriptor)>>8)&0xFF, //输入端点描述符 0x07, // 0x05, // 0x83, //端点3输入 0x03, //中断方式 0x08, //数据长度 0x00, 0x0A //
};
HID报告描述符如下
//HID描述符
const u8 KeyboardReportDescriptor[KP_ReportDescriptor_Size]=
{
0x05, 0x8c,
0x09, 0x01,
0xa1, 0x01,
0x09,0x03,
0x15,0x00,
0x26,0x00, 0xFF,
0x75,0x08,
0x95,34,
0x81,0x02,
0x09,0x04,
0x15,0x00,
0x26,0x00,0xFF,
0x75,0x08,
0x95,34,
0x91,0x02,
0xc0
};
键盘报告描述符如下
//USB鼠标报告描述符的定义 const u8 MouseReportDescriptor[Mouse_ReportDescriptor_Size]= { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x08, // REPORT_COUNT (8) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x25, 0xFF, // LOGICAL_MAXIMUM (255) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x95, 0x02, // REPORT_COUNT (2) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x02, // USAGE_MAXIMUM (Caps Lock) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x06, // REPORT_SIZE (6) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0xc0 // END_COLLECTION
};
usb_prop.c 文件中 需要修改的地方如下
void Joystick_Reset(void) { pInformation->Current_Configuration = 0; //设置当前的配置为0,表示没有配置过 pInformation->Current_Interface = 0; //默认的接口 pInformation->Current_Feature = Joystick_ConfigDescriptor[7]; //当前的属性,bmAttributes:设备的一些特性,0xc0表示自供电,不支持远程唤醒 SetBTABLE(BTABLE_ADDRESS); SetEPType(ENDP0, EP_CONTROL); //设置端点1为控制端点 SetEPTxStatus(ENDP0, EP_TX_STALL); //设置端点0发送延时 SetEPRxAddr(ENDP0, ENDP0_RXADDR); //设置端点0的接收缓冲区地址 SetEPTxAddr(ENDP0, ENDP0_TXADDR); //设置端点0的发送缓冲区地址 Clear_Status_Out(ENDP0); //清除端点0的状态 SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); //设置端点0的接收的计数 SetEPRxValid(ENDP0); //使能接收状态 //端点1 SetEPType(ENDP1, EP_INTERRUPT);//端点1 输出 PC向stm32发送数据 //设置端点1为中断控制端点 SetEPRxAddr(ENDP1, ENDP1_RXADDR); //设置端点1的接收缓冲地址 SetEPRxCount(ENDP1, 34); //设置端点1的接收计数 SetEPRxStatus(ENDP1, EP_RX_VALID); //设置端点1接收有效 //SetEPTxStatus(ENDP1, EP_TX_DIS); //端点2 SetEPType(ENDP2, EP_INTERRUPT);//端点2 输入 Stm32向pc发送数据 //设置端点2为中断控制端点 SetEPTxAddr(ENDP2, ENDP2_TXADDR); //设置端点2的接收缓冲地址 SetEPTxCount(ENDP2, 34); //设置端点2的发送计数 // SetEPTxStatus(ENDP2, EP_TX_DIS); SetEPTxStatus(ENDP2, EP_TX_NAK); //设置端点2为接收不响应 //端点3---------为键盘增加的 SetEPType(ENDP3, EP_INTERRUPT);//端点2 输入 Stm32向pc发送数据 //设置端点2为中断控制端点 SetEPTxAddr(ENDP3, ENDP3_TXADDR); //设置端点2的接收缓冲地址 SetEPTxCount(ENDP3, 8); //设置端点2的发送计数 // SetEPTxStatus(ENDP2, EP_TX_DIS); SetEPTxStatus(ENDP3, EP_TX_NAK); //设置端点2为接收不响应 bDeviceState = ATTACHED; //设置设备状态为 ATTACHED状态 SetDeviceAddress(0); //设置设备为默认地址 }
usb_conf.h 修改如下
#define EP_NUM (4)-----------改成4个EP EP0用于控制 EP1电脑下发 EP2单片机上传 EP3键盘或者鼠标上传 /*-------------------------------------------------------------*/ /* -------------- Buffer Description Table -----------------*/ /*-------------------------------------------------------------*/ /* buffer table base address */ /* buffer table base address */ #define BTABLE_ADDRESS (0x00) /* EP0 */ /* rx/tx buffer base address */ #define ENDP0_RXADDR (0x40)//(0x18) #define ENDP0_TXADDR (0x80)//(0x58) /* EP1 */ /* tx buffer base address */ //地址为32位对其,位4的倍数,不能超过 bMaxPacketSize #define ENDP1_RXADDR (0xc0)//(0x98) #define ENDP1_TXADDR (0x100)//(0xD8) //EP2 //#define ENDP2_RXADDR (0x118) #define ENDP2_TXADDR (0x140)//(0x118) //EP3 #define ENDP3_TXADDR (0x180)//(0x158)
usb_endp.c 文件中 添加EP1接收函数
void EP1_OUT_Callback(void) { u8 DataLen; u8 DataBuffer[64]; USB_ReceiveFlg = TRUE; DataLen = GetEPRxCount(ENDP1); PMAToUserBufferCopy(DataBuffer, ENDP1_RXADDR, DataLen); SetEPRxValid(ENDP1); }
main函数中添加 发送数据函数
EP2上传数据的函数 发送一个
UserToPMABufferCopy(Transi_Buffer, ENDP2_TXADDR, 34); //发送的数组 端点地址 发送字节数SetEPTxValid(ENDP2);//发送
键盘上传的函数 发送一个键值0x04 按键a 然后再发送8个字节0 就是按下a后再松开
Transi_Buffer[0] = 0x00;
Transi_Buffer[1] = 0x00;
Transi_Buffer[2] = 0x04;
Transi_Buffer[3] = 0x00;
Transi_Buffer[4] = 0x00;
Transi_Buffer[5] = 0x00;
Transi_Buffer[6] = 0x00;
Transi_Buffer[7] = 0x00;
UserToPMABufferCopy(Transi_Buffer, GetEPTxAddr(ENDP3), 8);
SetEPTxCount(ENDP3, 8);
SetEPTxValid(ENDP3);
Delay(1000000);
Transi_Buffer[0] = 0x00;
Transi_Buffer[1] = 0x00;
Transi_Buffer[2] = 0x00;
Transi_Buffer[3] = 0x00;
Transi_Buffer[4] = 0x00;
Transi_Buffer[5] = 0x00;
Transi_Buffer[6] = 0x00;
Transi_Buffer[7] = 0x00;
UserToPMABufferCopy(Transi_Buffer, GetEPTxAddr(ENDP3), 8);
SetEPTxCount(ENDP3, 8);
SetEPTxValid(ENDP3);
承接USB开发 QQ727341554 TEL13810175694
相关文章推荐
- USB自定义设备驱动开发——修改驱动后应用程序无法使用
- 通过修改内核提高3G上网卡设备速率(usbserial.c)
- WDF开发USB设备驱动教程(2)
- USB如何检测到设备的插入-usb技术入门教程1
- USB Composite Class Device ( USB 复合设备 )
- MFC 笔记 申请设备子类 加入图片 自定义字体 修改窗口标题
- Windows主机端与自定义USB HID设备通信详解
- c++primer第二章“c++定义了几种基本类型,还提供了可用于自定义数据类型的机制,此外,我们还能修改已有的类型以形成复合类型”
- Windows主机端与自定义USB HID设备通信详解
- 流程图控件FlowChart.NET中如何自定义复合节点教程(一)
- WDF开发USB设备驱动教程(3)
- Windows主机端与自定义USB HID设备通信详解
- Vista中禁止向USB存储设备写数据简单教程
- windows主机端与自定义USB HID设备通信详解
- VirtualBox 使用技巧 教程三 VirtualBox使用USB设备
- WDF开发USB设备驱动教程(1)
- Windows主机端与自定义USB HID设备通信详解
- Windows主机端与自定义USB HID设备通信详解
- USB复合设备与组合设备的区别
- Windows主机端与自定义USB HID设备通信详解