基于语音识别的个人电梯系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于语音识别的个人电梯系统
数学与计算机科学学院 电子信息科学与技术专业
学号:105032005018 姓名:兰俊福 指导教师:郑子华
【摘 要】:设计语音控制步进电机系统,通过凌阳16位单片机提供的语音模块,实现步进机组成的电梯系统控制,实现声控电梯。

语音通过麦克风输入,由喇叭输出,输入的语音经过微处理器处理后识别控制相应的步进电机和数码管的显示。

文中介绍了系统的硬件结构和软件功能,详细描述凌阳单片机语音识别控制方法与设计。

【关键词】:凌阳单片机;电梯;语音识别;步进电机;
引言 (3)
1 方案分析 (3)
1.1方案选择和对比 (3)
1.1.1 单片机80C51 (3)
1.1.2 凌阳单片机 (3)
1.1.3 DSP芯片 (3)
1.2方案总结 (3)
2 概要设计 (4)
2.1设计思路 (4)
2.2模块设计分析 (4)
2.2.1 步进机运转模块 (4)
2.2.2 数码管模块 (5)
2.2.3 麦克风模块 (5)
2.3软件体系结构 (6)
3 详细设计 (7)
3.1硬件电路设计 (7)
3.1.1 主控芯片凌阳单片机SPSCE061A介绍 (7)
3.1.2 步进电机工作原理和步进电机驱动器的介绍 (9)
3.1.3 电容式麦克风介绍 (10)
3.1.4 扬声器介绍 (10)
3.2软件设计 (10)
3.2.1 凌阳的音频压缩算法及API函数 (10)
3.2.2 WAV格式压缩 (12)
3.2.3 语音识别的电路结构 (12)
3.2.4 系统程序流程图 (13)
3.2.5 程序流程说明 (13)
3.2.6 程序子函数模块代码 (14)
4 结果与总结 (20)
4.1实验结果 (20)
4.2总结 (21)
参考文献 (22)
附录 (24)
引言
步进电动机作为一种数字伺服执行元件,具有结构简单、运行可靠、控制方便、控制性能好等优点,在诸多运动控制领域有着广泛应用,如在汽车电子,医疗电子等领域。

语音识别技术与语音合成技术结合使人们能够甩掉键盘,通过语音命令进行操作。

语音技术的应用已经成为一个具有竞争性的新兴高技术产业。

而现在许多微处理器的内部时钟也越来越高,处理数据的能力也越来越强,越来越快。

本设计是利用凌阳单片机提供的语音信号处理的高效优点实现语音对步进电机与数码管显示的控制,最终控制电梯系统的运行。

1 方案分析
系统要求:①、通过麦克风把语音输入进去处理并存储,控制其从喇叭播放。

②、通过语音的识别控制步进电机的旋转,包括正转,反转。

③、通过语音的识别控制数码管的跳变显示。

1.1 方案选择和对比
1.1.1 单片机80C51
80c51单片机是功能极强的8位高档单片机,非常适用于逻辑控制,拥有4k的程序存储器,128的的数据存储器,两个16位的定时器,富含32个并行IO口,最高频率达12MHZ,外扩AD和DA转换器可以进行数据的处理控制。

1.1.2 凌阳单片机
凌阳单片机的CPU内核采用凌阳最新推出的Microcontroller and Signal Processor 16位微机处理器芯片,它将许多功能部件集成在一个芯片内,包括AD,DA转换等,体积小 ,集成度高,可靠性好且易于扩展。

1.1.3 DSP芯片
DSP芯片是是一种特别适合于进行数字信号处理运算的微处理器器,其主要应用是实时快速地实现各种数字信号处理算法。

片内具有快速RAM,具有强大数据处理能力和高运行速度。

1.2 方案总结
综合考虑以三种方案,第一种要实现对语音信号的处理比较难,毕竟是通用处理器,不适合复杂的信号处理等算法。

第二种凌阳单片机可以说是小型的dsp芯片,也就是数字信号处理芯片,且内部集成各种模数转换,数模转换的模块,所以对语音信号处理可以提供良好的平台。

