6893|6

9805

帖子

24

TA的资源

版主

楼主
 

LPC1500体验+使用NXP LPC1549做的一个超好玩的USB键盘 [复制链接]

本帖最后由 littleshrimp 于 2014-9-12 15:33 编辑

使用NXP LPC1549做的一个超好玩的USB键盘
1、做的是什么
这是一个非常有意思的东西,是一个防止别人偷偷使用你电脑的小装置,它的实际作用并不大,可以说根本没有实用价值,但是可以通过它让像我这样的小菜们更好的熟悉这款单片机,熟悉USB HID方面的开发,通过设计一个小项目来带动学习是很好玩的一件事。
2、它有什么功能
它是通过LPC1549实现的一个具有特殊功能的USB键盘,可以捕获使用者按下caps lock按键的状态,并通过判断按下的次数决定是否解锁,没解锁的时候此键盘通过不断发送win+l按键组合来锁定windows 系统,通过发送backspace 按键来干扰用户输入密码。只有解锁后此键盘才能消停。
3、它可以有什么功能(留给想玩的朋友开发)
a 可以增加判断每次按键的间隔时间功能来增加密码难度
b 可以增加RTC电池,便于记录每次开机的时间,用户通过发出特定指令让键盘把开机记录(开机时间,使用多长时间,什么时候关机)输出到记事本上(以后再也不用担心别人看没看我电脑啦)
c 玩过蓝牙的朋友也可以用CC2540做一个这样的键盘,把复杂的密码写到单片机里,当检测到用户手机并且验证成功时自动把密码输入到登录界面里,检测不到手机就一顿乱输入,把系统锁死。这样就再也不用怕密码级别不够和密码太难记不住了,而且还能防止别人偷看你密码,防止通过键盘声或键盘痕迹破解密码呢!哈哈,这可真是安全部门必备神器。
4、为什么要做这个
a 为了骗开发板,这是我最喜欢这些活动的地方(各种开发板没少骗),为了多接触一些器件,方便时间产品时选型。因为自己申请样品画板比较费时间,做出来的东西还不一定行不行,买官方的还太贵。
b 为了骗奖品,不提做设计就要收回开发板,就做吧,既然做了就尽量好好做吧,骗点奖品也是好的。
c 为了学习、进步,自从参加活动以来我已经研究出一套如何骗开发板方法了,哈哈(还能有点出息不),还有看过我发帖的朋友能够发现我发帖的质量也比以前有了小小的进步,很多东西也规范化了点,我是一个乐于分享的人,但是碍于自己写的东西太拿不出手,所以这点进步对我来说挺重要的。
d 顺便给和我一样的小菜起个头,有机会可以一起交流我的qq1440507229
e 就是不为了产品本身要实现的功能
5、我是怎么做的
NXP官方例程里有一个usbd_rom_hid_keyboard的例程,里边基本功能已经实现,我呢只是给
lpcopen_2_08c_keil_iar_nxp_lpcxpresso_1549\applications\lpc15xx\examples\usbd_rom\usbd_rom_hid_keyboard\hid_keyboard.c
做了一个小小的外科手术。
官方例程的文件在这里 lpcopen_2_08c_keil_iar_nxp_lpcxpresso_1549.zip (2.56 MB, 下载次数: 57)
不过避免医疗事故发生在动手术前还要了解一下usb hid的小常识。TI有个资料比较不错SLAA514.pdf  Application Report  
USB Keyboard Using MSP430 MCU.pdf.rar (273 KB, 下载次数: 38)
别的我也没细看,最关心的还是下边这张表,里边说明Report(我理解为键盘通过USB给电脑发送的数据)的格式。

