当前位置:文档之家› 基于单片机技术的语音控制小车设计

基于单片机技术的语音控制小车设计

基于单片机技术的语音控制小车设计基于单片机技术的语音控制小车设计1基于单片机技术的语音控制小车设计1、引言语音处理技术是一门新兴的技术,它不仅包括语音的录制和播放,还涉及语音的压缩编码和解码,语音的识别等各种处理技术。

以往做这方面的设计,一般有两个途径:一种方案是单片机扩展设计,另一种就是借助于专门的语音处理芯片。

普通的单片机往往不能实现这么复杂的过程和算法,即使勉强实现也要加很多的外围器件。

专门的语音处理芯片也比较多,如ISD 系列、PM50 系列等,但是专门的语音处理芯片功能比较单一,想在语音之外的其他方面应用基本是不可能的。

SPCE061A 是一款 16 位μ'nSP结构的微控制器。

该芯片带有硬件乘法器,能够实现乘法运算、内积运算等复杂的运算。

它不仅运算能力强,而且处理速度快,单周期最高可以达到 49MHz。

SPCE061A 内嵌 32K 字的 FLASH 程序存储器以及 2K 的SRAM。

同时该 SOC 芯片具有 ADC 和 DAC 功能,其 MIC_ADC 通道带有AGC自动增益环节,能够很轻松的将语音信号采集到芯片内部,两路 10 位的电流输出型DAC,只要外接一个功放就可以完成声音的播放。

以上介绍的这些硬件资源使得该SPCE061A 能够单芯片实现语音处理功能。

借助于 SPCE061A 的语音特色,“基于单片机技术的语音控制小车设计”实现了对小车前进、后退、左转、右转、停车等语音控制功能.2、语音控制小车设计要求2.1 功能要求:1.可以通过简单的 I/O 操作实现小车的前进、后退、左转、右转功能;2.配合 SPCE061A 的语音特色,利用系统的语音播放和语音识别资源,实现语音控制的功能;3.可以在行走过程中声控改变小车运动状态;4.在超出语音控制范围时能够自动停车。

2.2 参数说明车体:双电机两轮驱动供电:电池(四节AA:1.2V×4 或 1.5V×4)工作电压:DC 4V~6V工作电流:运动时约 200mA3. SPCE061A特性简介SPCE061A是一款性价比很高的十六位单片机,使用它可以非常方便灵活的实现语音的录放,该芯片拥有8路10位精度的 ADC,其中一路为音频转换通道,并且内置有自动增益电路。

这为实现语音录入提供了方便的硬件条件。

两路10位精度的DAC,只需要外接功放(SPY0030A)即可完成语音的播放。

该单片机具有一套易学易用的指令系统和集成开发环境,在此环境中,它支持标准 C 语言编程,也支持C 语言与汇编语言的互相调用。

另外还提供了语音录放的库函数,只要了解库函数的使用,就可以很容易的完成语音的录放、识别等功能,这些都为软件开发提供了方便的条件。

SPCE061A特性:16位μ’nSP微处理器;工作电压:内核工作电压VDD为 3.0V~3.6V(CPU),I/O口工作电压VDDH为VDD~5.5V(I/O);CPU时钟:0.32MHz~49.152MHz;内置2K 字 SRAM;内置32K 闪存 ROM;2可编程音频处理;晶体振荡器;系统处于备用状态下(时钟处于停止状态),耗电小于2μA@3.6V;2 个 16 位可编程定时器/计数器(可自动预置初始计数值);2 个 10 位 DAC(数-模转换)输出通道;32 位通用可编程输入/输出端口;14 个中断源可来自定时器 A / B,时基,2 个外部时钟源输入,键唤醒;具备触键唤醒的功能;使用音频编码 SACM_S240 方式(2.4K 位/秒),能容纳 210 秒的语音数据;锁相环 PLL 振荡器提供系统时钟信号;32768Hz 实时时钟;7 通道 10 位电压模-数转换器(ADC)和单通道声音模-数转换器;声音模-数转换器输入通道内置麦克风放大器和自动增益控制(AGC)功能;具备串行设备接口;低电压复位(LVR)功和低电压监测(LVD)功能;内置在线仿真板(IC E,In-C ircuitEm ulator)接口。