第三种拥有强大的数据处理能力和运行速度,对语音信号的处理控制可以实现,但是总结方案,相对本设计来说,凌阳单片机的性价比较高,所以选择凌阳单片机微控制器完成设计
2 概要设计
2.1 设计思路:
本设计是采用凌阳单片机提供的语音处理模块对步进电机和数码管进行控制,实现声控电梯。

从麦克风把语音信号输入进去,经过放大,自动增益控制,模数转换,存储到ROM 里。

调用凌阳提供的API函数进行控制播放,将要辨别的语音信号输入进去调用相应的API 函数进行识别控制步进电机的运转、数码管的显示、相应语音的播放。

下图2.1为系统框图:
图2.1 系统框图
2.2 模块设计分析
2.2.1 步进机运转模块
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。

在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。

本设计采用的是四相六线制步进机。

该模块需要实现两种功能:
①、搭建驱动电路,驱动步进电机;
②、向驱动器发送转动命令。

驱动电路部分;
由于单片机引脚输出的功率不足于使步进电机转动,所以要添加驱动部分,本设计是加入ULN2003芯片;ULN2003 是高耐压、大电流达林顿陈列,由七个硅NPN 达林顿管组成。

uln2003电路的特点如下:
ULN2003 的每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连。

ULN2003 工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V 的电压,输出还可以在高负载电流并行运行。

ULN2003可以为本步进电机提供足够的功率使其转动。

具体接法如下图:
图3.21 ULN2003驱动器接法
若给uln2003提供的vcc越高,力矩就越大,转动越有力量。

一般需要5v以上。

向驱动器发送转动命令:
步进电机区别于其他控制电机的最大特点是,它是通过输入脉冲信号来进行控制的,即电机的总转动角度由输入脉冲数决定,而电机的转速由脉冲信号频率决定,所以编程向步进机发送循环脉冲就可以控制步进机的转动。

2.2.2 数码管模块
由于数码管的码段是led,所以只要几毫安到几十毫安的电流即可,凌阳单片机的引脚可以满足其条件,再加上本设计是利用共阴极单位数码管,公共脚直接接地,所以没有灌电流太大而损坏单片机的情况。

接法如下图2.22:
图2.22 数码管接法
2.2.3 麦克风模块
麦克风是声电转换器,通过声波控制电流的变化; 下图为麦克风的电路模块:
图2.23 麦克风电路模块
其中X1是麦克风,将声波转换成电压,vmic和avss1分别为麦克风的电源端和模拟地端,micp和micn分别为输入到差分放大器的两个正负电压输入端。

在SPCE061芯片中内部已经集成了对语音转换来的电压进行放大,自动增益;音频输入组成框图2.23如下:
框图2.23
运算放大器的输入级是差分放大电路组成,它是运算放大器的主要组成部分,它有两个输入端,这样能有效的抑制共模信号,放大有效的信号。

输出U0经过自动增益控制使得输入的语音的大小再处理后音量(也就是后来的电压)相差不大。

2.2.4 语音输出模块:
语音经过数模转换后需要经过运算放大器输出;61板提供的具体电路如下;
图2.24 语音输出电路
其中spy0030是凌阳的芯片,相当于lm386;但比lm386有更好的音质,且可以工作在2.2内到6v之内;最大输出功率可达700mw;SPY0030个引脚的功能如下:
1.音频输出负端;
2.音频输出正端;
3.地端;
4.音频输入负端;
5.音频输入负端;
6.参考电压;
7.芯片使能端;
8.电源;
2.3 软件体系结构
图2.3 软件体系结构图
3 详细设计
3.1 硬件电路设计
此次设计的硬件材料; 61板:麦克风,扬声器; 步进电机驱动器; 一位数码管;
总体电路如图3.1所示:
图3.1 总体电路图 3.1.1 主控芯片凌阳单片机SPSCE061A介绍
SPCE061A 是继μ’nSP™系列产品SPCE500A等之后凌阳科技推出的又一款16位结构的微控制器。

SPCE061A里内嵌32K字的闪存(FLASH)。

较高的处理速度使μ’nSP™能够非常容易地、快速地处理复杂的数字信号。

