原创 USB键盘的实现

2010-4-26 21:44 5598 14 16 分类: MCU/ 嵌入式

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 


 


一、移植过程分析


 


1、移植前的准备工作


现在我们实现一个系统,很少是从0开始,都是在已有的系统上借鉴和修改,这是软件可重用性的表现。


1)我的USB键盘的目标


摇杆的“上、右、下、左”分别代表“a b c d”,OK键表示“左GUI键”,PB2表示“左CTRL键”。


我的实现完全是在“JoyStickMouse”例程的基础上进行修改。


2)需要修改的地方


首先是描述符:要多使用一个端点、因此接口描述符要修改,增加一个端点描述符,报告描述符也要修改成键盘数据集合。


 


其次是要增加中断输出端点处理。分析数据,并控制LED灯(把它当成大小写指示灯。


 


2、移植前的准备工作


开始进行移植。


1)增加命令ukey


鼠标是用的命令umouse,这里改成ukey,由于这两个现在还不能同时实现,所以命令数不用增加,直接在原来的基础上修改。这里甚至连命令处理函数的名称我都不修改了。


 


2)修改usb_desc.c


将设备描述符里的产品序列号由02 00 改为 02 01


HID接口描述符所用的端点数目 1 改为 2


 


增加了一个端点描述符:


    0x07,          /*bLength: Endpoint Descriptor size*/


    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/


    0x01,          /*使用1号的输出端点*/


    0x03,          /*中断端点*/


    0x04,          /*wMaxPacketSize: 4 Byte max */


    0x00,


    0x20,


加了这个端点描述符后,要改变配置集合描述符的长度。加上7就行了,这个在头文件中用“define”重新定义就行了。


 


最重要的修改报告描述符:


上一篇博文这个工作已经做好了。改过之后的描述符变为61=0x3D个字节,所以要修改报告描述符的长度,这个也是在头文件中修改。


 


修改字符串描述符,产品名称改为“ntsc2004的小键盘”。产品序列号改变为“stm2004”。


改变之后,先单独编译一下,没有发生错误。


 


3)增加一个usb_endp.c


这个函数专门用于处理中断输出端点数据的接收和处理。


中断端点1输出处理是调用:


void (*pEpInt_OUT[7])(void) =


  {


    EP1_OUT_Callback,


    EP2_OUT_Callback,


    EP3_OUT_Callback,


    EP4_OUT_Callback,


    EP5_OUT_Callback,


    EP6_OUT_Callback,


    EP7_OUT_Callback,


  };


第一个函数进行处理的,所以我们在这个文件里就实现这个函数。


 


先包含必须的头文件。


usb_conf.h中,先把以下语句注释掉。


//#define  EP1_OUT_Callback   NOP_Process。因为我们接下来要实现它。


先不具体实现功能,只加了以下代码:


void EP1_OUT_Callback(void){


#if usb_debug


      Uart_PutString("端点1中断输出\r\n" );


#endif


}


 


既然用到了端点1的中断输出,则必须先进行初始化,包括端点类型的设置(中断类型)、端点描述符表的初始化(给它设置接收缓冲区的地址和大小)。这个是在用户提供的初始化代码中完成的。


初始化代码在Device_Properti->Reset()函数中。


  SetEPType(ENDP1, EP_INTERRUPT);


  SetEPTxAddr(ENDP1, ENDP1_TXADDR); //设置发送缓冲区。


  SetEPRxAddr(ENDP1, ENDP1_RXADDR); //设置接收缓冲区,接收报告一个字节。


  SetEPTxCount(ENDP1, 2);  //发送的最大数组2个。


  SetEPRxCount(ENDP1,64); //接收的最大数值64个。


  SetEPRxStatus(ENDP1, EP_RX_NAK);


  SetEPTxStatus(ENDP1, EP_TX_NAK); //设置端点状态,现在为不响应


 


那么端点什么时候变得有效呢?


4)修改usbmouse.c


我这里就不改变文件名称了。


5)改变Joystick_Send(KeyAct)的行为。


void Joystick_Send(u8 Keys)


{


  u8 Mouse_Buffer[2] = {0, 0};


  switch (Keys)


  {


    case 'a':


      Mouse_Buffer[1]=0x59;  //对应小键盘上的“<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1


      break;


    case 'b':


      Mouse_Buffer[1]=0x5A;  // 2


      break;


    case 'c':


      Mouse_Buffer[1]=0x5B;


      break;


    case 'd':


      Mouse_Buffer[1]=0x5C;;


      break;


    case 1:


       Mouse_Buffer[0] |= 0x01;  //Ctrl键。


      break;


    case 4:


      Mouse_Buffer[0] |= 0x08;  //GUI


      break;


    default:


      return;


  }


 


  UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 2);


  SetEPTxValid(ENDP1);


  Mouse_Buffer[0] = 0;


  Mouse_Buffer[1] = 0;


}


 


6)编写usb_endp.c


在端点1输出中断中如下处理:


void EP1_OUT_Callback(void){


    u8 OutBuf;


#if usb_debug


      Uart_PutString("端点1数据:" );


#endif


      PMAToUserBufferCopy(&OutBuf, GetEPRxAddr(ENDP1), 1);  //读取一个字节的数据到用户缓冲区 OutBuf


#if usb_debug


      Uart_PutHex(OutBuf);


      Uart_PutString("\r\n" );


#endif


      if ( OutBuf & 0x01 )


             GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);


    else


        GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_RESET);


    SetEPRxValid(ENDP1);


}


 


 


3、下载测试。


整个工程编译下载,很快就成功了。在设备管理器发现了该设备如下所示:


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


点击看大图


 

 


但按键测试的时候,发现了这样的问题:


打开一个word文档,定位光标。然后按下一个键“UP”,结果发现文档一直持续不停的写入“1”。


想了想,应该是没有发送按键释放消息,在按键松开以后,键盘还应该发一个“对应按键位置数据清0的消息。


这样程序稍微改一下,再次下载,程序已经正常工作了。


 


还有没有实现“abcd”的输入,而是取代以小键盘上的“1234。因为我不知道abcdHID对应键值,而1234在《圈圈》书上有,所以我也懒得去测试abcd的代码了,直接就用1234


 


 

文章评论2条评论)

登录后参与讨论

用户377235 2015-8-27 11:58

谢谢你的无私分享

用户973744 2011-11-5 07:22

请问下nthq2004 在按键松开以后,键盘还应该发一个“对应按键位置数据清0”的消息 要如何实现,谢谢!
相关推荐阅读
nthq2004 2010-05-08 20:04
USB自定义设备驱动02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  本来还想编写应用程序测试一下自定...
nthq2004 2010-05-07 21:35
USB自定义设备驱动01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、USB设备驱动入门1、学习目...
nthq2004 2010-05-04 21:01
智林开发板上实现自定义的USB HID设备
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、自定义HID设备的相关概念1...
nthq2004 2010-05-01 21:58
U盘例程在智林开发板上的移植
 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 一、移植前的准备工作1、有哪些操...
nthq2004 2010-04-30 19:19
U盘实现流程跟踪分析02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   二、追踪USB大容量设备的实现...
nthq2004 2010-04-27 21:51
U盘实现流程跟踪分析01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   一、追踪USB大容量设备的实现...
我要评论
2
14
关闭 站长推荐上一条 /2 下一条