OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9254|回复: 34

STM32F103C8 USB键盘 numLock capLock 灯如何实现

[复制链接]

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-2-11 16:57:29 | 显示全部楼层 |阅读模式
88金钱
STM32F103C8 USB键盘 numLock capLock 灯如何实现? 最近研究了一下 STM32 USB键盘程序,从论坛下载了几个例程.基本上可以实现普通的键盘功能.只差LED了.USB 报告描述符已经是正确的.有05 08的LED宣告.例程是一个鼠标程序.目前找不到LED的报告事件或者函数.知道的朋友请指点一下.谢谢..

最佳答案

查看完整内容[请看2#楼]

请看我用过的USB HID键盘描述符c文件:(也是用原来的Joystick描述符,修改过用的)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 16:57:30 | 显示全部楼层
请看我用过的USB HID键盘描述符c文件:(也是用原来的Joystick描述符,修改过用的)
usb_desc.rar (2.34 KB, 下载次数: 734)
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-2-11 18:39:12 | 显示全部楼层
帮顶
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 18:39:51 | 显示全部楼层
HID键盘指示灯的定义,见下图:
    HID键盘--键盘指示灯.jpg
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 19:17:47 | 显示全部楼层
请看我曾经用过的程序实现:【注:已用到实际的应用中,请放心参考使用!】

typedef struct tag_caps_find{
        u8 caps_row;
        u8 caps_col;
        u8 caps_chk;
}CAPS_FIND_ST;


CAPS_FIND_ST   caps_find;


/****************************************************************************       
* 功    能: 查找模式按键是否具备,分析其键的位置
*---------------------------------------------------------------------------*
* 入口参数: pdata        A pointer to parameter passed to task.
* 出口参数: None
****************************************************************************/

void  Find_ModeKey_Function(void)
{
    //...............................

    //........矩阵键盘扫描{
     if(keycode==KC_LCAP){        //Caps Lock按键按下                                                         
                caps_find.caps_row=i; //USB键盘中---Caps按键所在的行位置数值
                caps_find.caps_col=j;         //USB键盘中---Caps按键所在的行位置数值
                if(caps_find.caps_chk==0){ //Caps按键没有按下
                   caps_find.caps_chk=1; //识别Caps按键按下
                }                                               
      }


     if(keycode==KC_LSFT){        //左SHIT按键
         //.................................
         //.................................
         //.................................
     }

     if(keycode==KC_RSFT){        //右SHIT按键       
         //.................................
         //.................................
         //.................................
     }

     if(keycode==KC_LCTL){        //左CTRL按键
         //.................................
         //.................................
         //.................................
     }

     if(keycode==KC_RCTL){        //右CTRL按键       
         //.................................
         //.................................
         //.................................
      }  

     if(keycode==KC_LGUI){        //左GUI按键
         //.................................
         //.................................
         //.................................
     }

     if(keycode==KC_RGUI){        //右GUI按键
         //.................................
         //.................................
         //.................................
     }


    if(keycode==KC_LALT){        //左ALT按键
        //.................................
         //.................................
         //.................................
    }

    if(keycode==KC_RALT){        //右ALT按键
        //.................................
         //.................................
         //.................................

     }

   } //........矩阵键盘扫描

}

/****************************************************************************       
* 功    能:  模式按键---模式功能查找执行任务
*---------------------------------------------------------------------------*
* 入口参数: pdata        A pointer to parameter passed to task.
* 出口参数: None
****************************************************************************/

void Task_ModeKey_Find(void *pdata)
{  
   u8 i;               
  pdata = pdata;
  while(1)
  {        

       Find_ModeKey_Function();


       //.................................
       //.................................

       //.................................
       //.................................

       switch(caps_find.caps_chk){                       
         case 0:
            break;
         case 1:  //找到caps按键键位
               if(key_matrix[caps_find.caps_row][caps_find.caps_col] == 0x00){  //如果caps按键按下
                    flag_caps_press=1;       
                    caps_find.caps_chk=2; //按下caps按键---转换状态               
                    CAPS_LED_ON(); //点亮CAPS指示灯       

                    CoOS_ENTER_CRITICAL();  
                    Buffer0_Scan[0] |=0x02; //输出为大写状态
                    CoOS_EXIT_CRITICAL();         
                                       
                    do{
                        CoTickDelay(100);                                
                    }while(key_matrix[caps_find.caps_row][caps_find.caps_col] == 0x00);//等待caps按键抬起
                }                                       
                break;
          case 2: //Caps按键按下过后----直到Caps按键释放
               if(key_matrix[caps_find.caps_row][caps_find.caps_col] == 0x00){  //如果caps按键按下
                    flag_caps_press=0;       
                    caps_find.caps_chk=1; //回复初始状态       
                    CAPS_LED_OFF(); //熄灭CAPS指示灯       
                    CoOS_ENTER_CRITICAL();  
                    Buffer0_Scan[0] &=~0x02; //输出为小写状态
                    CoOS_EXIT_CRITICAL();     
                                       
                    do{
                         CoTickDelay(100);                                
                    }while(key_matrix[caps_find.caps_row][caps_find.caps_col] == 0x00);//等待caps按键抬起
                }                                       
                break;                               
        } //end:switch(caps_find.caps_chk)               

      //.................................
       //.................................

       //.................................
       //.................................


       CoTickDelay(100);

     }//end: while(1)
}



