6808|14

69

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

在万利的STM32学习板上实现USB多媒体键盘 [复制链接]


   圈圈通过对原来的USB摇杆实例进行修改,做了一个USB HID多媒体键盘,可以调节音量、启动Windows Media
播放器、停止/暂停播放、打开网页、打开计算器等等功能。由于摇杆和多媒体键盘都是HID设备,因而改动的工作量很
少,只需要修改一下VID、PID,字符串描述符、报告描述符、返回报告的格式即可。
  板上各按键的功能分配如下:摇杆往上音量增加;摇杆往下音量降低;摇杆往左静音;摇杆往右启动Windows
Media播放器;摇杆中键(确认键)为播放/暂停(对千千静听等播放器也有效);按键KEY2为打开网页;按键KEY3
为打开计算器。
   从这里下载整个代码包:http://blog.ednchina.com/computer00/141572/message.aspx
下载该压缩包,解压到ManleyEKBoardEKSTM32FUSBDemo(8M osc)USBDemoUSBLibdemos目录下,
然后编译,烧写调试即可。
    运行后可以看到弹出的新硬件,以及设备管理器中的设备,一个为HID设备,一个为标准用户控制设备,
如下图所示:



报告描述符的代码如下:
const u8 ReportDescriptor[SIZ_REPORT_DESC] =
{
 0x05, 0x0c, // USAGE_PAGE (Consumer Page)
 0x09, 0x01, // USAGE (Consumer Control)
 0xa1, 0x01, // COLLECTION (Application)
 0x09, 0xea, //   USAGE (Volume Decrement) 
 0x09, 0xe9, //   USAGE (Volume Increment) 
 0x09, 0xe2, //   USAGE (Mute)
 0x09, 0xcd, //   USAGE (Play/Pause)
 0x0a, 0x83, 0x01, //USAGE (Windows Media Player(0x183))
 0x0a, 0x23, 0x02, //USAGE (AC Home(0x0223))
 0x0a, 0x92, 0x01, //USAGE (AL Calculator(0x192))
 0x15, 0x00, //     LOGICAL_MINIMUM (0)
 0x25, 0x01, //     LOGICAL_MAXIMUM (1)
 0x95, 0x07, //     REPORT_COUNT (7)
 0x75, 0x01, //     REPORT_SIZE (1)
 0x81, 0x02, //     INPUT (Data,Var,Abs)
 0x75, 0x01, //     REPORT_SIZE (1)
 0x95, 0x01, //     REPORT_COUNT (1)
 0x81, 0x03, //     INPUT (Cnst,Var,Abs)
 0xc0        // END_COLLECTION
}; /* ReportDescriptor */
 
此帖出自stm32/stm8论坛

最新回复

                                 有个void DataStageOut(void)函数,在函数末尾,增加对数据的处理:#define SET_REPORT 0x09if(pInformation->ControlState == WAIT_STATUS_IN) //如果数据已经接收完毕{ //则对数据处理 if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))           && RequestNo == SET_REPORT)  //如果是SET REPORT请求 {  //则处理SET REPORT请求   }}前面的接收数据可能你还要自己改下,不知道他这个缓冲区是从哪里获取来的。最简单的办法就是自己开辟一个缓冲区来代替那里的Buffer来接收数据。   详情 回复 发表于 2008-8-24 11:42
点赞 关注
 

回复
举报

72

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

圈圈已经成精了,STM32的USB开发包已经玩熟了

                                 说实话,这个USB开发包非常好用,我们已经用了近十年。
此帖出自stm32/stm8论坛
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

板凳
 

说实话,我对这个程序的结构并不了解……但是我知道改什

这个程序具体是怎样工作的我不关心,我只修改描述符、返回数据和接收数据就行了,哈哈……
此帖出自stm32/stm8论坛
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

4
 

香主还能把程序结构做个简单介绍

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

5
 

00是做项目前期预研非常不错,至于做产品还不知道,呵呵,

                                  
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

6
 

能用就好

                                 介绍程序结构就免了,ST不是教育机构,ST的程序也不是最好的,只是个Demo,如果为了学习研究,还是要靠自己分析。
此帖出自stm32/stm8论坛
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

7
 

呵呵,虽然我没有仔细看过代码,但我可以按我的理解来说

应该是在端点0输出中断回调函数中处理建立过程的标准请求,然后根据不同的请求,
选择需要返回不同的数据(主要是各种描述符)或者处理输出的数据。而在端点0输入
中断的回调函数中,返回剩余的(一个数据包不能发送完)数据。主程序则是
等待设置配置,
一旦设置配置之后,那么非0端点就可以启用了,然后根据需要对这些端点操作即可。

对于枚举过程的各种描述符的请求以及设置地址、设置配置等等,原来的程序模板都
已经实现了,所以我们只需要修改描述符中的数据以及数据即可。除非你要增加新的
描述符,才需要去修改这些代码。对于非0端点,需要在中断中处理数据的话,只需要
自己增加对应端点的回调函数即可,当然还要记得事先对相应的端点做初始化。
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