Report 的第0个字节代表键盘的功能按键,LeftCtrl ,Left Shift,Left Alt,Left GUI分别代表键盘左边的CTRL键,SHIFT键,ALT键和Window图标的那个键(锁定windows就是使用这个按键配合L键来实现的)。
Report 的第1个字节保留不使用。Report2至第7可以设置6个按键,实现除功能键以外的6个按键同时按下,按下的顺序是从数据的低字节到高字节,比如在byte2里设置了’c’ byte3里设置了’a’,这时往记事本里输入的顺序是’c’,’a’
知道原理以后剩下的就是简单的逻辑问题了,首先要找到处理caps lock状态的地方,它在
lpcopen_2_08c_keil_iar_nxp_lpcxpresso_1549\applications\lpc15xx\examples\usbd_rom\usbd_rom_hid_keyboard\hid_keyboard.c
文件的Keyboard_SetReport函数内:

  1.     /* we will reuse standard EP0Buf */
  2.     if (length == 0) {
  3.         return LPC_OK;
  4.     }
  5.     /* ReportID = SetupPacket.wValue.WB.L; */
  6.     switch (pSetup->wValue.WB.H) {
  7.     case HID_REPORT_OUTPUT:
  8.         /*  If the USB host tells us to turn on the NUM LOCK LED,
  9.          *  then turn on LED#2.
  10.          */
  11.         if (**pBuffer & 0x02) {//判断caps lock指示灯状态
  12.             Board_LED_Set(0, 1);
  13.       if(caps_lock_flag == 0)//如果caps lock为1会反复执行此处,计数让其只在caps lock状态发生一次变化时才加1
  14.       {
  15.         caps_lock_flag = 1;//更新标志
  16.         caps_lock_counter++;
  17.       }
  18.         }
  19.         else {
  20.       caps_lock_flag = 0;//更新标志
  21.             Board_LED_Set(0, 0);
  22.         }
  23.         break;

  24.     case HID_REPORT_INPUT:                /* Not Supported */
  25.     case HID_REPORT_FEATURE:            /* Not Supported */
  26.         return ERR_USBD_STALL;
  27.     }
  28.     return LPC_OK;
复制代码

我定义一个变量
caps_lock_counter,记录caps lock状态改变的次数。
Keyboard_SetReport这个函数会被频繁的执行所以要在只有caps lock改变时才对caps_lock_counter加加。
Keyboard_UpdateReport里添加一段代码,当caps_lock_counter小于5时就向电脑输入指定按键,锁定并干扰电脑。
否则就点亮开发板上的绿灯,指示锁定解除。

  1. /* Routine to update keyboard state */
  2. static void Keyboard_UpdateReport(void)
  3. {
  4.      HID_KEYBOARD_CLEAR_REPORT(&g_keyBoard.report[0]);//清数据
  5.    if(caps_lock_counter<5)//
  6.     {
  7.       if(lock_flag == 0)
  8.       {
  9.          lock_flag = 1;
  10.          g_keyBoard.report[0] = 0x08;
  11.          g_keyBoard.report[2] = 0x0F;
  12.       }
  13.       else if(lock_flag == 1)
  14.       {
  15.          lock_flag = 2;
  16.          //g_keyBoard.report[0] = 0xff;
  17.          g_keyBoard.report[2] = 0x2A;
  18.          //g_keyBoard.report[3] = 0x0F;
  19.          //g_keyBoard.report[4] = 0x0F;
  20.       }
  21.       else
  22.       {
  23.         lock_flag = 0;
  24.       }
  25.     }
  26.     else
  27.     {      
  28.             Board_LED_Set(1, 1);
  29.     }
  30. }
复制代码

