描述
<p><strong>项目简述</strong></p>
<p>本项目采用启英泰伦的CI-B02GS01J语音模组识别用户指令,并将识别结果通过串口传输给MCU,MCU将识别结果转化为DOS指令并将指令通过基于HID协议的USB串口注入到PC端,进而实现对PC端的语音控制。</p>
<p>***注:由于在采购元器件时PCB板已交予立创PCB工厂加工,同时因为活动过于火爆导致原定采用的C22GS02S语音识别模组在商城内处于持续断货状态。无奈之下本项目最终采用了同样基于启英泰伦公司CI1102核心的单麦离线语音识别模组 CI-B02GS01J。
由于项目在设计之初为通信端口预留了充足的跳线端子,使得PCB板能够完美兼容后续采用的CI-B02GS01J模组。因此在实物调试正常的情况下,没有再对PCB板做大幅度调整。</p>
<hr>
<h3>演示视频</h3>
<p><a href="https://www.bilibili.com/video/BV1FA411P7kY/" target="_blank">https://www.bilibili.com/video/BV1FA411P7kY/</a></p>
<p><strong>原理及硬件描述</strong></p>
<p>本项目原定采用启英泰伦的C22GS02S语音识别模组(现采用CI-B02GS01J,以下简称语音识别模块)识别用户指令,同时结合stm32f103c8t6最小板(以下简称MCU)实现与PC通信。在项目中语音识别模块根据烧录的离线指令信息识别用户指令,并将识别结果通过自带串口传输给MCU。MCU接收到串口数据后,依据HID描述报告将指令信息转译成HID通用指令,再通过MCU自带的USB口传输至PC最终实现对PC端的控制。</p>
<p> 在硬件方面,我对各模块的串口通信引脚设计了跳线帽,以实现在不同场合对模块的烧录/通信。同时,空闲的引脚也被引出,以便后续对模块进行功能上的拓展。</p>
<p> 板载的ESP-12F为预留的扩展部分,计划用于实现语音模块的在线语音功能,以及PC端到其他设备之间的数据通信(例如:挂在PC磁盘至局域网,或者实现将PC截屏传输至手机等)。但由于时间原因,此部分功能将不在此次活动中展示。</p>
<p><strong>原理图详细描述</strong></p>
<p>1.离线语音识别模块,原定采用CI1102为核心的C22GS02S语音识别模块,用于识别用户指令。模块的RX0、TX0端口用于烧录,RX1、TX1端口用于与MCU通信,三路空闲PWM引出用于后续拓展。
<img src="//image.lceda.cn/pullimage/XCbovX7zqCggV40XDMRAjCz7uf4ZXIJ3VT3s6eof.png" alt="image.png"></p>
<p>2.stm32f103底座,用于安装stm32最小板,实现与PC端和语音模块的通信,同时为其他模块提供稳定的3.3V、5V电源。</p>
<p><img src="//image.lceda.cn/pullimage/V84drYhWJOGXijPw0ROzNBUeyba9KLYX2bunslup.png" alt="image.png"></p>
<p>3.ESP-12F拓展模块,,计划用于实现语音模块的在线语音功能,以及PC端到其他设备之间的数据通信。</p>
<p><img src="//image.lceda.cn/pullimage/1rnqbVLEMSavGNQau46EBy2NOpF7AUjphydFfSEg.png" alt="image.png"></p>
<p>4.烧录/通信跳线、空闲引脚引出以及电源稳压部分(较为简单,不做过多描述)。</p>
<p><img src="//image.lceda.cn/pullimage/DjCbLQFZx4nyTiakVp1Onyd8ROxefHa5cKrJDaoB.png" alt="image.png"></p>
<p><strong>软件开发部分关键代码</strong></p>
<pre><code>//配置HID设备描述符如下,
0x05, 0x01,// USAGE_PAGE (Generic Desktop)
0x09, 0x06,// USAGE (Keyboard)
0xa1, 0x01,// COLLECTION (Application)
0x05, 0x07,// USAGE_PAGE (Keyboard)
0x19, 0xe0,// USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7,// USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00,// LOGICAL_MINIMUM (0)
0x25, 0x01,// LOGICAL_MAXIMUM (1)
0x75, 0x01,// REPORT_SIZE (1)
0x95, 0x08,// REPORT_COUNT (8)
0x81, 0x02,// INPUT (Data,Var,Abs)
0x95, 0x01,// REPORT_COUNT (1)
0x75, 0x08,// REPORT_SIZE (8)
0x81, 0x03,// INPUT (Cnst,Var,Abs)
0x95, 0x05,// REPORT_COUNT (5)
0x75, 0x01,// REPORT_SIZE (1)
0x05, 0x08,// USAGE_PAGE (LEDs)
0x19, 0x01,// USAGE_MINIMUM (Num Lock)
0x29, 0x05,// USAGE_MAXIMUM (Kana)
0x91, 0x02,// OUTPUT (Data,Var,Abs)
0x95, 0x01,// REPORT_COUNT (1)
0x75, 0x03,// REPORT_SIZE (3)
0x91, 0x03,// OUTPUT (Cnst,Var,Abs)
0x95, 0x06,// REPORT_COUNT (6)
0x75, 0x08,// REPORT_SIZE (8)
0x15, 0x00,// LOGICAL_MINIMUM (0)
0x25, 0xFF,// LOGICAL_MAXIMUM (255)
0x05, 0x07,// USAGE_PAGE (Keyboard)
0x19, 0x00,// USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65,// USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00,// INPUT (Data,Ary,Abs)
0xc0</code></pre>
<pre><code>//标准键盘各个按键的宏定义如下
#define KEY_NULL 0x00
#define KEY_A 0x04 //A
#define KEY_B 0x05 //B
#define KEY_C 0x06 //C
#define KEY_D 0x07 //D
#define KEY_E 0x08 //E
#define KEY_F 0x09 //F
#define KEY_G 0x0A //G
#define KEY_H 0x0B //H
#define KEY_I 0x0C //I
#define KEY_J 0x0D //J
#define KEY_K 0x0E //K
#define KEY_L 0x0F //L
#define KEY_M 0x10 //M
#define KEY_N 0x11 //N
#define KEY_O 0x12 //O
#define KEY_P 0x13 //P
#define KEY_Q 0x14 //Q
#define KEY_R 0x15 //R
#define KEY_S 0x16 //S
#define KEY_T 0x17 //T
#define KEY_U 0x18 //U
#define KEY_V 0x19 //V
#define KEY_W 0x1A //W
#define KEY_X 0x1B //X
#define KEY_Y 0x1C //Y
#define KEY_Z 0x1D //Z
#define KEY_1 0x1E //1 !
#define KEY_2 0x1F //2 @
#define KEY_3 0x20 //3
#define KEY_4 0x21 //4
#define KEY_5 0x22 //5
#define KEY_6 0x23 //6
#define KEY_7 0x24 //7
#define KEY_8 0x25 //8
#define KEY_9 0x26 //9
#define KEY_0 0x27 //0
#define KEY_ENTER 0x28
#define KEY_ESC 0x29
#define KEY_BACKSPACE 0x2A
#define KEY_TAB 0x2B
#define KEY_SPACE 0x2C
#define KEY_SUB 0x2D // - and _
#define KEY_EQUAL 0x2E // = and +
#define KEY_LEFT_BRACKET 0x2F // [ and {
#define KEY_RIGHT_BRACKET 0x30 // ] and }
#define KEY_VERTICAL_LINE 0x31 // "\" and |
#define KEY_WAVE 0x32 // ` and ~
#define KEY_SEMICOLON 0x33 // ; and :
#define KEY_QUOTE 0x34 // ' and "
#define KEY_THROW 0x35 // ~ and `
#define KEY_COMMA 0x36 // , and <
#define KEY_DOT 0x37 // . and >
#define KEY_QUESTION 0x38 // / and ?
#define KEY_CAPS_LOCK 0x39
#define KEY_F1 0x3A
#define KEY_F2 0x3B
#define KEY_F3 0x3C
#define KEY_F4 0x3D
#define KEY_F5 0x3E
#define KEY_F6 0x3F
#define KEY_F7 0x40
#define KEY_F8 0x41
#define KEY_F9 0x42
#define KEY_F10 0x43
#define KEY_F11 0x44
#define KEY_F12 0x45
#define KEY_PRT_SCR 0x46
#define KEY_SCOLL_LOCK 0x47
#define KEY_PAUSE 0x48
#define KEY_INS 0x49
#define KEY_HOME 0x4A
#define KEY_PAGEUP 0x4B
#define KEY_DEL 0x4C
#define KEY_END 0x4D
#define KEY_PAGEDOWN 0x4E
#define KEY_RIGHT_ARROW 0x4F
#define KEY_LEFT_ARROW 0x50
#define KEY_DOWN_ARROW 0x51
#define KEY_UP_ARROW 0x52
#define KEY_PAD_NUMLOCK 0x53
#define KEY_PAD_DIV 0x54 // /
#define KEY_PAD_MUL 0x55 // *
#define KEY_PAD_SUB 0x56 // -
#define KEY_PAD_ADD 0x57 // +
#define KEY_PAD_ENTER 0x58
#define KEY_PAD_1 0x59
#define KEY_PAD_2 0x5A
#define KEY_PAD_3 0x5B
#define KEY_PAD_4 0x5C
#define KEY_PAD_5 0x5D
#define KEY_PAD_6 0x5E
#define KEY_PAD_7 0x5F
#define KEY_PAD_8 0x60
#define KEY_PAD_9 0x61
#define KEY_PAD_0 0x62
#define KEY_PAD_DOT 0x63
#define KEY_PRESSED 0x00
#define KEY_RELEASED 0x01 //控制
#define KEY_LCTRL 0x01 //左 ctrl 0x01
#define KEY_LALT 0x04 //左Alt 0x04
#define KEY_LSHFIT 0x02 //左Shift 0x02
#define KEY_LWIN 0x08 //左windows 0x08
#define KEY_RWIN 0x80 //右windows 0x80
#define KEY_RSHIFT 0x20 //右Shift 0x20
#define KEY_RALT 0x40 //右Alt 0x40
#define KEY_RCTRL 0x10 //右Ctrl 0x10</code></pre>
<pre><code>
//覆写HAL_UART_RxCpltCallback()方法,实现串口数据收发
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
RxBuff[Rx_Count++]=RxByte;
//实现接收转发送,测试用
if(RxByte==0x0A)
{
//while(HAL_UART_Transmit_IT(&huart2,RxBuff,Rx_Count)==HAL_OK);
uint8_t i=0;
int n=0;
for(;i</code></pre>
评论(1)