管脚配置图3.112如下:
图3.112 管脚配置图
如上图所示;SPSCE061有32个普通IO口:IOA0-IOA15;IOB0-IOB15;有两个模拟量输出引脚,振荡电路输出输入两个引脚;AGC的控制引脚;麦克风的正向负向输入引脚;还有一些芯片需要电源与底线的引脚等;本设计利用到的引脚是IOB0-IOB11;DAC语音播放输出引脚DAC,麦克风的正向负向引脚MICP,MICN,语音信号的自动增益引脚AGC。

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

3.1.2 步进电机工作原理和步进电机驱动器的介绍
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。

在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。

这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。

使得在速度、位置等控制领域用步进电机来控制变的非常的简单。

四相反应式步进电机的工作原理
○1结构: 电机转子均匀分布着很多小齿,定子齿有四个励磁绕阻,其几何轴线依次分别与转子齿轴线错开。

0、1/2て, て;(相邻两转子齿轴线间的距离为齿距以て表示),即A 与齿1相对齐,B与齿2向右错开1/2て,C与齿3向右错开て,D与齿4错开1/2て;
○2力矩: 电机一旦通电,在定转子间将产生磁场(磁通量Ф)当转子与定子错开一定角度产生力F与(dФ/dθ)成正比。

其磁通量Ф=Br*S Br为磁密,S为导磁面积 F与L*D*Br 成正比 L为铁芯有效长度,D为转子直径 Br=N·I/RN·I为励磁绕阻安匝数(电流乘匝数)R为磁阻。

力矩=力*半径力矩与电机有效体积*安匝数*磁密 成正比(只考虑线性状态)因此,电机有效体积越大,励磁安匝数越大,定转子间气隙越小,电机力矩越大,反之亦然。

○3基本旋转原理:四相六线制步进机内部模拟如下图3.12;
图3.12 步进电机内部模拟结构
当A通电(高电平),BCD不通电(低电平)时,由于磁场作用;齿1与A对齐;
当B通电,ACD不通电时,齿2与B对齐,这时步进机逆时针旋转了45度;
当C通电,ABD不通电时,齿3与C对齐,这时步进机逆时针又旋转了45度;
当D通电,ABC不通电时,齿4与D对齐,这时步进机逆时针又旋转了45度;
当A通电,BCD不通电时,齿1与A对齐,这时步进机逆时针又旋转了45度;
这样一周,步进机旋转了180度;
如此循环,步进电机就逆时针旋转了,如果按ADCBA方式循环通电,则步进电机就按顺时针旋转。

如果给它通电也就是脉冲的间隔越短,则步进机的转速就越快,即在一定的范围内,步进机的转速与脉冲频率成正比。

3.1.3 电容式麦克风介绍
本设计采用的电容式麦克风;电容式麦克风有两块金属极板,其中一块表面涂有驻极体薄膜(多数为聚全氟乙丙烯)并将其接地,另一极板接在场效应晶体管的栅极上,栅极与源极之间接有一个二极管。

当驻极体膜片本身带有电荷,表面电荷地电量为Q,板极间地电容量为C,则在极头上产生地电压U=Q/C,当受到振动或受到气流地摩擦时,由于振动使两极板间的距离改变,即电容C改变,而电量Q不变,就会引起电压的变化,电压变化的大小,反映了外界声压的强弱,这种电压变化频率反映了外界声音的频率,这就是驻极体传声器地工作原理。

3.1.4 扬声器介绍
扬声器是一种十分常用的电声换能器件,扬声器在电子元器件中是一个最薄弱的器件,而对于音响效果而言,它又是一个最重要的器件。

扬声器的种类繁多。

音频电能通过电磁、压电或静电效应,使其纸盆或膜片振动周围空气造成音响。

按换能机理和结构分动圈式(电动式)、电容式(静电式)、压电式(晶体或陶瓷)、电磁式(压簧式)、电离子式和气动式扬声器等,电动式扬声器具有电声性能好、结构牢固、成本低等优点,应用广泛;按声辐射材料分纸盆式、号筒式、膜片式;按纸盆形状分圆形、椭圆形、双纸盆和橡皮折环;按工作频率分低音、中音、高音,有的还分成录音机专用、电视机专用、普通和高保真扬声器等;按音圈阻抗分低阻抗和高阻抗;按效果分直辐和环境声等。

