当前位置:文档之家› 用单片机实现语音控制机器人

用单片机实现语音控制机器人

用单片机实现语音控制机器人制作人:潘磊pb02023035卢恒pb02006088题目:用凌阳单片机实现语音识别功能并传递给PIC单片机信号,由PIC单片机控制机器人实现动作关键字:PIC单片机,凌阳单片机,语音控制单片机在现今生活中占有越来越重要的地位,用语音控制单片机实现控制更具有广泛的应用价值。

用语音控制舞蹈机器人做一些动作是我们这次实现的功能,虽然这在语音控制方面仍处于起步阶段,但他体现了语音控制的原理和基本实现,也为更高级的运用打下了基础。

原理:1.语音识别原理语音识别电路基本结构如上图所示:语音识别分为特定发音人识别(Speaker Dependent)和非特定发音人识别(Speaker Independent)两种方式。

特定发音人识别是指语音样板由单个人训练,对训练人的语音命令识别准确率较高,而其他人的语音命令识别准确率较低或不识别。

非特定发音人识别:是指语音样板由不同年龄、不同性别、不同口音的人进行训练,可以识别一群人的命令。

语音样板的提取非常重要。

我们将标准模式的存储空间称之为“词库”,而把标准模式称之为“词条”或“样板”。

所谓建立词库,就是将待识别的命令进行频谱分析,提取特征参数作为识别的标准模式。

识别过程首先要滤除输入语音信号的噪音和进行预加重处理,提升高频分量,然后用线性预测系数等方法进行频谱分析,找出语音的特征参数作为未知模式,接着与预先存储的标准模式进行比较,当输入的未知模式与标准模式的特征相一致时,便被机器识别,产生识别结果输出。

如果输入的语音与标准模式的特征完全一致固然好,但是语音含有不确定因素,完全一致的条件往往不存在,事实上没有人能以绝对相同的语调把一个词说两遍,因此,预先制定好计算输入语音的特征模式与各特征模式的类似程度,或距离度的算法规则固化在ROM中,把该距离最小,即最类似的模式作为识别相应语音的手段。

当然,影响识别率的因素还有一些,如连续发音(如英语)与断续发音(如汉语)的不同(二者区别在于单词间隔有200ms 以上的空隙时间)。

本程序采用特定人识别方式,将训练的标准样板存于内部RAM中(掉电丢失),每次上电复位后都要进行训练,2.硬件电路硬件电路比较简单,MIC选用驻极体电容话筒,这种话筒具有灵敏度高、无方向性、重量轻、体积小、频率响应宽、保真度好等优点,驻极体话筒的偏压由SPCE061A的VMIC管脚提供。

其硬件电路如下图所示。

SPCE061A的A/D转换器有8个通道,其中有1个通道是MIC-IN输入,它专门用于对语音信号进行采样。

语音信号经MIC转换成电信号,由隔直电容隔掉直流成分,然后输入至SPCE061A内部前置放大器。

SPCE061A内部自动增益控制电路AGC能随时跟踪、监视前置放大器输出的音频信号电平,当输入信号增大时,AGC电路自动减小放大器的增益;当输入信号减小时,AGC电路自动增大放大器的增益,可使进入A/D的信号保持在最佳电平,又可使削波减至最小,A/D转换器对输入的音频信号进行8kHz采样,并按照凌阳音频编码格式进行编码,每秒将占用16kBits的存储器空间。

2.机器人的控制。

我们控制的机器人是“小强”,他总共有三个电机需要控制。

行走由一个直流电机控制,手部有两个步进电机控制。

对每一个电机规定固定的端口,由PIC控制电机驱动电路H桥的使能端从而实现各种动作的控制。

在这里,PIC单片机时刻监视凌阳单片机的信号位,不同的电平组合进行不同的动作,实现语音控制。

程序设计1.语音识别程序。

程序包括三部分:训练样本、识别和语音提示。

由于语音样本是存在内部RAM中,掉电将丢失,所以在每次上电复位时都必须重新训练,训练过程主要是靠调用库函数 BSR_Train 来完成,为了防止误命令,每条语音命令训练2遍,只有2次命令相同时才成功,BSR_Train函数有8种可能的返回值:0------训练成功;-1------没有检测到命令;-2------需要再训练一次,每条命令训练2次,第一次训练成功则返回-2;-3------环境太吵;-4------存储器满;-5------两次命令不一样;-6------命令序号超出范围;-7------命令已存在;训练成功则训练下一条,否则继续训练。

语音识别程序包括识别程序和中断服务程序。

识别程序完成选取词库、初始化A/D 和定时器TimerA、识别运算及识别结果处理,整个流程图如图。

中断服务程序定时读取A/D转换结果,并存入缓冲区,A/D的输入为MIC通道的语音信号。

语音识别和放音分时复用TimerA FIQ 中断,由标志位判断是语音识别处理还是放音处理。

中断服务程序的流程图如图所示。