Keyboard_UpdateReport函数中,没解锁时首先是发送win+l锁定windows的组合键,这时如果是在windows登录以后才执行的话,系统肯定是被锁上了(如果电脑有密码的话,否则是退到登录界面),然后防止别人输入你的密码只按win+l是不行的,还要反复切换成backspace键删除别人输入的密码(够损的)
0x08对应WIN0x0F对应L0x2A对应BACKSPACE键。


  1. // The following section defines the HID Usage codes for each defined key on the
  2. // keyboard.  These are defined in the HID "Usage Tag" (HUT) specification.

  3. #define usbUsageReserved            0x00
  4. #define usbUsageErrorRollOver        0x01
  5. #define usbUsagePOSTFail            0x02
  6. #define usbUsageErrorUndefined        0x03
  7. #define usbUsageA                    0x04
  8. #define usbUsageB                    0x05
  9. #define usbUsageC                    0x06
  10. #define    usbUsageD                    0x07
  11. #define usbUsageE                    0x08
  12. #define usbUsageF                    0x09
  13. #define usbUsageG                    0x0A
  14. #define usbUsageH                    0x0B
  15. #define usbUsageI                    0x0C
  16. #define usbUsageJ                    0x0D
  17. #define usbUsageK                    0x0E
  18. #define usbUsageL                    0x0F
  19. #define usbUsageM                    0x10
  20. #define usbUsageN                    0x11
  21. #define usbUsageO                    0x12
  22. #define usbUsageP                    0x13
  23. #define usbUsageQ                    0x14
  24. #define usbUsageR                    0x15
  25. #define usbUsageS                    0x16
  26. #define usbUsageT                    0x17
  27. #define usbUsageU                    0x18
  28. #define usbUsageV                    0x19
  29. #define usbUsageW                    0x1A
  30. #define usbUsageX                    0x1B
  31. #define usbUsageY                    0x1C
  32. #define usbUsageZ                    0x1D
  33. #define usbUsage1                    0x1E
  34. #define usbUsage2                    0x1F
  35. #define usbUsage3                    0x20
  36. #define usbUsage4                    0x21
  37. #define usbUsage5                    0x22
  38. #define usbUsage6                    0x23
  39. #define usbUsage7                    0x24
  40. #define usbUsage8                    0x25
  41. #define usbUsage9                    0x26
  42. #define usbUsage0                    0x27
  43. #define usbUsageEnter                0x28
  44. #define usbUsageEscape                0x29
  45. #define usbUsageBackspace            0x2A
  46. #define usbUsageTab                    0x2B
  47. #define usbUsageSpacebar            0x2C
  48. #define usbUsageMinus                0x2D
  49. #define usbUsageEqual                0x2E
  50. #define usbUsageLeftBracket            0x2F
  51. #define usbUsageRightBracket        0x30
  52. #define usbUsageBackslash            0x31
  53. #define usbUsageVerticalBar            0x32
  54. #define usbUsageSemicolon            0x33
  55. #define usbUsageApostrophe            0x34
  56. #define usbUsageTilde                0x35
  57. #define usbUsageComma                0x36
  58. #define usbUsagePeriod                0x37
  59. #define usbUsageSlash                0x38
  60. #define usbUsageCapsLock            0x39
  61. #define usbUsageF1                    0x3A
  62. #define usbUsageF2                    0x3B
  63. #define usbUsageF3                    0x3C
  64. #define usbUsageF4                    0x3D
  65. #define usbUsageF5                    0x3E
  66. #define usbUsageF6                    0x3F
  67. #define usbUsageF7                    0x40
  68. #define usbUsageF8                    0x41
  69. #define usbUsageF9                    0x42
  70. #define usbUsageF10                    0x43
  71. #define usbUsageF11                    0x44
  72. #define usbUsageF12                    0x45
  73. #define usbUsagePrintScreen            0x46
  74. #define usbUsageScrollLock            0x47
  75. #define usbUsagePause                0x48
  76. #define usbUsageInsert                0x49
  77. #define usbUsageHome                0x4A
  78. #define usbUsagePageUp                0x4B
  79. #define usbUsageDeleteForward        0x4C
  80. #define usbUsageEnd                    0x4D
  81. #define usbUsagePageDown            0x4E
  82. #define usbUsageRightArrow            0x4F
  83. #define usbUsageLeftArrow            0x50
  84. #define usbUsageDownArrow            0x51
  85. #define usbUsageUpArrow                0x52
  86. #define usbUsageKeypadNumlock        0x53
  87. #define usbUsageKeypadSlash            0x54
  88. #define usbUsageKeypadAsterisk        0x55
  89. #define usbUsageKeypadMinus            0x56
  90. #define usbUsageKeypadPlus            0x57
  91. #define usbUsageKeypadEnter            0x58
  92. #define usbUsageKeypad1                0x59
  93. #define usbUsageKeypad2                0x5A
  94. #define usbUsageKeypad3                0x5B
  95. #define usbUsageKeypad4                0x5C
  96. #define usbUsageKeypad5                0x5D
  97. #define usbUsageKeypad6                0x5E
  98. #define usbUsageKeypad7                0x5F
  99. #define usbUsageKeypad8                0x60
  100. #define usbUsageKeypad9                0x61
  101. #define usbUsageKeypad0                0x62
  102. #define usbUsageKeypadPeriod        0x63
  103. #define usbUsageNonUsBackslash        0x64
  104. #define usbUsageWindowsKey            0x65
  105. #define usbUsagePower                0x66
  106. #define usbUsageKeypadEqual            0x67
  107. #define usbUsageF13                    0x68
  108. #define usbUsageF14                    0x69
  109. #define usbUsageF15                    0x6A
  110. #define usbUsageF16                    0x6B
  111. #define usbUsageF17                    0x6C
  112. #define usbUsageF18                    0x6D
  113. #define usbUsageF19                    0x6E
  114. #define usbUsageF20                    0x6F
  115. #define usbUsageF21                    0x70
  116. #define usbUsageF22                    0x71
  117. #define usbUsageF23                    0x72
  118. #define usbUsageF24                    0x73
  119. #define usbUsageExecute                0x74
  120. #define usbUsageHelp                0x75
  121. #define usbUsageMenu                0x76
  122. #define usbUsageSelect                0x77
  123. #define usbUsageStop                0x78
  124. #define usbUsageAgain                0x79
  125. #define usbUsageUndo                0x7A
  126. #define usbUsageCut                    0x7B
  127. #define usbUsageCopy                0x7C
  128. #define usbUsagePaste                0x7D
  129. #define usbUsageFind                0x7E
  130. #define usbUsageMute                0x7F
  131. #define usbUsageVolumeUp            0x80
  132. #define usbUsageVolumneDown            0x81
  133. #define usbUsageLockingCapsLock        0x82
  134. #define usbUsageLockingNumLock        0x83
  135. #define usbUsageLockingScrollLock    0x84
  136. #define usbUsageKeypadComma            0x85
  137. #define usbUsageAS400KeypadEqual    0x86
  138. #define usbUsageInternational1        0x87
  139. #define usbUsageInternational2        0x88
  140. #define usbUsageInternational3        0x89
  141. #define usbUsageInternational4        0x8A
  142. #define usbUsageInternational5        0x8B
  143. #define usbUsageInternational6        0x8C
  144. #define usbUsageInternational7        0x8D
  145. #define usbUsageInternational8        0x8E
  146. #define usbUsageInternational9        0x8F
  147. #define usbUsageLang1                0x90
  148. #define usbUsageLang2                0x91
  149. #define usbUsageLang3                0x92
  150. #define usbUsageLang4                0x93
  151. #define usbUsageLang5                0x94
  152. #define usbUsageLang6                0x95
  153. #define usbUsageLang7                0x96
  154. #define usbUsageLang8                0x97
  155. #define usbUsageLang9                0x98
  156. #define usbUsageAlternateErase        0x99
  157. #define usbUsageSysReq                0x9A
  158. #define usbUsageCancel                0x9B
  159. #define usbUsageClear                0x9C
  160. #define usbUsagePrior                0x9D
  161. #define usbUsageReturn                0x9E
  162. #define usbUsageSeparator            0x9F
  163. #define usbUsageOut                    0xA0
  164. #define usbUsageOper                0xA1
  165. #define usbUsageClearAgain            0xA2
  166. #define usbUsageCrSelProps            0xA3
  167. #define usbUsageExSel                0xA4
  168. #define usbUsageLeftControl            0xE0
  169. #define usbUsageLeftShift            0xE1
  170. #define usbUsageLeftAlt                0xE2
  171. #define usbUsageLeftGUI                0xE3
  172. #define usbUsageRightControl        0xE4
  173. #define usbUsageRightShift            0xE5
  174. #define usbUsageRightAlt            0xE6
  175. #define usbUsageRightGUI            0xE7
