打印
[USB芯片]

【CH32X035评估板测评】+ USB_Keyboard

[复制链接]
4165|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
袁胜富|  楼主 | 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代码表达:
typedef struct {
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;

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


三、代码

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

#include "debug.h"
#include "ch32x035_usbfs_device.h"


//================================================================================
//================================================================================
//  Keyboard

#define KEY_LEFT_CTRL   0x80
#define KEY_LEFT_SHIFT    0x81
#define KEY_LEFT_ALT    0x82
#define KEY_LEFT_GUI    0x83
#define KEY_RIGHT_CTRL    0x84
#define KEY_RIGHT_SHIFT   0x85
#define KEY_RIGHT_ALT   0x86
#define KEY_RIGHT_GUI   0x87

#define KEY_UP_ARROW    0xDA
#define KEY_DOWN_ARROW    0xD9
#define KEY_LEFT_ARROW    0xD8
#define KEY_RIGHT_ARROW   0xD7
#define KEY_BACKSPACE   0xB2
#define KEY_TAB       0xB3
#define KEY_RETURN      0xB0
#define KEY_ESC       0xB1
#define KEY_INSERT      0xD1
#define KEY_DELETE      0xD4
#define KEY_PAGE_UP     0xD3
#define KEY_PAGE_DOWN   0xD6
#define KEY_HOME      0xD2
#define KEY_END       0xD5
#define KEY_CAPS_LOCK   0xC1
#define KEY_F1        0xC2
#define KEY_F2        0xC3
#define KEY_F3        0xC4
#define KEY_F4        0xC5
#define KEY_F5        0xC6
#define KEY_F6        0xC7
#define KEY_F7        0xC8
#define KEY_F8        0xC9
#define KEY_F9        0xCA
#define KEY_F10       0xCB
#define KEY_F11       0xCC
#define KEY_F12       0xCD

typedef struct
{
    void    (*begin)(void);
    size_t  (*write)(uint8_t k);
    size_t  (*press)(uint8_t k);
    size_t  (*release)(uint8_t k);
    void    (*releaseAll)(void);
    void    (*print)(char *fmt,...);
}_KeyBorad;


extern _KeyBorad   KeyBorad;
extern uint8_t USBConActive;
//  Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct {
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;

void sendReport(KeyReport *keys);
void begin(void);
size_t write(uint8_t k);
size_t press(uint8_t k);
size_t release(uint8_t k);
void releaseAll(void);

#endif/*KEYBOARD_H*/

KeyBorad.c代码
#include "Keyboard.h"
#include "debug.h"
#include "String.h"
#include "Stdlib.h"
#include "Stdio.h"
#include "Stdarg.h"
#include "ch32x035_usbfs_device.h"
//================================================================================
//================================================================================
//  Keyboard
uint8_t USBConActive = 1;//USB激活状态标志    1-没有激活 0-激活了
KeyReport _keyReport;

void begin(void)
{
    USBFS_RCC_Init( );
    USBFS_Device_Init( ENABLE , PWR_VDD_SupplyVoltage());//键盘初始化
}

void sendReport(KeyReport *keys)
{
    if(!(USBConActive == 0))
    {
        return;
    }
  uint8_t buf[8] = {keys->modifiers, keys->reserved, keys->keys[0], keys->keys[1],
                    keys->keys[2], keys->keys[3], keys->keys[4], keys->keys[5]
                   };
  USBFS_Endp_DataUp( DEF_UEP1, buf, sizeof( buf ), DEF_UEP_CPY_LOAD );/*端点上传数据*/
  //delay required to prevent persistent key when call print
  Delay_Ms(10);
}

//extern const uint8_t _asciimap[128] PROGMEM;

#define SHIFT 0x80
const uint8_t _asciimap[128] = {
  0x00,             // NUL
  0x00,             // SOH
  0x00,             // STX
  0x00,             // ETX
  0x00,             // EOT
  0x00,             // ENQ
  0x00,             // ACK
  0x00,             // BEL
  0x2a,     // BS Backspace
  0x2b,     // TAB  Tab
  0x28,     // LF Enter
  0x00,             // VT
  0x00,             // FF
  0x00,             // CR
  0x00,             // SO
  0x00,             // SI
  0x00,             // DEL
  0x00,             // DC1
  0x00,             // DC2
  0x00,             // DC3
  0x00,             // DC4
  0x00,             // NAK
  0x00,             // SYN
  0x00,             // ETB
  0x00,             // CAN
  0x00,             // EM
  0x00,             // SUB
  0x00,             // ESC
  0x00,             // FS
  0x00,             // GS
  0x00,             // RS
  0x00,             // US

  0x2c,      //  ' '
  0x1e | SHIFT,  // !
  0x34 | SHIFT,  // "
  0x20 | SHIFT,  // #
  0x21 | SHIFT,  // $
  0x22 | SHIFT,  // %
  0x24 | SHIFT,  // &
  0x34,          // '
  0x26 | SHIFT,  // (
  0x27 | SHIFT,  // )
  0x25 | SHIFT,  // *
  0x2e | SHIFT,  // +
  0x36,          // ,
  0x2d,          // -
  0x37,          // .
  0x38,          // /
  0x27,          // 0
  0x1e,          // 1
  0x1f,          // 2
  0x20,          // 3
  0x21,          // 4
  0x22,          // 5
  0x23,          // 6
  0x24,          // 7
  0x25,          // 8
  0x26,          // 9
  0x33 | SHIFT,    // :
  0x33,          // ;
  0x36 | SHIFT,    // <
  0x2e,          // =
  0x37 | SHIFT,    // >
  0x38 | SHIFT,    // ?
  0x1f | SHIFT,    // @
  0x04 | SHIFT,    // A
  0x05 | SHIFT,    // B
  0x06 | SHIFT,    // C
  0x07 | SHIFT,    // D
  0x08 | SHIFT,    // E
  0x09 | SHIFT,    // F
  0x0a | SHIFT,    // G
  0x0b | SHIFT,    // H
  0x0c | SHIFT,    // I
  0x0d | SHIFT,    // J
  0x0e | SHIFT,    // K
  0x0f | SHIFT,    // L
  0x10 | SHIFT,    // M
  0x11 | SHIFT,    // N
  0x12 | SHIFT,    // O
  0x13 | SHIFT,    // P
  0x14 | SHIFT,    // Q
  0x15 | SHIFT,    // R
  0x16 | SHIFT,    // S
  0x17 | SHIFT,    // T
  0x18 | SHIFT,    // U
  0x19 | SHIFT,    // V
  0x1a | SHIFT,    // W
  0x1b | SHIFT,    // X
  0x1c | SHIFT,    // Y
  0x1d | SHIFT,    // Z
  0x2f,          // [
  0x31,          // bslash
  0x30,          // ]
  0x23 | SHIFT,  // ^
  0x2d | SHIFT,  // _
  0x35,          // `
  0x04,          // a
  0x05,          // b
  0x06,          // c
  0x07,          // d
  0x08,          // e
  0x09,          // f
  0x0a,          // g
  0x0b,          // h
  0x0c,          // i
  0x0d,          // j
  0x0e,          // k
  0x0f,          // l
  0x10,          // m
  0x11,          // n
  0x12,          // o
  0x13,          // p
  0x14,          // q
  0x15,          // r
  0x16,          // s
  0x17,          // t
  0x18,          // u
  0x19,          // v
  0x1a,          // w
  0x1b,          // x
  0x1c,          // y
  0x1d,          // z
  0x2f | SHIFT,  // {
  0x31 | SHIFT,  // |
  0x30 | SHIFT,  // }
  0x35 | SHIFT,  // ~
  0       // DEL
};

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


size_t press(uint8_t k)
{
  uint8_t i;
  if (k >= 136) {     // it's a non-printing key (not a modifier)
    k = k - 136;
  } else if (k >= 128) {  // it's a modifier key
    _keyReport.modifiers |= (1 << (k - 128));
    k = 0;
  } else {        // it's a printing key
    k = pgm_read_byte(_asciimap + k);
    if (!k) {
      return 0;
    }
    if (k & 0x80) {           // it's a capital letter or other character reached with shift
      _keyReport.modifiers |= 0x02; // the left shift modifier
      k &= 0x7F;
    }
  }

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

    for (i = 0; i < 6; i++) {
      if (_keyReport.keys[i] == 0x00) {
        _keyReport.keys[i] = k;
        break;
      }
    }
    if (i == 6) {
     return 0;
    }
  }
  sendReport(&_keyReport);
  return 1;
}

