达者为先师者之意
LD开发3320语音识别模块
- 1 LD3320语音识别模块基本参数
-
- 1.1 基本参数
- 1.2 识别原理
- 1.3 解决方案:
- 2 LD3320语音识别模块二次开发
-
- 2.1 源码修改
-
- 2.1.1 `LDChip.c`:修改关键字和识别码(此处省略部分代码)
- 2.1.2 `LDChip.h`:根据关键字修改相应的识别码(此处省略部分代码)
- 2.1.3 `main.c`:(此处省略部分代码)
- 2.2 模块调试
-
- 2.2.1 下载模块程序
- 2.2.2 模块调试
- 3 LD3320语音识别所有文件代码
-
- 3.1 `main.c`:
- 3.2 `LDChip.c`:
- 3.3 `LDChip.h`:
- 3.4 `Reg_RW.c`:
- 3.5 `Reg_RW.h`:
- 3.6 `config.h`:
- 3.7 `STC11XX.h`:
1 LD3320语音识别模块基本参数
1.1 基本参数
以下是该模块的各种参数。
- 型号:YS-LDV7
- 名称:集成语音识别模块
- 规格:43*29.7MM
- 供电电压:5V (内部工作电压 3.3V)
- 待机电流:30MA 电流:45MA
- IO 口输出:高电平为 3.3V
- 通信方式:串口通信(5)V 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 解决方案:
在设置要识别的关键词后,为了进一步降低误识别率,可以在识别列表中添加一些其他单词,以吸收误识别,从而降低误识别率。我们称这些关键词为垃圾关键词。比如在某个应用场景中,需要识别的关键词有四个,前进、后退、开门、关门。设置这四个关键词LD3320后,可再设置10~30个单词LD3320,如前门、后门、阿阿阿、呜呜等。因此,最好将一些拟声词或容易混淆的词设置为垃圾关键词,即识别后不输出。只有在四个关键词中,识别结果才能被认为是有效的。如果识别结果是垃圾关键词,则表明是由其他声音引起的误识别,产品应重新开始识别过程。这样可以有效降低误识别率。大大提高终端用户的主观使用体验。
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"span class="token punctuation">,\
"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(); LED=~ LED; Delay200ms(); LED=~ LED; Delay200ms(); LED=~ LED; } /*********************************************************** * 名 称: void MCU_init() * 功 能: 单片机初始化 * 入口参数: * 出口参数: * 说 明: * 调用方法: **********************************************************/ void MCU_init() { P0 = 0xff; P1 = 0xff; P2 = 0xff; P3 = 0xff; P4 = 0xff; LD_MODE = 0; // 设置MD管脚为低,并行模式读写 IE0=1; EX0=1; EA=1; } /*********************************************************** * 名 称: 延时函数 * 功 能: * 入口参数: * 出口参数: * 说 明: * 调用方法: **********************************************************/ void Delay200us() //@22.1184MHz { unsigned char i, j; _nop_(); _nop_(); i = 5; j = 73; do { while (--j); } while (--i); } void delay(unsigned long uldata) { unsigned int j = 0; unsigned int g = 0; while(uldata--) Delay200us(); } void Delay200ms() //@22.1184MHz { unsigned char i, j, k; i = 17; j = 208; k = 27; do { do { while (--k); } while (--j); } while (--i); } /*********************************************************** * 名 称: 中断处理函数 * 功 能: * 入口参数: * 出口参数: * 说 明: * 调用方法: **********************************************************/ void ExtInt0Handler(void) interrupt 0 { ProcessInt0(); } /*********************************************************** * 名 称:用户执行函数 * 功 能:识别成功后,执行动作可在此进行修改 * 入口参数: 无 * 出口参数:无 * 说 明: **********************************************************/ void User_handle(uint8 dat) { //UARTSendByte(dat);//串口识别码(十六进制) if(0==dat) { G0_flag=ENABLE; LED=0; PrintCom("收到\r\n"); /*text.....*/ } else if(ENABLE==G0_flag) { G0_flag=DISABLE; LED=1; 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; } } else { PrintCom("请说出一级口令\r\n"); /*text.....*/ } }
3.2 LDChip.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" extern void delay(unsigned long uldata); uint8 idata ucRegVal; extern uint8 idata nAsrStatus; void ProcessInt0(void); /************************************************************************ 功能描述: 复位LD模块 入口参数: none 返 回 值: none 其他说明: none **************************************************************************/ void LD_Reset() { RSTB=1; delay(5); RSTB=0; delay(5); RSTB=1; delay(5); CSB=0; delay(5); CSB=1; delay(5); } /************************************************************************ 功能描述: LD模块命令初始化 入口参数: none 返 回 值: none 其他说明: 该函数为出厂配置,一般不需要修改; 有兴趣的客户可对照开发手册根据需要自行修改。 **************************************************************************/ void LD_Init_Common() { LD_ReadReg(0x06); LD_WriteReg(0x17, 0x35); delay(10); LD_ReadReg(0x06); LD_WriteReg(0x89, 0x03); delay(5); LD_WriteReg(0xCF, 0x43); delay(5); LD_WriteReg(0xCB, 0x02); /*PLL setting*/ LD_WriteReg(0x11, LD_PLL_11); LD_WriteReg(0x1E,0x00); LD_WriteReg(0x19, LD_PLL_ASR_19); LD_WriteReg(0x1B, LD_PLL_ASR_1B); LD_WriteReg(0x1D, LD_PLL_ASR_1D); delay(10); LD_WriteReg(0xCD, 0x04); // LD_WriteReg(0x17, 0x4c); delay(5); LD_WriteReg(0xB9, 0x00); LD_WriteReg(0xCF, 0x4F); LD_WriteReg(0x6F, 0xFF); } /************************************************************************ 功能描述: LD模块 ASR功能初始化 入口参数: none 返 回 值: none 其他说明: 该函数为出厂配置,一般不需要修改; 有兴趣的客户可对照开发手册根据需要自行修改。 **************************************************************************/ void LD_Init_ASR() { LD_Init_Common(); LD_WriteReg(0xBD, 0x00); LD_WriteReg(0x17, 0x48); delay( 10 ); LD_WriteReg(0x3C, 0x80); LD_WriteReg(0x3E, 0x07); LD_WriteReg(0x38, 0xff); LD_WriteReg(0x3A, 0x07); LD_WriteReg(0x40, 0); LD_WriteReg(0x42, 8); LD_WriteReg(0x44, 0); LD_WriteReg(0x46, 8); delay( 1 ); } /************************************************************************ 功能描述: 中断处理函数 入口参数: none 返 回 值: none 其他说明: 当LD模块接收到音频信号时,将进入该函数, 判断识别是否有结果,如果没有从新配置寄 存器准备下一次的识别。 **************************************************************************/ void ProcessInt0(void) { uint8 nAsrResCount=0; EX0=0; ucRegVal = LD_ReadReg(0x2B); LD_WriteReg(0x29,0) ; LD_WriteReg(0x02,