3.2 软件设计
3.2.1 凌阳的音频压缩算法及API函数
凌阳的音频压缩算法分为有损压缩和无损压缩;
凌阳音频压缩算法根据不同的压缩比分为以下几种:
SACM-A2000:压缩比为8:1,8:1.25,8:1.5
SACM-S480: 压缩比为80:3,80:4.5
SACM-S240: 压缩比为80:1.5
每一种算法凌阳都提供了相关的API函数;
SACM-A2000:
相关的API函数:
void SACM_A2000_Initial(int Init_Index) //初始化
void SACM_A2000_ServiceLoop(void) //获取语音资料,填入译码队列
void SACM_A2000_Play(int Speech_Index, int Channel, int Ramp_Set) //播放 void SACM_A2000_Stop(void) //停止播放
void SACM_A2000_Pause (void) //暂停播放
void SACM_A2000_Resume(void) //暂停后恢复
void SACM_A2000_Volume(Volume_Index) //音量控制
unsigned int SACM_A2000_Status(void) //获取模块状态
void SACM_A2000_InitDecode(int Channel) //译码初始化
void SACM_A2000_Decode(void) //译码
void SACM_A2000_FillQueue(unsigned int encoded-data)//填充队列
unsigned int SACM_A2000_TestQueue(void) //测试队列
Call F_FIQ_Service_ SACM_A2000 //中断服务函数
SACM-S480:
相关的API函数
int SACM_S480_Initial(int Init_Index) //初始化
void SACM_ S480_ServiceLoop(void) //获取语音资料,填入译码队列
void SACM_ S480_Play(int Speech_Index, int Channel, int Ramp_Set)播放 void SACM_ S480_Stop(void) //停止播放
void SACM_S480_Pause (void) //暂停播放
void SACM_S480_Resume(void) //暂停后恢复
void SACM_S480_Volume(Volume_Index) //音量的控制
unsigned int SACM_S480_Status(void) //获取模块的状态
Call F_FIQ_Service_ SACM_S480 //中断服务函数
SACM-S480:
相关的API函数
int SACM_S240_Initial(int Init_Index) //初始化
void SACM_ S240_ServiceLoop(void) //获取语音资料,填入译码队列
void SACM_ S240_Play(int Speech_Index, int Channel, int Ramp_Set)播放 void SACM_ S240_Stop(void) //停止播放
void SACM_S240_Pause (void) //暂停播放
void SACM_S240_Resume(void) //暂停后恢复
void SACM_S240_Volume(Volume_Index) //音量控制
unsigned int SACM_S240_Status(void) //获取模块状态
Call F_FIQ_Service_ SACM_S240 //中断服务函数
语音辨识的一些API函数:
int BSR_DeleteSDGroup(0);初始化;
int BSR_Train (int CommandID, int TraindMode);训练部分
void BSR_InitRecognizer(int AudioSource);辨识器初始化
void BSR_StopRecognizer(void);停止辨识
BSR_InitRecognizer;中断部分
3.2.2 WAV格式压缩
对于常用的SACM_A2000和SACM_S480两种放音算法要涉及到语音资源的添加问题,即将录制的WAV文件按照需要的压缩比进行压缩,变成资源表形式在程序中调用。

需要通过压缩软件进行压缩,如图3.221:压缩算法可压缩比可选,如图3.222:
图3.221 图3.222
将生成的压缩文件加载到工程的资源文件当中就可进行调用。

3.2.3 语音识别的电路结构
语音识别的实现方案是将输入的语音信号进行预处理,包括滤波,采样,量化,加窗,端点检测,预加重等,语音信号经过预处理后需要进行特征参数处理。

这样可以同时生成模板库语音和需要辨识的信号,将需要辨识的信号与模板信号的特征参数相比较分析可以粗略的得出识别结果。

