[USB芯片] 【CH32X035评估板测评】+ USB_Keyboard

[复制链接]
 楼主| 袁胜富 发表于 2023-10-14 20:43 | 显示全部楼层 |阅读模式
本帖最后由 袁胜富 于 2023-10-14 22:58 编辑

一、概述

CH32X035拥有设备控制器(USBFS),可以使用其为USB键盘设备,本评测基于官方例程修改而来,进一步封装只需要调用结构体成员函数即可完成相关字符的输出。
于是乎为了和大家分享,我出了这个文章。

二、原理分析


键盘发送给PC的数据每次8个字节:
Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7 Byte8定义分别是:Byte1 -- |--bit0: Left Control是否按下,按下为1 |--bit1: Left Shift 是否按下,按下为1 |--bit2: Left Alt 是否按下,按下为1 |--bit3: Left GUI 是否按下,按下为1 |--bit4: Right Control是否按下,按下为1 |--bit5: Right Shift 是否按下,按下为1 |--bit6: Right Alt 是否按下,按下为1 |--bit7: Right GUI 是否按下,按下为1Byte2 --保留位Byte3--Byte8
-- 这六个为普通按键
综上所述,8个字节可用C代码表达:
  1. typedef struct {
  2.   uint8_t modifiers;
  3.   uint8_t reserved;
  4.   uint8_t keys[6];
  5. } KeyReport;

当按键按下:键盘发送给PC8个字节的0x00.


三、代码

键盘.h代码:
  1. #ifndef KEYBOARD_H
  2. #define KEYBOARD_H

  3. #include "debug.h"
  4. #include "ch32x035_usbfs_device.h"


  5. //================================================================================
  6. //================================================================================
  7. //  Keyboard

  8. #define KEY_LEFT_CTRL   0x80
  9. #define KEY_LEFT_SHIFT    0x81
  10. #define KEY_LEFT_ALT    0x82
  11. #define KEY_LEFT_GUI    0x83
  12. #define KEY_RIGHT_CTRL    0x84
  13. #define KEY_RIGHT_SHIFT   0x85
  14. #define KEY_RIGHT_ALT   0x86
  15. #define KEY_RIGHT_GUI   0x87

  16. #define KEY_UP_ARROW    0xDA
  17. #define KEY_DOWN_ARROW    0xD9
  18. #define KEY_LEFT_ARROW    0xD8
  19. #define KEY_RIGHT_ARROW   0xD7
  20. #define KEY_BACKSPACE   0xB2
  21. #define KEY_TAB       0xB3
  22. #define KEY_RETURN      0xB0
  23. #define KEY_ESC       0xB1
  24. #define KEY_INSERT      0xD1
  25. #define KEY_DELETE      0xD4
  26. #define KEY_PAGE_UP     0xD3
  27. #define KEY_PAGE_DOWN   0xD6
  28. #define KEY_HOME      0xD2
  29. #define KEY_END       0xD5
  30. #define KEY_CAPS_LOCK   0xC1
  31. #define KEY_F1        0xC2
  32. #define KEY_F2        0xC3
  33. #define KEY_F3        0xC4
  34. #define KEY_F4        0xC5
  35. #define KEY_F5        0xC6
  36. #define KEY_F6        0xC7
  37. #define KEY_F7        0xC8
  38. #define KEY_F8        0xC9
  39. #define KEY_F9        0xCA
  40. #define KEY_F10       0xCB
  41. #define KEY_F11       0xCC
  42. #define KEY_F12       0xCD

  43. typedef struct
  44. {
  45.     void    (*begin)(void);
  46.     size_t  (*write)(uint8_t k);
  47.     size_t  (*press)(uint8_t k);
  48.     size_t  (*release)(uint8_t k);
  49.     void    (*releaseAll)(void);
  50.     void    (*print)(char *fmt,...);
  51. }_KeyBorad;


  52. extern _KeyBorad   KeyBorad;
  53. extern uint8_t USBConActive;
  54. //  Low level key report: up to 6 keys and shift, ctrl etc at once
  55. typedef struct {
  56.   uint8_t modifiers;
  57.   uint8_t reserved;
  58.   uint8_t keys[6];
  59. } KeyReport;

  60. void sendReport(KeyReport *keys);
  61. void begin(void);
  62. size_t write(uint8_t k);
  63. size_t press(uint8_t k);
  64. size_t release(uint8_t k);
  65. void releaseAll(void);

  66. #endif/*KEYBOARD_H*/