4、系统总体方案介绍小车的运动控制采用语音控制和中断定时控制相结合,通过语音触发小车动作,小车动作之后,随时可以通过语音指令改变小车的运动状态。

在每一次动作触发的同时启动定时器,如果小车由于某些原因不能正常的接收语音指令,则只要定时时间一到,中断服务程序就会发出指令让小车停下来。

SPCE061A 被控对象控制板小车程序下控制程载电缆序下载线喇叭电池盒图1 控制系统所需硬件35、系统硬件设计系统的硬件方面,由于大部分的功能实现都是在61板上完成的,只有电机控制部分电路另外设计在一块独立的电路板上,我们称之为控制板。

下面详细的介绍小车的结构和运行原理以及控制电路板的结构和功能实现。

图2 系统硬件框图SPCE061 复位按钮 A芯片程序下载接口MIC输控制按钮入口图3 系统硬件组装效果图45.1 车体介绍语音控制小车为四轮结构。

其中前面两个车轮由前轮电机控制,在连杆和支点作用下控制前轮左右摆动,来调节小车的前进方向。

在自然状态下,前轮在弹簧作用下保持中间位置。

后面两个车轮由后轮电机驱动,为整个小车提供动力。

所以又称前面的轮子为方向轮,后面的两个轮子为驱动轮。

5.2 小车的行走原理.直走:由小车的结构分析,在自然状态下,前轮在弹簧作用下保持中间状态,这是只要后轮电机正转小车就会前进。

倒车:倒车动作和前进动作刚好相反,前轮电机仍然保持中间状态,后轮电机反转,小车就会向后运动。

图4 小车前进、后退示意图左转:前轮电机逆时针旋转(规定为正转),后轮电机正转,这时小车就会在前后轮共同作用下朝左侧前进。

右转:前轮电机反转,后轮电机正转,这时小车就是会在前后轮共同作用下朝右侧前进。

图5 小车转向示意图55.3 控制板原理图控制板主要包括:接口电路、电源电路和两路电机的驱动电路,控制板原理图如下。

接口电路:接口电路负责将61板的I/O接口信号传送给控制电路板,I/O信号主要为控制电机需要的IOB8~IOB11这四路信号,同时为了方便后续的开发和完善,预留了IOB12~IOB15 以及IOA8~IOA15接口,可以在这些接口上添加一些传感器。

电源部分:整个小车有4个电源信号:电池电源,控制板工作电源,61板工作电源,61板的I/O输出电源。

系统供电由电池提供,控制板直接采用电池供电(VCC),然后经二极管D1后产生61板电源SPCE061A 在语音控制小车中的应用(VCC_61),通过61板的Vio跳线产生61板的端口电源(V1)。

图6 小车控制电路图6、系统软件设计6.1 系统的主程序设计系统的主程序流程如下图所示:6图7 主程序流程图共分为四大部分:初始化部分、训练部分、识别部分、重训操作。

初始化部分:初始化操作将 IOB8~IOB11 设置为输出端,用以控制电机。

必要时还要有对应的输入端设置和 PWM 端口设置等。

训练部分:训练部分完成的工作就是建立语音模型。

程序一开始判断小车是否被训练过,如果没有训练过则要求对其进行训练,并且会在训练成功之后将训练的模型存储到 Flash,在以后使用时不需要重新训练;如果已经训练过会把存储在Flash 中的模型调出来装载到辨识器中。

识别部分:在识别环节当中,如果辨识结果是名字,停止当前的动作并进入待命状态,然后等待动作命令。

如果辨识结果为动作指令小车会语音告知相应动作并执行该动作,在运动过程中可以通过呼叫小车SPCE061A在语音控制小车中的应用的名字使小车停下来。