复制代码

另外附上按键对应文件,里边已经定义好键盘会用到的所有按键。
我是不会告诉你它是在TI USB开发包的
MSP430_USB_Developers_Package_3_0_0_0\MSP430_USB_API_Stacks\examples\hidExamples\hidTraditional\IAR\keyboard_H8_Example\main.h
下发现的。

TI USB开发包MSP430_USB_Developers_Package-3.0-Installer.rar软件太大不能上传,谁喜欢自己下吧。
最后在上电配置完USB后加一段时间的延时再发送按键好让用户有足够多的时间解锁,防止刚开机时乱按影响系统启动。
另外还有一个是判断数据正忙的标志,这个是通过一个回调函数清除的,但是在开机的过程中乱输入按键会导致不能执行回调函数,不清零就不会执行下一次发送按键指令,所以加了这么一句话

  1.             /* send report data */
  2.             if (g_keyBoard.tx_busy == 0) {
  3.                 g_keyBoard.tx_busy = 1;
  4.         busy_counter = 0;
  5.                 USBD_API->hw->WriteEP(g_keyBoard.hUsb, HID_EP_IN, &g_keyBoard.report[0], KEYBOARD_REPORT_SIZE);
  6.             }
  7.       else
  8.       {
  9.         //重新开机无法执行Keyboard_EpIN_Hdlr函数,使g_keyBoard.tx_busy一直为1
  10.         //如果不判断g_keyBoard.tx_busy一直往里写的话会导致系统错误HardFault_Handler
  11.         if(busy_counter++ > 10)//当busy10次以后复位g_keyBoard.tx_busy
  12.         {
  13.           busy_counter = 0;
  14.           g_keyBoard.tx_busy = 0;
  15.         }
  16.       }