KeyBorad.c代码
  1. #include "Keyboard.h"
  2. #include "debug.h"
  3. #include "String.h"
  4. #include "Stdlib.h"
  5. #include "Stdio.h"
  6. #include "Stdarg.h"
  7. #include "ch32x035_usbfs_device.h"
  8. //================================================================================
  9. //================================================================================
  10. //  Keyboard
  11. uint8_t USBConActive = 1;//USB激活状态标志    1-没有激活 0-激活了
  12. KeyReport _keyReport;

  13. void begin(void)
  14. {
  15.     USBFS_RCC_Init( );
  16.     USBFS_Device_Init( ENABLE , PWR_VDD_SupplyVoltage());//键盘初始化
  17. }

  18. void sendReport(KeyReport *keys)
  19. {
  20.     if(!(USBConActive == 0))
  21.     {
  22.         return;
  23.     }
  24.   uint8_t buf[8] = {keys->modifiers, keys->reserved, keys->keys[0], keys->keys[1],
  25.                     keys->keys[2], keys->keys[3], keys->keys[4], keys->keys[5]
  26.                    };
  27.   USBFS_Endp_DataUp( DEF_UEP1, buf, sizeof( buf ), DEF_UEP_CPY_LOAD );/*端点上传数据*/
  28.   //delay required to prevent persistent key when call print
  29.   Delay_Ms(10);
  30. }

  31. //extern const uint8_t _asciimap[128] PROGMEM;

  32. #define SHIFT 0x80
  33. const uint8_t _asciimap[128] = {
  34.   0x00,             // NUL
  35.   0x00,             // SOH
  36.   0x00,             // STX
  37.   0x00,             // ETX
  38.   0x00,             // EOT
  39.   0x00,             // ENQ
  40.   0x00,             // ACK
  41.   0x00,             // BEL
  42.   0x2a,     // BS Backspace
  43.   0x2b,     // TAB  Tab
  44.   0x28,     // LF Enter
  45.   0x00,             // VT
  46.   0x00,             // FF
  47.   0x00,             // CR
  48.   0x00,             // SO
  49.   0x00,             // SI
  50.   0x00,             // DEL
  51.   0x00,             // DC1
  52.   0x00,             // DC2
  53.   0x00,             // DC3
  54.   0x00,             // DC4
  55.   0x00,             // NAK
  56.   0x00,             // SYN
  57.   0x00,             // ETB
  58.   0x00,             // CAN
  59.   0x00,             // EM
  60.   0x00,             // SUB
  61.   0x00,             // ESC
  62.   0x00,             // FS
  63.   0x00,             // GS
  64.   0x00,             // RS
  65.   0x00,             // US

  66.   0x2c,      //  ' '
  67.   0x1e | SHIFT,  // !
  68.   0x34 | SHIFT,  // "
  69.   0x20 | SHIFT,  // #
  70.   0x21 | SHIFT,  // $
  71.   0x22 | SHIFT,  // %
  72.   0x24 | SHIFT,  // &
  73.   0x34,          // '
  74.   0x26 | SHIFT,  // (
  75.   0x27 | SHIFT,  // )
  76.   0x25 | SHIFT,  // *
  77.   0x2e | SHIFT,  // +
  78.   0x36,          // ,
  79.   0x2d,          // -
  80.   0x37,          // .
  81.   0x38,          // /
  82.   0x27,          // 0
  83.   0x1e,          // 1
  84.   0x1f,          // 2
  85.   0x20,          // 3
  86.   0x21,          // 4
  87.   0x22,          // 5
  88.   0x23,          // 6
  89.   0x24,          // 7
  90.   0x25,          // 8
  91.   0x26,          // 9
  92.   0x33 | SHIFT,    // :
  93.   0x33,          // ;
  94.   0x36 | SHIFT,    // <
  95.   0x2e,          // =
  96.   0x37 | SHIFT,    // >
  97.   0x38 | SHIFT,    // ?
  98.   0x1f | SHIFT,    // @
  99.   0x04 | SHIFT,    // A
  100.   0x05 | SHIFT,    // B
  101.   0x06 | SHIFT,    // C
  102.   0x07 | SHIFT,    // D
  103.   0x08 | SHIFT,    // E
  104.   0x09 | SHIFT,    // F
  105.   0x0a | SHIFT,    // G
  106.   0x0b | SHIFT,    // H
  107.   0x0c | SHIFT,    // I
  108.   0x0d | SHIFT,    // J
  109.   0x0e | SHIFT,    // K
  110.   0x0f | SHIFT,    // L
  111.   0x10 | SHIFT,    // M
  112.   0x11 | SHIFT,    // N
  113.   0x12 | SHIFT,    // O
  114.   0x13 | SHIFT,    // P
  115.   0x14 | SHIFT,    // Q
  116.   0x15 | SHIFT,    // R
  117.   0x16 | SHIFT,    // S
  118.   0x17 | SHIFT,    // T
  119.   0x18 | SHIFT,    // U
  120.   0x19 | SHIFT,    // V
  121.   0x1a | SHIFT,    // W
  122.   0x1b | SHIFT,    // X
  123.   0x1c | SHIFT,    // Y
  124.   0x1d | SHIFT,    // Z
  125.   0x2f,          // [
  126.   0x31,          // bslash
  127.   0x30,          // ]
  128.   0x23 | SHIFT,  // ^
  129.   0x2d | SHIFT,  // _
  130.   0x35,          // `
  131.   0x04,          // a
  132.   0x05,          // b
  133.   0x06,          // c
  134.   0x07,          // d
  135.   0x08,          // e
  136.   0x09,          // f
  137.   0x0a,          // g
  138.   0x0b,          // h
  139.   0x0c,          // i
  140.   0x0d,          // j
  141.   0x0e,          // k
  142.   0x0f,          // l
  143.   0x10,          // m
  144.   0x11,          // n
  145.   0x12,          // o
  146.   0x13,          // p
  147.   0x14,          // q
  148.   0x15,          // r
  149.   0x16,          // s
  150.   0x17,          // t
  151.   0x18,          // u
  152.   0x19,          // v
  153.   0x1a,          // w
  154.   0x1b,          // x
  155.   0x1c,          // y
  156.   0x1d,          // z
  157.   0x2f | SHIFT,  // {
  158.   0x31 | SHIFT,  // |
  159.   0x30 | SHIFT,  // }
  160.   0x35 | SHIFT,  // ~
  161.   0       // DEL
  162. };

  163. #define pgm_read_byte(addr) (*(const unsigned char *)(addr))


  164. size_t press(uint8_t k)
  165. {
  166.   uint8_t i;
  167.   if (k >= 136) {     // it's a non-printing key (not a modifier)
  168.     k = k - 136;
  169.   } else if (k >= 128) {  // it's a modifier key
  170.     _keyReport.modifiers |= (1 << (k - 128));
  171.     k = 0;
  172.   } else {        // it's a printing key
  173.     k = pgm_read_byte(_asciimap + k);
  174.     if (!k) {
  175.       return 0;
  176.     }
  177.     if (k & 0x80) {           // it's a capital letter or other character reached with shift
  178.       _keyReport.modifiers |= 0x02; // the left shift modifier
  179.       k &= 0x7F;
  180.     }
  181.   }

  182.   // Add k to the key report only if it's not already present
  183.   // and if there is an empty slot.
  184.   if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
  185.       _keyReport.keys[2] != k && _keyReport.keys[3] != k &&
  186.       _keyReport.keys[4] != k && _keyReport.keys[5] != k) {

  187.     for (i = 0; i < 6; i++) {
  188.       if (_keyReport.keys[i] == 0x00) {
  189.         _keyReport.keys[i] = k;
  190.         break;
  191.       }
  192.     }
  193.     if (i == 6) {
  194.      return 0;
  195.     }
  196.   }
  197.   sendReport(&_keyReport);
  198.   return 1;
  199. }

  200. // release() takes the specified key out of the persistent key report and
  201. // sends the report.  This tells the OS the key is no longer pressed and that
  202. // it shouldn't be repeated any more.
  203. size_t release(uint8_t k)
  204. {
  205.   uint8_t i;
  206.   if (k >= 136) {     // it's a non-printing key (not a modifier)
  207.     k = k - 136;
  208.   } else if (k >= 128) {  // it's a modifier key
  209.     _keyReport.modifiers &= ~(1 << (k - 128));
  210.     k = 0;
  211.   } else {        // it's a printing key
  212.     k = pgm_read_byte(_asciimap + k);
  213.     if (!k) {
  214.       return 0;
  215.     }
  216.     if (k & 0x80) {             // it's a capital letter or other character reached with shift
  217.       _keyReport.modifiers &= ~(0x02);  // the left shift modifier
  218.       k &= 0x7F;
  219.     }
  220.   }

  221.   // Test the key report to see if k is present.  Clear it if it exists.
  222.   // Check all positions in case the key is present more than once (which it shouldn't be)
  223.   for (i = 0; i < 6; i++) {
  224.     if (0 != k && _keyReport.keys[i] == k) {
  225.       _keyReport.keys[i] = 0x00;
  226.     }
  227.   }

  228.   sendReport(&_keyReport);
  229.   return 1;
  230. }

  231. void releaseAll(void)
  232. {
  233.   _keyReport.keys[0] = 0;
  234.   _keyReport.keys[1] = 0;
  235.   _keyReport.keys[2] = 0;
  236.   _keyReport.keys[3] = 0;
  237.   _keyReport.keys[4] = 0;
  238.   _keyReport.keys[5] = 0;
  239.   _keyReport.modifiers = 0;
  240.   sendReport(&_keyReport);
  241. }

  242. size_t write(uint8_t c)
  243. {
  244.   uint8_t p = press(c);  // Keydown
  245.   release(c);            // Keyup
  246.   return p;              // just return the result of press() since release() almost always returns 1
  247. }

  248. /**
  249. * 自动格式输出
  250. */
  251. void print(char *fmt,...)
  252. {
  253.     char T1_Bufferr[128];
  254.     uint16_t i,j;
  255.     va_list ap;
  256.     va_start(ap,fmt);
  257.     vsprintf(T1_Bufferr,fmt,ap);
  258.     va_end(ap);
  259.     i=strlen(T1_Bufferr);
  260.     for(j=0;j<i;j++)
  261.     {
  262.         write(T1_Bufferr[j]);
  263.     }
  264. }

  265. //结构体初始化
  266. _KeyBorad   KeyBorad =
  267. {
  268.         begin,
  269.         write,
  270.         press,
  271.         release,
  272.         releaseAll,
  273.         print
  274. };



Main.c代码
  1. #include <ch32x035_usbfs_device.h>
  2. #include <Keyboard.h>
  3. #include "debug.h"

  4. /*********************************************************************
  5. * @fn      main
  6. *
  7. * [url=home.php?mod=space&uid=247401]@brief[/url]   Main program.
  8. *
  9. * [url=home.php?mod=space&uid=266161]@return[/url]  none
  10. */
  11. int main(void)
  12. {

  13.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  14.     SystemCoreClockUpdate();
  15.     Delay_Init();
  16.     USART_Printf_Init(115200);
  17.     printf("SystemClk:%d\r\n", SystemCoreClock);
  18.     printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
  19.     KeyBorad.begin();
  20.     while(1)
  21.     {
  22.         KeyBorad.print("YuanShengfu\r\n");
  23.         Delay_Ms(500);
  24.     }
  25. }




四、展示


13852a3bf30de4f6c67bfce2a5513e02
b59f11c5515b25f2422fb0e323c2e131
0aaae6f5facf6decc4081a0bffeb40cd 源码在附件

  

CH32X035C8T6_USBKeyBoard.zip

582.86 KB, 下载次数: 28

linhuikui 发表于 2024-3-19 16:15 | 显示全部楼层
正在找这个功能
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

163

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部