识别程序如下://================================================================================== ======// 工程名称: Guard_SD.spj// 功能描述: 语音识别DEMO程// 每次上电复位后请训练3条命令,第一条为触发命令// 后两条为控制命令,//// 涉及的库:CMacro.lib//// 组成文件: main.c// FIQ.asm/hardware.asm/InitIO.asm// hardware.inc/hardware.h//================================================================================== =========#include "bsrsd.h"#define NAME_ID 0x100#define COMMAND_ONE_ID 0x101#define COMMAND_TWO_ID 0x102#define RSP_INTRO 0 //0. I am your body guard.#define RSP_NAME 1 //1. Please give me your name.#define RSP_FIRE 2 //2. Say Fire.#define RSP_GUARD 3 //3. Say Guard.#define RSP_AGAIN 4 //4. Say again.#define RSP_NOVOICE 5 //5. No voice detected.#define RSP_NAMEDIFF 6 //6. Two given names are different. #define RSP_HERE 7 //10. I'm here#define RSP_STANDBY 8 //8. Iam standing by.#define RSP_GUNSHOT 9 //11. Gun sound.#define RSP_READY 10 //13. I'm ready!int gActivated = 0;//..................global variables.....................//1---触发命令识别成功//0---无触发命令//*************** 播放提示语音 ***********************////input:播放序号//output:NO//*****************************************************//void PlayRespond(int Result){BSR_StopRecognizer(); //关闭识别器SACM_A2000_Initial(1); //初始化播放器SACM_A2000_Play(Result, 3, 3); //播放提示语音while((SACM_A2000_Status()&0x0001) != 0){SACM_A2000_ServiceLoop();}SACM_A2000_Stop(); //停止播放BSR_InitRecognizer(BSR_MIC); //初始化识别器// BSR_EnableCPUIndicator();}//*************** 训练命令函数 ***********************////input:命令序号、提示语序号//output:0----训练成功 -1------训练失败//*****************************************************//int TrainWord(int WordID, int RespondID){int res;PlayRespond(RespondID);while(1){res = BSR_Train(WordID,BSR_TRAIN_TWICE);if(res == 0) //训练成功break;switch(res){case -1: //没有检测到命令PlayRespond(RSP_NOVOICE);return -1;case -2: //需要再训练一次PlayRespond(RSP_AGAIN);break;case -3: //环境太吵return -1;case -4: //存储器满return -1;case -5: //两次命令不一样PlayRespond(RSP_NAMEDIFF);return -1;case -6: //命令序号超出范围return -1;case -7: //命令已存在return -1;}}return 0;}//*************** 主程序 *********************************************** //************************************************//int main(){int res, timeCnt=0;InitIO();BSR_DeleteSDGroup(0);//初始化存储器,选用SPCE061A内部RAM存储语音样本 PlayRespond(RSP_INTRO);while(TrainWord(NAME_ID,1) != 0) ; //训练用户名while(TrainWord(COMMAND_ONE_ID,2) != 0) ; //训练第一条命令while(TrainWord(COMMAND_TWO_ID,3) != 0) ; //训练第二条命令BSR_InitRecognizer(BSR_MIC); //初始化识别器//BSR_EnableCPUIndicator();PlayRespond(RSP_STANDBY); //播放提示语?I'm standing by.while(1){res = BSR_GetResult(); //进行识别,获取识别结果if(res > 0) //识别成功{if(gActivated) //如果已经触发{timeCnt = 0;switch(res){case NAME_ID: //用户名PlayRespond(RSP_HERE);break;case COMMAND_ONE_ID: //第一条命令PlayRespond(RSP_GUNSHOT);gActivated = 0;break;case COMMAND_TWO_ID: //第二条命令PlayRespond(RSP_READY);gActivated = 0;}}else //没有触发{if(res == NAME_ID){PlayRespond(RSP_HERE);gActivated = 1;timeCnt = 0;}}}else if (gActivated){if (++timeCnt > 450) //如果已经触发,但没有命令识别出来{PlayRespond(RSP_NOVOICE);gActivated = 0;timeCnt = 0;}}}}中断服务程序如下://===================================================//文件名称:FIQ.asm//功能描述:中断放音//======================================================.PUBLIC _FIQ//................................................EXTERNAL _BSR_FIQ_Routine.EXTERNAL __gIsStopRecog //This variable = 0 if recognizer is busy,// = 1 if recognizer is stopped,// = 2 if recognizer is paused..PUBLIC _BREAK,_IRQ0, _IRQ1, _IRQ2, _IRQ3, _IRQ4, _IRQ5, _IRQ6, _IRQ7//...................................................INCLUDE A2000.inc;.INCLUDE hardware.inc.DEFINE P_WatchDog_Clear 0x7012.TEXT_FIQ:PUSH R1,R4 TO [SP] //寄存器入栈R1 = [P_INT_Ctrl] //读中断标志位R1 &= 0x2000JZ FIQ_ret //不是TimerA FIQ中断R1 = [__gIsStopRecog]JNZ TimerA_is_S480TimerA_is_Recognize: //TimerA FIQ为语音识别服务call _BSR_FIQ_Routine //语音识别服务函数JMP FIQ_retTimerA_is_S480: //TimerA FIQ为放音服务CALL F_FIQ_Service_SACM_S480; //放音服务函数FIQ_ret:R1 = 0xa800;[P_INT_Clear] = R1; //清中断标志POP R1,R4 FROM [SP]; //寄存器出栈reti;_BREAK:_IRQ0:_IRQ1:_IRQ2:_IRQ3:_IRQ4:_IRQ5:_IRQ6:_IRQ7:.END2.机器人控制程序。

相关主题