语音识别的电路结构图3.23如下:
图3.23 语音识别的电路结构图
3.2.4 系统程序流程图
图3.24 程序流程图 3.2.5 程序流程说明
提示音 输入语音
“请输入触发名称” “电梯”
“请输入第一条命令”“一楼”
“请输入第二条命令”“二楼”
“请输入第三条命令” “三楼”
“请输入第四条命令” “四楼”
“请再说一遍”(以上提示音每说完一遍出现此命令)
“没有听到任何声音” (当没有检测到声音时出现此命令)
“两次输入不一样”(当两次输入的名称不同时出现此命令)
“准备就绪”(以上五条语句全部训练成功时,进入识别)
*************识别*****************************************
发布命令 应答
“电梯” “要去几楼”
“一楼” 步进机转动到一楼,数码管跳变到显示1,播放“一楼到”;
“二楼” 步进机转动到二楼,数码管跳变到显示2,播放“二楼到”;
“三楼” 步进机转动到三楼,数码管跳变到显示3,播放“三楼到”;
“四楼” 步进机转动到四楼,数码管跳变到显示4,播放“四楼到”;
如果已经输入触发名称,却没输入命令,播放“请问您要去几楼”;
3.2.6 程序子函数模块代码
○1播放语音部分调用的API函数包括:
【API格式】int SACM_S480_Initial(int Init_Index)
【功能说明】SACM_S480语音播放之前的初始化。

【参 数】Init_Index=0 表示手动方式;Init_Index=1 则表示自动方式。

【返 回 值】0:代表语音模块初始化失败
1:代表初始化成功。

【备 注】该函数用于对定时器、中断和DAC等的初始化。

【API格式】void SACM_S480_ServiceLoop(void)
【功能说明】从资源中获取SACM_S480语音资料,并将其填入解码队列中。

【API格式】int SACM_S480_Play(int Speech_Index, int Channel, int Ramp_Set); 【功能说明】播放资源中SACM_S480语音或乐曲。

【参 数】 Speech _Index 表示语音索引号。

Channel: 1.通过DAC1通道播放;
2.通过DAC2通道播放;
3.通过DAC1和DAC2双通道播放。

Ramp_Set:0.禁止音量增/减调节;
1.仅允许音量增调节;
2.仅允许音量减调节;
3.允许音量增/减调节。

【返 回 值】无。

【 API格式】unsigned int SACM_S480_Status(void);
【功能说明】获取SACM_S480语音播放的状态。

【参 数】无。

【返 回 值】当R1的值 bit0=0,表示语音播放结束;bit0=1,表示语音在播放中。

语音播放部分代码:
void PlayRespond(int Result)
{
BSR_StopRecognizer(); //停止辨识
SACM_S480_Initial(1); //初始化
SACM_S480_Play(Result, 3, 3);// 播放对应序号的语音
while((SACM_S480_Status()&0x0001) != 0)
{
SACM_S480_ServiceLoop(); //取语音资料,填入译码队列中
ClearWatchDog(); //清除看门狗
}
SACM_S480_Stop(); //停止播放
BSR_InitRecognizer(BSR_MIC); //初始化辨识器
BSR_EnableCPUIndicator(); //启动实时监控
}
○2训练模块部分调用的API函数:
【API格式】int BSR_Train (int CommandID, int TraindMode);
【功能说明】训练函数。

【参 数】
CommandID:命令序号,范围从0x100到0xFFF,并且对于每组训练语句都是
唯一的。

TraindMode:训练次数,要求使用者在应用之前训练一或两遍:
BSR_TRAIN_ONCE:要求训练一次。

BSR_TRAIN_TWICE要求训练两次。

【返 回 值】训练成功,返回0;没有声音返回-1;训练需要更多的语音数
据来训练,返回-2;当环境太吵时,返回-3;当数据库满,返回-4;当
两次输入命令不通,返回-5;当序号超出范围,返回-6。