// release() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t release(uint8_t k)
{
  uint8_t i;
  if (k >= 136) {     // it's a non-printing key (not a modifier)
    k = k - 136;
  } else if (k >= 128) {  // it's a modifier key
    _keyReport.modifiers &= ~(1 << (k - 128));
    k = 0;
  } else {        // it's a printing key
    k = pgm_read_byte(_asciimap + k);
    if (!k) {
      return 0;
    }
    if (k & 0x80) {             // it's a capital letter or other character reached with shift
      _keyReport.modifiers &= ~(0x02);  // the left shift modifier
      k &= 0x7F;
    }
  }

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

  sendReport(&_keyReport);
  return 1;
}

void releaseAll(void)
{
  _keyReport.keys[0] = 0;
  _keyReport.keys[1] = 0;
  _keyReport.keys[2] = 0;
  _keyReport.keys[3] = 0;
  _keyReport.keys[4] = 0;
  _keyReport.keys[5] = 0;
  _keyReport.modifiers = 0;
  sendReport(&_keyReport);
}

size_t write(uint8_t c)
{
  uint8_t p = press(c);  // Keydown
  release(c);            // Keyup
  return p;              // just return the result of press() since release() almost always returns 1
}

/**
* 自动格式输出
*/
void print(char *fmt,...)
{
    char T1_Bufferr[128];
    uint16_t i,j;
    va_list ap;
    va_start(ap,fmt);
    vsprintf(T1_Bufferr,fmt,ap);
    va_end(ap);
    i=strlen(T1_Bufferr);
    for(j=0;j<i;j++)
    {
        write(T1_Bufferr[j]);
    }
}

//结构体初始化
_KeyBorad   KeyBorad =
{
        begin,
        write,
        press,
        release,
        releaseAll,
        print
};



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

/*********************************************************************
* @fn      main
*
* [url=home.php?mod=space&uid=247401]@brief[/url]   Main program.
*
* [url=home.php?mod=space&uid=266161]@return[/url]  none
*/
int main(void)
{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf("ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    KeyBorad.begin();
    while(1)
    {
        KeyBorad.print("YuanShengfu\r\n");
        Delay_Ms(500);
    }
}




四、展示




源码在附件

  

CH32X035C8T6_USBKeyBoard.zip

582.86 KB

使用特权

评论回复
沙发
linhuikui| | 2024-3-19 16:15 | 只看该作者
正在找这个功能

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

140

帖子

2

粉丝