8
 

原例程中的按键处理并没有消抖处理,俺重新改了按键的驱

unsigned char KeyCurrent,KeyOld,KeyNoChangedTime;
unsigned char KeyPress;
unsigned char KeyDown,KeyUp,KeyLast;

#define KEY_SEL    0x01
#define KEY_RIGHT  0x02
#define KEY_LEFT   0x04
#define KEY_DOWN   0x10
#define KEY_UP     0x08
#define KEY_2      0x20
#define KEY_3      0x40

#define KeyIO ((((GPIOD->IDR)>>11)&0x1F)|((((GPIOD->IDR)>>3)&0x03)<<5))

void KeyScan(void);
/********************************************************************
函数功能:键盘扫描。每5ms调用一次
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void KeyScan(void)
{
 //开始键盘扫描
 //保存按键状态到当前按键情况
 //KeyCurrent总共有8个bit
 //当某个开关按下时,对应的bit为1
      
 KeyCurrent=~KeyIO;    

 if(KeyCurrent!=KeyOld)  //说明按键情况发生了改变
  {
   KeyNoChangedTime=0;       //键盘按下时间为0
   KeyOld=KeyCurrent;        //保存当前按键情况
   return;
  }
 else
  {
   KeyNoChangedTime++;         //按下时间累计
   if(KeyNoChangedTime>=1)     //如果按下时间足够
   {
    KeyNoChangedTime=1;
    KeyPress=KeyOld;      //保存按键
    KeyDown|=(~KeyLast)&(KeyPress); //求出新按下的键
    KeyUp|=KeyLast&(~KeyPress);     //求出新释放的键
    KeyLast=KeyPress;            //保存当前按键情况
   }
  }
}


当某个键按下时,在KeyDown中对应的位被设置为1;某个键被释放时,KeyUp中对应的位为1;
KeyPress中保存的是当前按键的按住情况,某位按住时位为1。

KeyDown和KeyUp中的值使用后要手动清除,表示已经处理了这个事件,而KeyPress不用手动清除,
它一直反映按键的按住情况。

实际使用方法范例如下:

if(KeyDown & KEY_UP)   //摇杆往上移动键按下
if(KeyDown & KEY_RIGHT) //摇杆往右移动键按下
if(KeyPress & KEY_DOWN) //摇杆往下移动被按住了
if(KeyUp & KEY_LEFT) //摇杆往左移动由原来的按住变成了松开
if(KeyUp || KEY_DOWN) //有按键状态变动

万利的板子上有两个按键KEY2和KEY3,另外还有一个摇杆:KEY_SEL,KEY_LEFT,KEY_RIGHT,KEY_UP,KEY_DOWN.
当初为了统一名称,都叫成KEY了,后面的摇杆改成叫Joystick似乎更好一些~~~~
不然两个KEY_UP和KEY_DOWN会让人混饶...
此帖出自stm32/stm8论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

9
 

Re

                                 版主,改过的代码能支持 SET REPORT 吗?既然你增加了一个端口来控制LED,那如何和电脑的键盘同步控制LED呢
此帖出自stm32/stm8论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

10
 

USB键盘和电脑的键盘同步控制LED是由PC端的USB键盘驱动完成

                                 USB设备端不管也不知道这个同步的问题。
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

11
 

不支持SET REPORT,我的是通过中断端点输出报告的

主机在检测到HID设备有中断输出端点时,将使用中断输出端点发送报告。
我在中断输出端点中读出数据,控制LED即可。主机会自动同步各块键盘之间的LED灯。
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

12
 

哈哈,圈圈你这个就是SET REPORT

                                 只不过这个SET REPORT走的是中断端点而不是控制端点。
此帖出自stm32/stm8论坛
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

13
 

不一样的,SET REPORT是通过端点0的控制传输,

                                 而通过中断端点,则是中断传输,使用WriteFile API函数来操作的。
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

14
 

Re:

                                 我这里的应用 一定要加SET REPORT 啊!  很佩服ST写USB 库的人,强大的数据结构和编程风格,我搞了一天 也没有把SET REPORT 加上,也搞过 LPC2300和C8051F326 的USB驱动 ,很是惭愧
此帖出自stm32/stm8论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

15
 

应该是在usb_core.c里面修改吧,

有个void DataStageOut(void)函数,在函数末尾,增加对数据的处理:

#define SET_REPORT 0x09

if(pInformation->ControlState == WAIT_STATUS_IN) //如果数据已经接收完毕
{
 //则对数据处理
 if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
           && RequestNo == SET_REPORT)  //如果是SET REPORT请求
 {
  //则处理SET REPORT请求
  
 }
}


前面的接收数据可能你还要自己改下,不知道他这个缓冲区是从哪里获取来的。最简单的办法就是自己开辟一个缓冲区来代替那里的Buffer来接收数据。
此帖出自stm32/stm8论坛
 
 
 

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

查找数据手册?

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
快速回复 返回顶部 返回列表