C 代码
○3训练模块部分代码:
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(sorry);
return -1;
case -2: //需要重新训练一遍
PlayRespond(sayagain);
break;
case -3: //环境太吵
PlayRespond(huanjing);
return -1;
case -5: //检测出声音不同
PlayRespond(liangci); //两次输入名称不同
return -1;
case -6: //序号错误
return -1;
}
}
return 0;
}
○4步进机运转与数码管显示模块代码:
void F_upordown()
{int q,d;
if(ne>=cu){d=ne-cu; //输入的命令层序号大于当前层序号 for(q=0;q<d;q++){for(w=0;w<10;w++)
{ *P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0100;F_Delay(400);//将0x01 //赋给IOB口的高八位;
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0200;F_Delay(400);
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0400;F_Delay(400);
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0800;F_Delay(400);
}
cu++; *P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]); //数码管跳变 //将cu所对应的码值赋给IOB口的低八位;
}}
else{d=cu-ne; //输入的命令层序号小于当前层序号 for(q=0;q<d;q++){for(w=0;w<10;w++)
{
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0800;F_Delay(400);
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0400;F_Delay(400);
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0200;F_Delay(400);
*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0100;F_Delay(400);
}
cu--;*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]); //数码管跳变 }}
}
○5语音辨识模块部分调用的API函数:
【API格式】int BSR_DeleteSDGroup(0);
【功能说明】SRAM初始化。

【参 数】该参数是辨识的一个标识符,0代表选择SRAM,并初始化。

【返 回 值】当SRAM擦除成功返回0,否则,返回-1。

【API格式】void BSR_InitRecognizer(int AudioSource)
【功能说明】辨识器初始化。

【参 数】 定义语音输入来源。

通过MIC语音输入还是LINE_IN电压模拟量输入。

【API格式】int BSR_GetResult();
【功能说明】辨识中获取数据。

【参 数】 无。

【返回值】R1
当无命令识别出来时,返回0;
识别器停止未初始化或识别未激活返回-1;
当识别不合格时返回-2;
当识别出来时返回命令的序号。

【API格式】void BSR_StopRecognizer(void);
【功能说明】停止辨识。

语音识别模块的代码(主函数的部分代码):
Int main{
BSR_InitRecognizer(BSR_MIC); //辨识器初始化
BSR_EnableCPUIndicator(); //启动实时监控 PlayRespond(start); //播放开始辨识的提示音
while(1)
{
res = BSR_GetResult(); //获取识别结果
if(res > 0)
{
if(gActivated)
{
timeCnt = 0;
switch(res)
{
case NAME_ID:
PlayRespond(which);
break;
case COMMAND_ONE_ID: //识别第一个命令
ne=1;
F_upordown();
PlayRespond(first);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
case COMMAND_TWO_ID:
ne=2;
F_upordown();
PlayRespond(second);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
case COMMAND_THREE_ID:
ne=3;
F_upordown();
PlayRespond(third);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]); gActivated =0;
break;
case COMMAND_FOUR_ID:
ne=4;
F_upordown();
PlayRespond(forth);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
} }
else
{
if(res == NAME_ID)
{
PlayRespond(which);
gActivated = 1;
timeCnt = 0;
}
}
}
else if (gActivated)
{
if (++timeCnt > 450) //超出定时
{
PlayRespond(sorry);
gActivated = 0;
timeCnt = 0;
}
}
}
}
汇编代码
○6IO初始化模块代码:
_InitIO: .PROC
r1=0xffff
[Port_IOB_Attrib] = r1 //B口设置为同向输出 [Port_IOB_Dir] = r1
[Port_IOB_Data] = r1 //B口置高电平
r1=0xffff
[Port_IOA_Attrib] = r1 //A口设置为同向输出 [Port_IOA_Dir] = r1
r1 = 0xffff
[Port_IOA_Data] = r1 //A口置高电平
retf
.ENDP
○7延时模块代码:
_F_Delay: .proc
push r1,r5 to [sp];
bp=sp+3
L_Loop1:
R2=r1;
r3=1
r4=0x7012
[r4]=r3
L_Loop2:
R2-=1;
JNZ L_Loop2;
R1-=1;
JNZ L_Loop1;
pop r1,r5 from [sp];
retf
.endp
.END
4 结果与总结
4.1 实验结果
将程序烧到单片机芯片中,搭建好电梯模型;给芯片电源提供3v电压,给uln2003驱动器提供6v电压;此时扬声器会提示输入触发命令与第一到第四条命令;顺利进行语音训练后,
扬声器提示“准备就绪”,这时可以对电梯进行相应的声控;
单片机复位后开机效果如下图:数码管显示1,电梯模型处在1F处;
图4.11 开机效果
当用语音对电梯进行控制时,先要输入触发名称“电梯”,系统语音提示“要去几楼”,这时输入“二楼”,步进电机就会转动将模型电梯拉到二楼,数码管跳变到2,接着语音播放“二楼到”,如图4.12;又比如,在二楼的基础上再次输入“电梯”,系统提示完输入“四楼”;
电梯模型就被拉到四楼,数码管跳变到4,接着播报“四楼到”,如图4.13;如果输入了触发名称后没有再输入任何命令,系统会语音提示“请问您要去几楼”。

