达者为先 师者之意
LD3320语音识别模块开发
1 LD3320语音识别模块基本参数
1.1 基本参数
下面介绍该模块的各种参数。
- 型号:YS-LDV7
- 名称:一体化语音识别模块
- 规格:43*29.7MM
- 供电电压:5V (内部工作电压 3.3V)
- 待机电流:30MA 识别时电流:45MA
- IO 口输出:高电平为 3.3V
- 通信方式:串口通信(5V TTL 电平,不可直接接 RS232、RS485)
- 单片机参数:型号–>STC11L08XE 、flash–>8k、SRAM–>1280、eeprom–>32k
- 识别词条个数:50 句
- 工作温度:-20 至 60℃
- 本模块实际原理为 1 片 STC11 单片机+1 片 LD3320 组合形成的一款语音 识别模块,语音识别部分已写好驱动程序,用于只需要对 STC 单片机进行编 程加入自己的识别语句和控制程序即可,语音识别部分无需理会和做编程处理。
LD3320是非特定人(不用针对指定人)语音识别芯片,即语音声控芯片。最多可以识别50条预先内置的指令。
工作模式:LD3320(LDV7)语音模块可以工作在以下三种模式:(推荐使用口令模式,这样避免嘈杂环境下误动作。)
- 普通模式:直接说话,模块直接识别;
- 按键模式:按键触发开始ASR进程;
- 口令模式:需要一级唤醒词(口令);
实物连接图
1.2 识别原理
就是你说一句话,然后模块用拼音去和你的发音做比较,在关键词中找出哪些预设值的词语与发音的接近程度大于多少的(假定50%),然后再从一堆大于(50%)里面输出一个最接近的。
这里就会造成一个问题,容易造成误识别太多。如果你只有一个关键词:“时间”,然后你说了一句:“时刻”,他识别到时这个发音,所以有50%以上的相似,但是候选词中没有时刻这个比他更接近的关键词,所以他就会输出“时间”的结果。这样子他就是错误了。如果你设置一些拟声词,有可能随随便便就触发了。
1.3 解决方案:
在设定好要识别的关键词语后,为了进一步降低误识别率,可以再添加一些其他的任意词汇进识别列表,用来吸收错误识别,从而达到降低误识别率的目的。我们把这样一些关键词语称之为“垃圾关键词语”。比如,某个应用场景中,需要识别的关键词语是4条,“前进”,“后退”,“开门”,“关门”。在把这4个关键词语设置进LD3320后,可以再另外设置10~30个词语进LD3320,比如“前门”,“后门”,“阿阿阿”,“呜呜”等等。所以最好把一些拟声词或者容易混淆的词语设置为垃圾关键词,即,识别后不进行输出。只有识别结果是4个关键词语之内的,才认为识别有效。如果识别结果是“垃圾关键词语”,则说明是其他的声音导致的误识别,产品应该重新开始一次识别过程。这样,可以非常有效地降低误识别率。极大地提高终端用户的主观使用体验。
2 LD3320语音识别模块二次开发
2.1 源码修改
打开 keil4 APP
文件夹
然后点击 YS-V0.7.uvproj
快速打开所有源码:
LD3320语音识别模块二次开发
只需对 LDChip.c
、LDChip.h
、 main.c
这三个文件做出修改即可。
2.1.1 LDChip.c
:修改关键词和识别码(此处省略部分代码)
uint8 LD_AsrAddFixed()
{
#define DATE_A 50 /*数组二维数值*/ //关键词数量(可修改),建议不超过 50个
#define DATE_B 70 /*数组一维数值*/ //关键词最长的长度(可修改),建议不长于 70
uint8 code sRecog[DATE_A][DATE_B] = {
"xiao jie",\
"kai fa ban yan zheng",\
"dai ma ce shi",\
"kai deng",\
"guan deng",\
"bei jing",\
"shang hai",\
"guang zhou"
}; /*添加关键词,用户修改*/
uint8 code pCode[DATE_A] = {
CODE_CMD,\
CODE_KFBYZ,\
CODE_DMCS,\
CODE_KD,\
CODE_GD,\
CODE_BJ,\
CODE_SH,\
CODE_GZ
}; /*添加识别码,用户修改*/
添加内容为拼音输入方式,例如想添加“开灯”命令,则写入“kai deng”
,每个汉字间的拼音用空格隔开;
所添加的识别码为预先定义好的宏定义常量值,同时必须和关键词一一对应,如上图所示,“da ma ce shi”
命令对应的识别码为CODE_DMCS
。
2.1.2 LDChip.h
:根据关键词修改相应识别码(此处省略部分代码)
//识别码客户修改处
#define CODE_CMD 0x00 //该命令码0x00用户不可进行修改。
#define CODE_DMCS 0x01 //代码测试
#define CODE_KFBYZ 0x02 //开发板验证
#define CODE_KD 0x04 //开灯
#define CODE_GD 0x05 //关灯
#define CODE_BJ 0x16 //关灯
#define CODE_SH 0x17 //上海
#define CODE_GZ 0x2f //广州
此处即为识别码的添加和修改,可以根据自己的需要和喜好任意定义识别码和宏名,但必须和前面所使用的识别码配对,否则会提示未定义错误。识别码的参数范围为 01-FF
随意选择,没有具体意义,只要不存在重复的即可。
2.1.3 main.c
:(此处省略部分代码)
TEST
测试命令
/****条件编译定义*******/
#define TEST //测试命令
#ifdef TEST
PrintCom("一级口令:小杰\r\n"); /*text.....*/
PrintCom("二级口令:1、代码测试\r\n"); /*text.....*/
PrintCom(" 2、开发板验证\r\n"); /*text.....*/
PrintCom(" 3、开灯\r\n"); /*text.....*/
PrintCom(" 4、关灯\r\n"); /*text.....*/
PrintCom(" 5、北京\r\n"); /*text.....*/
PrintCom(" 6、上海\r\n"); /*text.....*/
PrintCom(" 7、广州\r\n"); /*text.....*/
#endif
TEST
为测试命令宏,添加TEST
则运行其中代码,此处代码为向串口打印相应数据,不希望执行测试命令,可以把内容去掉
修改处理函数(此处省略部分代码)
switch(dat) /*对结果执行相关操作,客户可删除Printcom 串口输出语句替换为其他需要控制的代码*/
{
case CODE_DMCS: /*命令“测试”*/
PrintCom("“代码测试”命令识别成功\r\n"); /*text.....*/
break;
case CODE_KFBYZ: /*命令“全开”*/
PrintCom("“开发板验证”命令识别成功\r\n"); /*text.....*/
break;
case CODE_KD: /*命令“复位”*/
PrintCom("“开灯”命令识别成功\r\n"); /*text.....*/
break;
case CODE_GD: /*命令“复位”*/
PrintCom("“关灯”命令识别成功\r\n"); /*text.....*/
break;
case CODE_BJ: /*命令“复位”*/
PrintCom("“北京”命令识别成功\r\n"); /*text.....*/
break;
case CODE_SH: /*命令“复位”*/
PrintCom("“上海”命令识别成功\r\n"); /*text.....*/
break;
case CODE_GZ: /*命令“复位”*/
PrintCom("“广州”命令识别成功\r\n"); /*text.....*/
break;
default:PrintCom("请重新识别发口令\r\n"); /*text.....*/break;
}
用户可以根据自己的使用情况在相对应的识别码后添加识别成功后的操作。那么在设备到某句话后就会执行相应的动作,实际上此段程序是判断识别到那个识别码然后执行相应的动作,属树莓派的程序应用处理部分。
2.2 模块调试
2.2.1 模块程序下载
本模块的程序下载实际为 STC 单片机的程序下载方法,首先我们需要安装 USB 转 TTL 驱动(如已安装无需再安装),然后接好 USB 转 TTL,打开 STC-ISP:
①选择单片机型号
②选择相应串口号
③打开程序文件 > 打开源程序 > 打开obj文件夹 > 选择后缀.hex文件
④注意勾选“复位脚用作I/O口”
,
⑤设置完毕后点击“下载/编程”,并冷启动
⑥冷启动完后,底部进度条会显示进度
2.2.2 模块调试
①打开串口助手
②接收缓冲区选择“文本模式”
③选择相应串口号
④波特率选择 9600
⑤打开串口
3 LD3320语音识别所有文件代码
3.1 main.c
:
/***************************飞音云电子****************************
** 工程名称:YS-V0.7语音识别模块驱动程序
** CPU: STC11L08XE
** 晶振:22.1184MHZ
** 波特率:9600 bit/S
** 配套产品信息:YS-V0.7语音识别开发板
** http://yuesheng001.taobao.com
** 作者:zdings
** 联系:751956552@qq.com
** 修改日期:2013.9.13
** 说明:口令模式: 即每次识别时都需要说“小杰”这个口令 ,才能够进行下一级的识别
/***************************飞音云电子******************************/
#include "config.h"
/************************************************************************************/
// nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
// LD_ASR_NONE: 表示没有在作ASR识别
// LD_ASR_RUNING: 表示LD3320正在作ASR识别中
// LD_ASR_FOUNDOK: 表示一次识别流程结束后,有一个识别结果
// LD_ASR_FOUNDZERO: 表示一次识别流程结束后,没有识别结果
// LD_ASR_ERROR: 表示一次识别流程中LD3320芯片内部出现不正确的状态
/***********************************************************************************/
uint8 idata nAsrStatus=0;
void MCU_init();
void ProcessInt0(); //识别处理函数
void delay(unsigned long uldata);
void User_handle(uint8 dat);//用户执行操作函数
void Delay200ms();
void Led_test(void);//单片机工作指示
uint8_t G0_flag=DISABLE;//运行标志,ENABLE:运行。DISABLE:禁止运行
sbit LED=P4^2;//信号指示灯
/***********************************************************
* 名 称: void main(void)
* 功 能: 主函数 程序入口
* 入口参数:
* 出口参数:
* 说 明:
* 调用方法:
**********************************************************/
void main(void)
{
uint8 idata nAsrRes;
uint8 i=0;
Led_test();
MCU_init();
LD_Reset();
UartIni(); /*串口初始化*/
nAsrStatus = LD_ASR_NONE; // 初始状态:没有在作ASR
#ifdef TEST
PrintCom("一级口令:小杰\r\n"); /*text.....*/
PrintCom("二级口令:1、代码测试\r\n"); /*text.....*/
PrintCom(" 2、开发板验证\r\n"); /*text.....*/
PrintCom(" 3、开灯\r\n"); /*text.....*/
PrintCom(" 4、关灯\r\n"); /*text.....*/
PrintCom(" 5、北京\r\n"); /*text.....*/
PrintCom(" 6、上海\r\n"); /*text.....*/
PrintCom(" 7、广州\r\n"); /*text.....*/
#endif
while(1)
{
switch(nAsrStatus)
{
case LD_ASR_RUNING:
case LD_ASR_ERROR:
break;
case LD_ASR_NONE:
{
nAsrStatus=LD_ASR_RUNING;
if (RunASR()==0) /* 启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算*/
{
nAsrStatus = LD_ASR_ERROR;
}
break;
}
case LD_ASR_FOUNDOK: /* 一次ASR识别流程结束,去取ASR识别结果*/
{
nAsrRes = LD_GetResult(); /*获取结果*/
User_handle(nAsrRes);//用户执行函数
nAsrStatus = LD_ASR_NONE;
break;
}
case LD_ASR_FOUNDZERO:
default:
{
nAsrStatus = LD_ASR_NONE;
break;
}
}// switch
}// while
}
/***********************************************************
* 名 称: LED灯测试
* 功 能: 单片机是否工作指示
* 入口参数: 无
* 出口参数:无
* 说 明:
**********************************************************/
void Led_test(void)
{
LED=~ LED;
Delay200ms();
LED=~ LED;
Delay200ms();
LED=~ LED;
Delay200ms()