重训操作:考虑到有重新训练的需求,设置了重新训练的按键(61 板的KEY3),7循环扫描该按键,一旦检测到此键按下,则将擦除训练标志位(0xe000 单元),并等待复位。

复位后,程序重新执行,当检测到训练标志位为 0xffff 时会要求重新对其进行训练。

6.2主控制源程序://====================================================== // The information contained herein is the exclusive property of // Sunnnorth Technology Co. And shall not be distributed, reproduced, // or disclosed in whole in part without prior written permission. // (C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO. // ALL RIGHTS RESERVED // The entire notice above must be reproduced on all authorized copies.//========================================================//======================================================== // 工程名称: Car_Demo// 功能描述: 实现小车的语音控制// 涉及的库: CMacro1016.lib// bsrv222SDL.lib// sacmv26e.lib// 组成文件: main.c// Flash.asm, hardware.asm,ISR.asm// hardware.h,s480.h, hardware.inc// 硬件连接: IOA0-----KEY1// IOA1-----KEY2// IOA2-----KEY3// IOB8-----前进// IOB9-----倒车// IOB10----左拐// IOB11----右拐// 维护记录: 2005-12-12 v1.0//========================================================#include "s480.h"#include "bsrsd.h"#define P_IOA_Data (volatile unsigned int *)0x7000 #define P_IOA_Dir (volatile unsigned int *)0x7002 #define P_IOA_Attrib (volatile unsigned int *)0x7003 #define P_IOB_Data (volatile unsigned int *)0x7005 #define P_IOB_Dir (volatile unsigned int *)0x7007 #define P_IOB_Attrib (volatileunsigned int *)0x7008 #define P_TimerA_Data (volatile unsigned int *)0x700A #define P_TimerA_Ctrl (volatile unsigned int *)0x700B #define P_TimerB_Data (volatile unsigned int *)0x700C8#define P_TimerB_Ctrl (volatile unsigned int *)0x700D #defineP_Watchdog_Clear (volatile unsigned int *)0x7012 #define P_INT_Mask (volatile unsigned int *)0x702D #define P_INT_Clear (volatile unsigned int *)0x7011#define NAME_ID 0x100#define COMMAND_GO_ID 0x101#define COMMAND_BACK_ID 0x102#define COMMAND_LEFT_ID 0x103#define COMMAND_RIGHT_ID 0x104#define S_NAME 0 //给我取个名字吧#define S_ACT1 1 //前进#define S_ACT2 2 //倒车,请注意#define S_ACT3 3 //左拐#define S_ACT4 4 //右拐#define S_RDY 5 //Yeah#define S_AGAIN 6 //请再说一遍#define S_NOVOICE 7 //没有听到任何声音#define S_CMDDIFF 8 //说什么暗语呀#define S_NOISY 8 //说什么暗语呀#define S_START 9 //准备就绪,开始辨识#define S_GJG 10 //拐就拐#define S_DCZY 11 //倒车,请注意extern unsigned int BSR_SDModel[100]; //外部变量BSR_SDModel[100],辨识器自带extern void F_FlashWrite1Word(unsigned int addr,unsigned int Value);extern void F_FlashErase(unsigned int sector); unsigned intuiTimeset = 3; //运行时间定时,调整该参数控制运行时间unsigned int uiTimecont; //运行时间计时//=============================================================// 语法格式: void Delay();// 实现功能: 延时// 参数: 无// 返回值: 无//=============================================================void Delay(){unsigned int i;for(i=0;i<0x3Fff;i++){9*P_Watchdog_Clear=0x0001;}}//============================================================= // 语法格式: void PlaySnd(unsigned SndIndex,unsigned DAC_Channel);// 实现功能: 语音播放函数// 参数: SndIndex-播放语音资源索引号// DAC_Channel-播放声道选择// 返回值: 无//============================================================= void PlaySnd(unsigned SndIndex,unsigned DAC_Channel) {BSR_StopRecognizer(); //停止识别器SACM_S480_Initial(1); //初始化为自动播放SACM_S480_Play(SndIndex, DAC_Channel, 3); //开始播放一段语音while((SACM_S480_Status()&0x0001)!= 0) //是否播放完毕,{SACM_S480_ServiceLoop(); //解码并填充队列*P_Watchdog_Clear=0x0001; //清看门狗}SACM_S480_Stop(); //停止播放BSR_InitRecognizer(BSR_MIC); //初始化识别器}//============================================================= // 语法格式: int TrainWord(int WordID,int SndID); // 实现功能: 训练一条指令// 参数: WordID-指令编码// SndID-指令提示音索引号// 返回值: 无//============================================================= int TrainWord(unsigned int WordID,unsigned int SndID) {int Result;PlaySnd(SndID,3); //引导训练,播放指令对应动作while(1){Result = BSR_Train(WordID,BSR_TRAIN_TWICE); //训练两次,获得训练结果if(Result==0)break;switch(Result){10case -1: //没有检测出声音PlaySnd(S_NOVOICE,3);return -1;case -2: //需要训练第二次PlaySnd(S_AGAIN,3);break;case -3: //环境太吵PlaySnd(S_NOISY,3);return -3;case -4: //数据库满return -4;case -5: //检测出声音不同PlaySnd(S_CMDDIFF,3);return -5;case -6: //序号错误return -6;default:break;}}return 0;}//=============================================================// 语法格式: void TrainSD();// 实现功能: 训练函数// 参数: 无// 返回值: 无//============================================================= void TrainSD(){while(TrainWord(NAME_ID,S_NAME) != 0) ; //训练名称while(TrainWord(COMMAND_GO_ID,S_ACT1) != 0) ; //训练第1个动作while(TrainWord(COMMAND_BACK_ID,S_ACT2) != 0) ; //训练第2个动作while(TrainWord(COMMAND_LEFT_ID,S_ACT3) != 0) ; //训练第3个动作while(TrainWord(COMMAND_RIGHT_ID,S_ACT4) != 0) ; //训练第4个动作 }//============================================================= // 语法格式: void StoreSD();// 实现功能: 存储语音模型函数// 参数: 无// 返回值: 无//============================================================= 11void StoreSD() { unsigned int ulAddr,i,commandID,g_Ret;F_FlashWrite1Word(0xef00,0xaaaa);F_FlashErase(0xe000);F_FlashErase(0xe100);F_FlashErase(0xe200);ulAddr=0xe000;//********for(commandID=0x100;commandID<0x105;commandID++){g_Ret=BSR_ExportSDWord(commandID);while(g_Ret!=0) //模型导出成功,g_Ret=BSR_ExportSDWord(commandID);for(i=0;i<100;i++) //保存语音模型SD1(0xe000---0xe063){F_FlashWrite1Word(ulAddr,BSR_SDModel[i]);ulAddr+=1;}}}//============================================================= // 语法格式: void StoreSD();// 实现功能: 装载语音模型函数// 参数: 无// 返回值: 无//============================================================= void LoadSD() { unsigned int *p,k,jk,Ret,g_Ret;p=(int *)0xe000;for(jk=0;jk<5;jk++){for(k=0;k<100;k++){Ret=*p;BSR_SDModel[k]=Ret; //装载语音模型p+=1;}g_Ret=BSR_ImportSDWord();while(g_Ret!=0) //模型装载成功,g_Ret=BSR_ImportSDWord();}}12//============================================================= // 语法格式: void GoAhead();// 实现功能: 前进子函数// 参数: 无// 返回值: 无//============================================================= void GoAhead() //前进 {PlaySnd(S_ACT1,3); //提示*P_IOB_Data=0x0100; //前进*P_INT_Mask |= 0x0004; //以下为中断定时操作__asm("int fiq,irq");uiTimecont = 0;}//============================================================= // 语法格式: void BackUp();// 实现功能: 后退子函数// 参数: 无// 返回值: 无//============================================================= void BackUp() //倒退 {PlaySnd(S_DCZY,3); //提示*P_IOB_Data=0x0200; //倒退*P_INT_Mask |= 0x0004; //以下为中断定时操作__asm("int fiq,irq");uiTimecont = 0;}//============================================================= // 语法格式: void TurnLeft();// 实现功能: 左转子函数// 参数: 无// 返回值: 无//============================================================= void TurnLeft() //左转 {PlaySnd(S_GJG,3);*P_IOB_Data=0x0900; //右转Delay(); //延时*P_IOB_Data=0x0500; //左转*P_INT_Mask |= 0x0004; //以下为中断定时操作__asm("int fiq,irq");13uiTimecont = 0;}//============================================================= // 语法格式: void TurnRight(); // 实现功能: 右转子函数// 参数: 无// 返回值: 无//============================================================= void TurnRight() //右转 {PlaySnd(S_GJG,3); //语音提示*P_IOB_Data=0x0500; //左转Delay(); //延时*P_IOB_Data=0x0900; //右转*P_INT_Mask |= 0x0004; //以下为中断定时操作__asm("int fiq,irq");uiTimecont = 0;}//============================================================= // 语法格式: void Stop();// 实现功能: 停车子函数// 参数: 无// 返回值: 无//============================================================= void Stop() //停车 {*P_IOB_Data=0x0000; //停车PlaySnd(S_RDY,3); //语音提示 }//============================================================= // 语法格式: void BSR(void);// 实现功能: 辨识子函数// 参数: 无// 返回值: 无//============================================================= void BSR(void){int Result; //辨识结果寄存Result = BSR_GetResult(); //获得识别结果if(Result>0) //有语音触发,{14*P_IOB_Data=0x0000; //临时停车switch(Result){case NAME_ID: //识别出名称命令Stop(); //停车待命break;case COMMAND_GO_ID: //识别出第一条命令GoAhead(); //执行动作一:直走break;case COMMAND_BACK_ID: //识别出第二条命令BackUp(); //执行动作二:倒车break;case COMMAND_LEFT_ID: //识别出第三条命令TurnLeft(); //执行动作三:左转break;case COMMAND_RIGHT_ID: //识别出第四条命令TurnRight(); //执行动作四:右转break;default:break;}}}//=============================================================// 语法格式: void IRQ5(void);// 实现功能: 中断服务子函数// 参数: 无// 返回值: 无//============================================================= void IRQ5(void)__attribute__((ISR)); //运动定时控制 void IRQ5(void) {if(uiTimecont++ == uiTimeset){*P_IOB_Data = 0x0000;}*P_INT_Clear = 0x0004;}//=============================================================// 语法格式: int main(void);// 实现功能: 主函数// 参数: 无// 返回值: 无15//============================================================= int main(void){ unsigned int BS_Flag; //Train标志位*P_IOA_Dir=0xff00; //初始化IOA,IOA0~7下拉输入*P_IOA_Attrib=0xff00;*P_IOA_Data=0x0000;*P_IOB_Dir=0x0f00; //初始化IOB,IOB8~11同向输出*P_IOB_Attrib=0x0f00;*P_IOB_Data=0x0000;BSR_DeleteSDGroup(0); //初始化存储器RAMBS_Flag=*(unsigned int *)0xe000; //读存储单元0xe000if(BS_Flag==0xffff) //没有经过训练(0xe000内容为0xffff){TrainSD(); //训练StoreSD(); //存储训练结果(语音模型)}else //经过训练(0xe000内容为0x0055){LoadSD(); //语音模型载入识别器}PlaySnd(S_START,3); //开始识别提示BSR_InitRecognizer(BSR_MIC); //初始化识别器while(1){BSR();if((*P_IOA_Data)&0x0004) //是否重新训练{F_FlashErase(0xe000);while(1);}}}166.3 语音识别的原理简介语音识别主要分为“训练”和“识别”两个阶段。

相关主题