原理篇4、CH9328使用
目录
- 简介
- 1、引脚介绍
- 部分引脚说明
- 2、工作模式
- 上传速度设置
- 工作模式设置:
- 3、电路连接
- 4、数据格式
- 通信协议
- 5、驱动程序
- 定义一个缓存空间
- 创建键码数组
- 键码发送
- 6、参考资料
- 资料获取
简介
1、CH9328 是一款串口转 HID 芯片,在电脑上识别为标准的 USB HID 类键盘设备。CH9328 用于单向数据传输,可以接收串口发送过来的数据(如 ASCII 码),并按照 HID 类键盘设备规范,将数据打包成标准的键盘码值通过 USB 口上传给计算机。通过提供的上位机软件,用户也可自行配置芯片的 VID、PID,以及各种字符串描述符。
2、默认串口通信波特率为 9600bps。
.
.
.
1、引脚介绍
部分引脚说明
(详细说明在 参考资料 中的网址下载说明文档)
.
.
.
.
2、工作模式
上传速度设置
CH9328的 IO1 引脚用于配置芯片的上传速度,上电时该引脚为高电平则速度配置为普通模式,上电时该引脚为低电平则速度配置为高速模式,高速模式的速度大概为普通模式的 1 倍。
.
.
工作模式设置:
工作模式 | IO2电平 | IO3电平 | IO4电平 | 功能说明 |
---|---|---|---|---|
模式0 | 1 | 1 | 1 | 该模式仅支持将可见ASCII码(如 a-z、0-9、@、#、$ 等)对应的字符转成标准的USB键值。特殊功能:接收到的串口数据包如果遇到 0x1B 时,则丢弃当前包中 0x1B 之后的数据,并将 0x1B 转换成回车键。 |
模式1 | 1 | 0 | 1 | 该模式仅支持将可见ASCII码(如 a-z、0-9、@、#、$ 等)对应的字符转成标准的USB键值。 |
模式2 | 1 | 1 | 0 | 该模式仅支持将可见ASCII码(如 a-z、0-9、@、#、$ 等)对应的字符转成标准的USB键值。特殊功能:接收到的串口数据包如果遇到 0x28 时,将 0x28 转换成回车键。 |
模式3 | 0 | 1 | 1 | 该模式为透传模式,不仅仅用于传输可见ASCII码字符。该模式下可以实现标准的USB全键盘功能。串口数据每8个字节组成一包,芯片每接收到8个字节后,直接打包通过USB口上传。即芯片为透传模式,不分析转换串口数据,直接按8个字节一包上传。故串口数据必须按照标准的USB键盘数据包进行发送。比如模拟“A”按下,则串口发送数据包为:0x00、0x00、0x04、0x00、0x00、0x00、0x00、0x00;比如模拟“A”释放,则串口发送数据包为:0x00、0x00、0x00、0x00、0x00、0x00、0x00、0x00;比如模拟“A+SHIFT”同时按下,则串口发送数据包为:0x02、0x00、0x04、0x00、0x00、0x00、0x00、0x00;比如模拟“A+SHIFT”同时释放,则串口发送数据包为:0x00、0x00、x00、0x00、0x00、0x00、0x00、0x00; |
.
.
.
3、电路连接
键盘上的电路连接原理图:
上图中已将 CH9328 的 IO1,IO3和IO4设置为高电平,IO2设置为低电平。
通过电平设置可将其工作模式设置为普通模式下的模式3(透传模式)。
.
数据手册中的电路原理图:
.
.
.
4、数据格式
在工作模式设置的模式3说明中已经大致说了数据格式。
以下为具体说明。
通信协议
使用的是CH9328的模式3。
在模式3,一次向CH9328发送8个字节的数据。
数据格式为:
[byte1][byte2][byte3][byte4][byte5][byte6][byte7][byte8]
其中第一个字节(byte1)用来标识特殊按键
[byte1]---bit0:左Ctrl 按下为1,否则为0。---bit1:左Shift 按下为1---bit2:左Alt 按下为1---bit3:左GUI 按下为1---bit4:右Ctrl 按下为1---bit5:右Shift 按下为1---bit6:右Alt 按下为1---bit7:右GUI 按下为1
.
按下左Shift 则第一个字节应该为 0000 0010
,即0x02。
完整发送的数据为
{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
.
若按下左Shift和右Ctrl 则第一个字节应该是 0000 0010
|0001 0000
的值,结果为 0x12。
(注意:这里的 ‘|’ 是 ‘或’ 符号,功能是按位相或。)
完整发送的数据为
{0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
.
第二个字节为保留字节 全部为0即可,即0x00。
第三到第八个字节为普通按键的键值,所以不加上特殊按键最多可以发送六个按键。
若按下 左Shift,左Ctrl,A,1,/ 这五个键,完整的发送数据为
{0x03, 0x00, 0x04, 0x1E, 0x38, 0x00, 0x00, 0x00};
其中 左Shift 和 左Ctrl 为 0x02 | 0x01 得到 0x03,
A的键值为 0x04,1 的键值为 0x1E,/ 的键值为 0x38。
若仅有 A 按下,然后其余按键都松开,则完整的发送数据为
{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00};
.
.
.
5、驱动程序
定义一个缓存空间
//USB发送数据 8字节大小缓存
uint8_t key_code[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
.
创建键码数组
定义键盘上每个按键对应的键码
//USB 未按下Fn时的键码
const uint8_t USB_KEY_CODE[KEYBOARD_ROW][KEYBOARD_COLUMN] = {//` ~ 1 ! 2 @ 3 # 4 $ 5 % 6 ^ 7 & 8 * 9 ( 0 ) - _ = + backspace{KEY_USB_SEPARATOR, KEY_USB_1, KEY_USB_2, KEY_USB_3, KEY_USB_4, KEY_USB_5, KEY_USB_6, KEY_USB_7, KEY_USB_8, KEY_USB_9, KEY_USB_0, KEY_USB_SUB, KEY_USB_EQUAL, KEY_USB_BACKSPACE},//tab Q q W w E e R r T t Y y U u I i O o P p [ { ] } \ |{KEY_USB_TAB, KEY_USB_Q, KEY_USB_W, KEY_USB_E, KEY_USB_R, KEY_USB_T, KEY_USB_Y, KEY_USB_U, KEY_USB_I, KEY_USB_O, KEY_USB_P, KEY_USB_LBRACKET, KEY_USB_RBRACKET, KEY_USB_BSLASH},//caps lock A a S s D d F f G g H h J j K k L l ; : ' " -- Enter{KEY_USB_CAPS_LOCK, KEY_USB_A, KEY_USB_S, KEY_USB_D, KEY_USB_F, KEY_USB_G, KEY_USB_H, KEY_USB_J, KEY_USB_K, KEY_USB_L, KEY_USB_SEMICOLON, KEY_USB_SQUOTES, 0, KEY_USB_RETURN},//shift Z z X x C c V v B b N n M m , < . > / ? shift ↑ DELETE{KEY_USB_LEFT_SHIFT, KEY_USB_Z, KEY_USB_X, KEY_USB_C, KEY_USB_V, KEY_USB_B, KEY_USB_N, KEY_USB_M, KEY_USB_COMMA, KEY_USB_FSTOP, KEY_USB_FSLASH, KEY_USB_RIGHT_SHIFT, KEY_USB_UP_ARROW, KEY_USB_DELETE},//ctrl Win alt ---- space --------- Fn ctrl ← ↓ →{KEY_USB_LEFT_CTRL, KEY_USB_LEFT_GUI, KEY_USB_LEFT_ALT, 0, 0, KEY_USB_SPACE, 0, 0, 0, 0, KEY_USB_RIGHT_CTRL, KEY_USB_LEFT_ARROW, KEY_USB_DOWN_ARROW, KEY_USB_RIGHT_ARROW}};//USB 按下Fn时第一行按键的键码
uint8_t FN_USB_Code[14] = {KEY_USB_ESC, KEY_USB_F1, KEY_USB_F2, KEY_USB_F3, KEY_USB_F4, KEY_USB_F5, KEY_USB_F6, KEY_USB_F7, KEY_USB_F8, KEY_USB_F9, KEY_USB_F10, KEY_USB_F11, KEY_USB_F12, KEY_USB_F13};
键码发送
更改第一个字节
//参数为此按键的键码和按键状态(按下为1,松开为0)。
void first_bit(uint8_t key_, uint8_t state);
.
实现方法
对缓存空间内第0字节的位操作可实现发送数据的更改。
void first_bit(uint8_t key_, uint8_t state)
{//判断键码是否正确if (key_ != 0){//如果按键为按下if (state == 1){key_code[0] = key_code[0] | key_;}else//否则当按键此按键松开{key_ = ~key_;key_code[0] = key_code[0] & key_;}}
}
.
.
更改其余字节
//参数为此按键的键码和按键状态(按下为1,松开为0)。
//因为CH9328只能发送六个普通按键的状态,
//所以当按下的按键数量大于6时,将无法发送,
//此函数可返回0/1,表示是否设置成功,
//当已经按下6个普通按键,再按下一个普通按键时,将无法设置,返回0。
uint8_t other_bit(uint8_t key_, uint8_t state)
.
实现方法
uint8_t other_bit(uint8_t key_, uint8_t state)
{//返回值,先设置为0,如果以下代码未将键码存入缓冲区,//返回值未改变,为0,//意味着已经按下6个按键,此按键无法设置。uint8_t o_ = 0;//判断键码是否正确if (key_ != 0){//如果状态为按下(1)if (state == 1){//从缓冲区的 第2字节开始查询空的位置for (uint8_t i = 2; i < 8; i++){//如果在第 i 字节找到空位置if (key_code[i] == 0x00){//将键码存入空位置中key_code[i] = key_;o_ = 1;//返回1 ,表示设置成功break;}}}//如果状态为松开(0)else if (state == 0){//从缓冲区的 第2字节开始查询此键码所在的位置for (uint8_t i = 2; i < 8; i++){//如果找到此键码保存的位置if (key_code[i] == key_){ //将键码删除,使此位置为空(0x00)。key_code[i] = 0x00;o_ = 1;//返回1 ,表示设置成功break;}}}}return o_;
}
.
.
发送缓存空间数据
原理图中ESP32的串口1连接 CH340C,用于代码下载和键盘调试,
串口2连接CH9328,用于发送按键数据。
先将ESP32的串口2打开。
Serial2.begin(9600);//波特率9600
.
发送缓存空间的数据。
Serial2.write(key_code, 8);
.
.
.
6、参考资料
1、沁恒CH9328数据手册
http://www.wch.cn/downloads/file/224.html?time=2021-01-02%2023:41:25&code=rYSU24iPmeAbHiFXl8Oyf3PsP0W8Pza8XGbBUDPw
.
.
资料获取
全部工程文件进ESP32工程群(483217976)自行下载,所有文件在 ESP32键盘 目录下。
原理篇4、CH9328使用相关推荐
- 《CDN 之我见》系列二:原理篇(缓存、安全)
2019独角兽企业重金招聘Python工程师标准>>> <CDN之我见>共由三个篇章组成,分为原理篇.详解篇和陨坑篇.本篇章适合那些从未接触过.或仅了解一些 CDN 专业 ...
- 检查压缩包是否损坏_修复损坏的gzip压缩文件之原理篇
接修复损坏的gzip压缩文件之原理篇,再次引用GZIP结构图: 已知修复一个损坏的gzip文件的关键环节在于找到下一个正常压缩包的起始点.根据结构图中的信息可知,每个压缩包的开始结构中有是否到达尾部标 ...
- Tomcat 原理篇
TOMCAT 原理篇 一.Tomcat 组成(Tomcat 由以下组件组成) 1.server a) Server是一个Catalina Servlet容器: b) Server 可以包含一个或多个s ...
- React Native JSBundle拆包之原理篇
概述 RN作为一款非常优秀的移动端跨平台开发框架,在近几年得到众多开发者的认可.纵观现在接入RN的大厂,如qq音乐.菜鸟.去哪儿,无疑不是将RN作为重点技术栈进行研发. 不过,熟悉RN的开发者也知道, ...
- 通过“四大行为”对WCF的扩展[原理篇]
整个WCF框架由两个基本的层次构成,即服务模型层和信道层.对信道层的扩展主要通过针对绑定的扩展实现,具体来说就是自定义绑定元素,以及相关的信道管理器(信道监听器和信道工厂).信道来改变对消息的处理和传 ...
- 《CDN 之我见》原理篇——CDN的由来与调度
2019独角兽企业重金招聘Python工程师标准>>> CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术.它能够有效 ...
- 原理篇 | 推荐系统之矩阵分解模型
导语:本系列文章一共有三篇,分别是 <科普篇 | 推荐系统之矩阵分解模型> <原理篇 | 推荐系统之矩阵分解模型> <实践篇 | 推荐系统之矩阵分解模型> 第一篇用 ...
- Kubernetes应用部署模型解析(原理篇)
2019独角兽企业重金招聘Python工程师标准>>> Kubernetes应用部署模型解析(原理篇) 博客分类: Kubernetes [编者按]Kubernetes可用来管理Li ...
- [zz]GMM-HMM语音识别模型 原理篇
GMM-HMM语音识别模型 原理篇 分类: Data Structure Machine Learning Data Mining 2014-05-28 20:52 20662人阅读 评论(34) 收 ...
- InnoDB原理篇:Change Buffer是如何提升索引性能的?
前言 相信很多小伙伴设计索引时,考虑更多的是索引是否能覆盖大部分的业务场景,却忽略了索引的性能. 什么?不同的索引,性能还不一样? 是的,这要从change buffer说起. Change Bu ...
最新文章
- 葡萄城报表介绍:复杂报表
- 编程语言中的Lambda 函数是如何产生的 它究竟有什么用
- MSMQ 安装问题的解决过程
- 四则运算(可怜的二柱子)2
- UVa 1368 - DNA Consensus String
- 基于FP5207的5V升12V电路设计
- 拓扑学+计算机,拓扑学与物理学结合,量子计算机正在成为现实
- S3C2440c语言汇编传参点灯
- 利用FlashPaper在web页面中显示PDF文件(兼容各浏览器)
- iso国家代码 三位字母_ISO 2字母语言代码
- stderr/stdout用法
- 移动机器人下位机软件
- 12月31日起涉线上支付的微信小程序需设置订单中心页
- echarts - 折线图 - 每分钟刷新数据并显示
- 201612-3-炉石传说
- IE浏览器对象不支持Blob属性或方法,IE浏览器不支持canvas toBlob()方法的Polyfill
- 适用于 Windows 的 5 大 PDF 编辑器
- 华为配置动态路由ISIS协议
- 连载 大学生求职七大昏招(五)说谎 4
- 省常高NOIP模拟 寻梦fantasy