图4.12 图4.13
4.2 总结
本次设计基本上达到预期的效果,模型也成功完成,实现了人语音与系统的交流。

对于语音识别这块的认知上,遇到的诸多难点在指导老师的帮助下大部分解决。

本次设计是采用具有语音模块处理的凌阳单片机,从完全陌生到使用IDE软件编程应用的过程中,遇到过许多形形色色的问题,都在努力探索与调试中解决了。

肯定了自己在这方面的学习能力。

同时也对可编程芯片有了进一步系统的了解与应用。

通过这次设计不仅提高了我的C语言编程能力,同时也增强了个人动手能力。

但是其中也暴露出了一些不足,主要的硬件电路(61板)是已经做好的,我是在这基础上应用到其他外围硬件电路上,这一点上认识到了自己硬件方面的设计有待提高。

再者,主要的语音识别的算法也已经存在,我是直接调用其相应的API函数,这一点上认识到了自己在算法编程方面的能力需要多多实践。

总而言之,这次的设计让我接触到了一种新的芯片,也让我了解了自己的不足,清楚了以后需要加强的部分。

参考文献
[1] 李晶皎.嵌入式语音技术及凌阳16位单片机应用.北京:北京航空航天大学出版社,
2003,1-278.
[2] 侯媛彬.凌阳单片机原理及其毕业设计精选.北京:科学出版社,2006, 115-122.
[3] 刘幺和,宋庭新.语音识别与控制应用技术.北京:科学出版社,2008, 140-158.
[4] 宗孔德,胡广书.数字信号处理.北京:清华大学出版社,1988, 52-78.
[5] 赵负图.DSP处理器和微控制器硬件电路.北京:化学工业出版社,2006 3-8.
[6] 龚运新.单片机C语言开发技术.北京:清华大学出版社,2006, 10-23.
Based on personal elevator speech recognition system
College: Institute of Mathematics and Computer Science
Mojor: Electronic Information Science and Technology
No. Studies: 105032005018
Author Name: lan junfu
Instructor name: zheng zihua
【abstract】:Design voice controlled stepper motor system, Through the Sunplus 16-bit single-chip modules to provide voice, To achieve Stepper machine controlling the composition of the elevator system;To achieve Elevator Speech Control. Voice through the microphone input,and through speaker output, Voice input processed in the microprocessor then control the stepper motor and Digital tube. This paper introduces the hardware structure and software function, A detailed description of Sunplus Single-chip voice recognition control method and design;
【key words】:sunplus sigle-chip;elevator; Speech Recognition;stepper motor;
附录
附录一:C编程程序
#include "bsrsd.h"
*)0x7000
int
unsigned
(volatile
#define P_IOA_Data
int
*)0x7001
unsigned
(volatile
#define
P_IOA_Buffer
*)0x7002
int
unsigned
#define
P_IOA_Dir (volatile
*)0x7003
int
unsigned
#define
P_IOA_Attrib (volatile
*)0x7004
int
unsigned
#define
P_IOA_Latch (volatile
*)0x7005
unsigned
int
#define
P_IOB_Data (volatile
*)0x7006
int
unsigned
#define
P_IOB_Buffer
(volatile
int
*)0x7007
unsigned
#define
(volatile
P_IOB_Dir
int
*)0x7008
P_IOB_Attrib (volatile
unsigned
#define
#define NAME_ID 0x100
#define COMMAND_ONE_ID 0x101
#define COMMAND_TWO_ID 0x102
#define COMMAND_THREE_ID 0x103
#define COMMAND_FOUR_ID 0x104
#define COMMAND_FIVE_ID 0x105
#define COMMAND_SIX_ID 0x106
#define chufa 0
#define one 1
#define two 2
#define six 3
#define four 4
#define five 5
#define six 6
#define first 7
#define second 8
#define third 9
#define forth 10
#define fifth 11
#define sixth 12
#define yichu 13
#define sorry 14
#define sayagain 15
#define huanjing 16
#define liangci 17
#define start 18
#define which 19
int dis_7[10]={0x00c0,0x00f9,0x00a4,0x00b0, 0x0099, 0x0092, 0x0082, 0x00f8, 0x0080, 0x0090};
int gActivated = 0;
int e,a,b,w;
int ne=1,cu=1;
extern void ClearWatchDog();
int PlayFlag = 0;
void PlayRespond(int Result)
{
BSR_StopRecognizer();
SACM_S480_Initial(1);
SACM_S480_Play(Result, 3, 3);
0)
!=
while((SACM_S480_Status()&0x0001)
{
SACM_S480_ServiceLoop();
ClearWatchDog();
}
SACM_S480_Stop();
BSR_InitRecognizer(BSR_MIC);
BSR_EnableCPUIndicator();
}
int TrainWord(int WordID, int RespondID)
{
int
res;
PlayRespond(RespondID);
while(1)
{
BSR_Train(WordID,BSR_TRAIN_TWICE);
=
res
break;
0)
if(res
==
switch(res)
{
case -1: //没有检测出声音 PlayRespond(sorry);
-1;
return
case -2: //需要重新训练一遍 PlayRespond(sayagain);
break;
case -3: //环境太吵
PlayRespond(huanjing);
-1;
return
case -5: //检测出声音不同
PlayRespond(liangci); //两次输入名称不同
-1;
return
case -6: //序号错误
-1;
return
}
}
0;
return
}
void F_upordown()
{int q,d;
if(ne>=cu){d=ne-cu;
for(q=0;q<d;q++){for(w=0;w<10;w++){*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0100;F_Delay (400);*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0200;
F_Delay(400);*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0400;F_Delay(400);*P_IOB_Data=(*P_ IOB_Data&0x00ff)|0x0800;
F_Delay(400);}cu++;*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
}}
else{d=cu-ne;
for(q=0;q<d;q++){for(w=0;w<10;w++){*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0800;F_Delay (400);*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0400;
F_Delay(400);*P_IOB_Data=(*P_IOB_Data&0x00ff)|0x0200;F_Delay(400);*P_IOB_Data=(*P_ IOB_Data&0x00ff)|0x0100;
F_Delay(400);}cu--;*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
}}
}
int main()
{
int res, timeCnt = 0;
InitIO();
*P_IOB_Data=~dis_7[1];
ne=1;
cu=1;
BSR_DeleteSDGroup(0);
// 初始化存储器RAM
// 播放开始训练的提示音"请输入触发名称"
//..........训练名称..............................
while(TrainWord(NAME_ID,0) != 0) ;
//..........训练第一条命令.......................
while(TrainWord(COMMAND_ONE_ID,1) != 0) ;
//..........训练第二条命令.......................
while(TrainWord(COMMAND_TWO_ID,2) != 0) ;
//..........训练第三条命令.......................
while(TrainWord(COMMAND_THREE_ID,3) != 0) ;
//..........训练第四条命令.......................
while(TrainWord(COMMAND_FOUR_ID,4) != 0) ;
//..........训练第五条命令.......................
//..........开始识别命令.........................
BSR_InitRecognizer(BSR_MIC); //辨识器初始化BSR_EnableCPUIndicator(); //启动实时监控
PlayRespond(start); //播放开始辨识的提示音 while(1)
{
BSR_GetResult();
=
res
>
0)
if(res
{
if(gActivated)
{
timeCnt = 0;
switch(res)
{
case NAME_ID:
PlayRespond(which);
break;
COMMAND_ONE_ID:
case
//识别第一个命令
ne=1;
F_upordown();
PlayRespond(first);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
COMMAND_TWO_ID:
case
ne=2;
F_upordown();
PlayRespond(second);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
COMMAND_THREE_ID:
case
ne=3;
F_upordown();
PlayRespond(third);
*P_IOB_Data=(*P_IOB_Data&0xff00)|(~dis_7[cu]);
gActivated =0;
break;
case COMMAND_FOUR_ID:。

相关文档
最新文档