复制代码

在一段时间还忙的话
g_keyBoard.tx_busy就清零,有人说能不能不判断g_keyBoard.tx_busy标志,就是一顿写行吗?不行,完全不顾单片机的感受只顾乱写会气死单片机的,HardFault_Handler就是它要对你说的话,不信你就试试。
6、作品展示



7、设计文件
hid_keyboard.c.rar (3.01 KB, 下载次数: 36)
hid_main.c.rar (2.3 KB, 下载次数: 32)
lpcopen_2_08c_keil_iar_nxp_lpcxpresso_1549.zip (2.56 MB, 下载次数: 57)
USB Keyboard Using MSP430 MCU.pdf.rar (273 KB, 下载次数: 38)




此帖出自NXP MCU论坛

最新回复

还顺便骗了大批观众  详情 回复 发表于 2014-9-12 23:18

赞赏

3

查看全部赞赏

点赞 关注(1)
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 

回复
举报

1158

帖子

2

TA的资源

版主

沙发
 
很好玩
此帖出自NXP MCU论坛
 
 
 

回复

1042

帖子

6

TA的资源

纯净的硅(中级)

板凳
 
牛人啊;
不过图片拍的不清晰;
此帖出自NXP MCU论坛

点评

你说的应该是视频吧?  详情 回复 发表于 2014-9-14 15:02
 
 
 

回复

578

帖子

0

TA的资源

纯净的硅(初级)

4
 
楼主厉害
此帖出自NXP MCU论坛
 
个人签名刻苦学习,共同进步
 
 

回复

161

帖子

0

TA的资源

一粒金砂(中级)

5
 
楼主做的哟意思,看了两次你的帖子,觉得你是为大神,大神,厉害。
此帖出自NXP MCU论坛
 
 
 

回复

1297

帖子

2

TA的资源

纯净的硅(中级)

6
 
还顺便骗了大批观众
此帖出自NXP MCU论坛
 
 
 

回复

9805

帖子

24

TA的资源

版主

7
 
music_586 发表于 2014-9-12 18:40
牛人啊;
不过图片拍的不清晰;

你说的应该是视频吧?
此帖出自NXP MCU论坛
 
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

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