回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 19:33:39 | 显示全部楼层
请看原来的:  
   USB键盘固件开发需求说明:


    USB键盘固件开发需求说明.jpg
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 19:38:07 | 显示全部楼层
请看:
   usb键盘固件升级_使用说明:

   usb键盘固件升级_使用说明.jpg
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 19:50:03 | 显示全部楼层
本帖最后由 操作系统 于 2017-2-11 19:51 编辑

理论上是通过PC发过来的数据包解析.并不是通过键盘扫描到某个键去实现LED灯.目前大小写键的功能是有的.numLock的功能都是有的.就是没有实现LED灯的指示.灯的指示是PC发过来的信号决定的.现在的问题是端点1收不到PC机发过来的数据包.端点1接收功能已经打开.我已经做过蓝牙键盘.对键盘各功能算是有点了解..蓝牙键盘的LED灯指示是底层代码做好了.会有相关的事件发到APP层.
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 19:54:42 | 显示全部楼层
xfcjava3 发表于 2017-2-11 18:39
HID键盘指示灯的定义,见下图:

现在的问题是键盘收不到这个字节..PC是在EP1,还是在EP0输出的呢.
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:07:12 | 显示全部楼层
我做过的:实现LED灯的指示了。PC同时插上2个键盘,都是正常的。都测试通过的。
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:13:27 | 显示全部楼层
你发送的Buffer0的数据,会同时影响PC的Buffer0的数据。

我也是用软件测试过的。自己做的键盘,按下CAPS按键,NUM Lock按键,就是PC端APP的Caps指示,Num Lock指示也是正常的。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 20:14:28 | 显示全部楼层
void Joystick_Reset(void)
{
  /* Set Joystick_DEVICE as not configured */
  pInformation->Current_Configuration = 0;
  pInformation->Current_Interface = 0;/*the default Interface*/

  /* Current Feature initialization */
  pInformation->Current_Feature = Joystick_ConfigDescriptor[7];

  SetBTABLE(BTABLE_ADDRESS);

  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);

  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 10);
  //SetEPRxStatus(ENDP1, EP_RX_DIS);
  SetEPTxStatus(ENDP1, EP_TX_NAK);


  SetEPRxAddr(ENDP1,ENDP1_RXADDR);
  SetEPRxCount(ENDP1,1);
  SetEPRxStatus(ENDP1, EP_TX_VALID);
  
  bDeviceState = ATTACHED;

  /* Set this device to response on default address */
  SetDeviceAddress(0);
}
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:16:21 | 显示全部楼层
你可以用 keyboardtestutility 这个工具测试你的键盘是否正常 keyboardtestutility.rar (727.26 KB, 下载次数: 577)
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:18:46 | 显示全部楼层
PC是在EP1输出的
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 20:19:56 | 显示全部楼层
xfcjava3 发表于 2017-2-11 20:07
我做过的:实现LED灯的指示了。PC同时插上2个键盘,都是正常的。都测试通过的。

你是怎么测试的.你是测试你的键盘动作.别人的键盘的灯会有动作是吧.你反过来试一下.别人的键盘上的CAPLOCK键按下时,你的键盘上的灯会有相应的指示吗
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:22:04 | 显示全部楼层
EP1_OUT_CallBack.jpg
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:22:59 | 显示全部楼层
当然了,就像你说的一样。不然的话,键盘就是工作不正常的了!!!!
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:35:15 | 显示全部楼层
1、你要是只使用CAPS,NUM LOCK的状态,就按照我15楼的提示去做!
2、如果你是要自己做一个完全兼容PC的usb键盘,你就得按照我说的去做。
      自己做的usb兼容键盘,当然要有键盘扫描什么的。
      CAPS,NUM LOCK指示灯的点亮或者熄灭,当然是自己的软件去控制了。
      没有驱动,LED指示灯,不会自动点亮的,难道不是吗。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 20:36:25 | 显示全部楼层

可能是我的报告描述符还有哪里不正确..我刚才在网上看到圈圈的一些关于把鼠标工程修改为键盘工程的一些要点..也要谢谢的你的指点.
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:36:26 | 显示全部楼层
我做的USB键盘,都是在windows,MAC OS系统下,测试通过的了,有什么可以怀疑的!
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:42:23 | 显示全部楼层
请放心使用,都是测试通过的!!!
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 20:42:53 | 显示全部楼层
本帖最后由 操作系统 于 2017-2-11 20:44 编辑
xfcjava3 发表于 2017-2-11 20:35
1、你要是只使用CAPS,NUM LOCK的状态,就按照我15楼的提示去做!
2、如果你是要自己做一个完全兼容PC的usb ...

键扫这一块我的程序已经完成了.LED驱动也完成了.像15楼一样的回调函数也有了..就是不进函数..可能是初始化或者描述符哪里不正确.
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:44:01 | 显示全部楼层
我的QQ: 390350125. 有事情,可以通过QQ联系。
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:45:55 | 显示全部楼层
用我12楼提供的: keyboardtestutility ,这个工具测试你的键盘是否正常!!!
只有用这个工具测试通过了,是每一个按键都要测试通过,才可以证明你的usb键盘功能才是正常的!!!
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-11 20:49:09 | 显示全部楼层
xfcjava3 发表于 2017-2-11 20:41
请看我用过的USB HID键盘描述符c文件:(也是用原来的Joystick描述符,修改过用的)

我的端点数据是1,可能是这里不对.为什么端点数量是2呢. 除端点0外,不是只有一个端点吗.
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2017-2-11 20:49:20 | 显示全部楼层
我有现成的工程项目文件,都是测试通过的。
还可以使用键盘虚拟出来的u盘,更新固件程序,非常方便!
我usb键盘,可以随意定义每一个按键的键位,
可以满足不同使用人员的要求,特别是玩游戏人员的使用!
回复

使用道具 举报

5

主题

19

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-7-29
在线时间
10 小时
发表于 2017-2-12 12:13:58 | 显示全部楼层
mark一下
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-2-13 11:18:36 | 显示全部楼层
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 10);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxAddr(ENDP1,ENDP1_RXADDR);
  SetEPRxCount(ENDP1,1);
  SetEPRxStatus(ENDP1, EP_TX_VALID);
  SetEPRxValid(ENDP1); //很多的例程没有这一条指令,可能不行.
//新增这个函数,并注解他的宏.
void EP1_OUT_Callback(void)
{
ui DataLen;
  
    DataLen = GetEPRxCount(ENDP1);
        if(DataLen == 1)
                {
                me.ep1out = 1;
               PMAToUserBufferCopy(&me.led, ENDP1_RXADDR, DataLen);
                }
        SetEPRxValid(ENDP1);
     // LED驱动程序自己加上.由事件 me.ep1out 触发
}
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2013-6-2
在线时间
12 小时
发表于 2017-10-11 15:40:17 | 显示全部楼层
正遇到这个问题,楼主的问题解决了吗
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-10-11 16:12:20 | 显示全部楼层
解决了.
回复

使用道具 举报

6

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2017-11-24
在线时间
27 小时
发表于 2017-11-24 16:19:15 | 显示全部楼层
我也遇到和你一样的问题,进入不了EP1_OUT_CALLBACK()这个回调函数,不知道楼主怎么解决的,仿真一直进不去这个函数
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2017-11-25 11:32:52 | 显示全部楼层
时间太久了.不记得具体了细节了.好像是与代码有关.SDP HID宣告也有关.
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2018-10-20
在线时间
9 小时
发表于 2019-7-12 17:34:09 | 显示全部楼层
xfcjava3 发表于 2017-2-11 16:57
请看我用过的USB HID键盘描述符c文件:(也是用原来的Joystick描述符,修改过用的)

HAL库里怎么添加接收得端点?
回复

使用道具 举报

3

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2019-7-4
在线时间
23 小时
发表于 2021-10-26 17:01:30 | 显示全部楼层
请问USB键盘进入BIOS,程序怎么改,有参考吗??
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
 楼主| 发表于 2021-10-28 08:57:13 | 显示全部楼层
lipei 发表于 2021-10-26 17:01
请问USB键盘进入BIOS,程序怎么改,有参考吗??

进入BIOS设置对键盘有没有要求,还真没有研究过呢?
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 16:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表