基于单片机的语音识别系统 毕业设计 好
基于单片机的语音识别系统
基于单片机的语音识别系统
摘要
近几年来,智能化和自动化技术在玩具制造领域中越来越被关注。本文介绍一种智能化小车控制系统的设计——语音控制小车。语音控制小车是基于SPCE061A 的代表性兴趣产品,它配合61板推出,综合应用了SPCE061A 的众多资源,小车采用语音识别技术,可通过语音命令对其行驶状态进行控制 。首先介绍了SPCE061A 的主要性能及其引脚的功能;接着完成了电源电路、复位电路、键盘电路、音频输入电路,音频输出电路和无线控制电路等硬件功能模块的设计。软件设计模块能实现智能小车的前进、后退、转向、停止、避障、表演动作以及循线等功能。测试表明,在环境背景噪音不太大,控制者的发音清晰的前提下,语音控制小车的语音识别系统能对特定的语音指令做出智能反应,做出预想中的有限的动作
关键词 :spec061a 语音识别 驱动电路 声控小车 智能反应
Abstract
In recent years, Intelligent and automation technology in the toy manufacture have been paid more and more attention.Introduce an intelligent vehicle control system design. SPCE061A program the system to single-chip, based on implementation of the car's voice control, This paper introduces the hardware sub-system design and implementation. The SPCE061A's main characters and pin function are introduced firstly. Completed the power circuit, reset circuit, keyboard circuitry, audio input circuits, audio output circuit and control circuit of wireless hardware such as the design of function modules. Software design module can achieve smart car forward, backward, turn, stop, obstacle avoidance, performing actions, as well as on-line functions. Test showed that the background noise in the environment is not too great, control persons under the premise of clear pronunciation, voice control car speech recognition systems for specific voice commands to make intelligent reaction, limited to the desired action.
Keywords : spec061a 、voice recogniton、Driving circuit、 Voice control dolly、intelirent response
目录
摘要 ............................................................................................................ I Abstract .................................................................................................. II 目录 ......................................................................................................... III
前言 ........................................................................................................... 1
1 方案介绍及设计简介 ........................................................................... 2
1.1 小车的控制要求及设计方案 ................................................. 2
1.1.1 小车的控制要求 .............................................................. 2
1.1.2 方案设计与论证 .............................................................. 2
1.2 SPCE061A 简介 ..................................................................... 3
1.2.1 SPCE061A 单片机概述 ................................................... 5
1.2.2 SPCE061A 的介绍 ........................................................... 7
1.2.3 SPCE061A 的结构 ........................................................... 7
1.3 SPCE061A 单片机强大的语音功能 ..................................... 8
1.3.1 语音识别的原理 .............................................................. 8
1.3.2 系统的结构框图 .............................................................. 9
1.4 语音控制小车设计要求 ....................................................... 10
1.4.1 功能要求 ........................................................................ 10
1.4.2 语音控制小车的主要功能 ............................................ 10
1.4.3 参数说明 ........................................................................ 10
1.4.4 注意事项 ........................................................................ 10
2 电路设计及程序设计 .................................................................. 11
2.1 电路设计基础知识 ............................................................... 11
2.2 电路方框图及说明 ............................................................... 13
2.3 各部分电路设计 ................................................................... 13
2.3.1 电机的选择 .................................................................... 14
2.3.2 继电器驱动电路的设计 ................................................ 14
2.3.3 行驶状态控制电路设计 ................................................ 15
2.3.4
2.3.5
3 麦克录音输入及AGC 电路 .......................................... 16 语音播报电路 ................................................................ 18 软件设计 ...................................................................................... 19
3.1 软件流程图及设计思路说明 ............................................... 19
3.1.1 程序设计 ........................................................................ 20
3.2 模块设计 ............................................................................... 20
3.2.1 中断流程图部分 ............................................................ 20
3.2.2 语音识别部分 ................................................................ 22
4 连接和操作说明 .......................................................................... 25
4.1 硬件模块连接图 ................................................................... 25
4.1.1 功能说明 ........................................................................ 25
4.1.2 代码下载 ........................................................................ 26
4.1.3 训练小车 ........................................................................ 27
4.1.4 声控小车 ........................................................................ 28
4.1.5 重新训练 ........................................................................ 28
总结 ......................................................................................................... 30
致谢 ......................................................................................................... 31
参考文献 ................................................................................................. 32
附件1 系统程序说明 .......................................................................... 33
前言
语音识别技术是近年来十分活跃的研究领域。语音识别系统的实用化研究是语音识别研究的一个主要方向。以玩具市场为例,具有高科技含量的电子玩具、智能玩具发展迅猛,电子互动式、智能化玩具已经成为玩具行业发展的主流。我国是玩具生产和出口大国,但在高科技玩具的发展方面和国外的差距很大,因此,及时投入精力广泛开展这方面的研究,无论对技术创新应用,还是社会经济发展,都有巨大的现实意义。与机器进行语音交流,让机器明白你说什么,这是人们长期以来梦寐以求的事情。语音识别技术就是让机器通过识别和理解过程把语音信号转变为相应的文本或命令的高技术。近二十年来,语音识别技术取得显著进步,开始从实验室走向市场。语音识别功能大大增加了玩具使用的乐趣,并使玩具体现出一定的智能性,因此成为大部分电子玩具、智能玩具设计中使用的关键技术。
本文利用凌阳单片机设计一个具有语音识别功能的智能遥控小车。该设计将遥控车由传统的手动遥控改成了语音识别遥控,集成了先进的语音识别技术,加上小车的机动灵活的特点,使控制者可以通过语音控制小车实现预设动作,从而释放控制者的双手,而且小车和控制者之间还具有一定的交互功能。所以此次研究具有较强的实用性和发展前景。
1 方案介绍及设计简介
1.1 小车的控制要求及设计方案
1.1.1 小车的控制要求
论文设计的要求是要用语音来控制小车的行驶状态。根据开始语音训练录制的语音命令来控制小车的前进、倒退、左转、右转和停止;在行驶的过程中小车通过光电传感器自动检测障碍物,并且自动避开障碍物绕道行驶。在整过行驶过程中小车自动记录行驶的路程和时间。
1.1.2 方案设计与论证
本系统为典型的实时控制系统,易用单片机控制来实现,这里以凌阳SPCE061A 单片机为主控元件,提出两种设计方案。
方案一:
采用凌阳SPCE061A 十六位单片机,对小车的整个行驶过程进行实时监控,完成所有功能需要24个I/O口,由于凌阳SPCE061A 单片机提供32个I/O口,一片即可实现所有功能,这为设计过程提供了极大方便。其主要设计思想是:小车上,安装一个霍尔元件利用单片机的IOB3外部中断判别轮胎转数的结果用以计算路程;安装三个检测障碍物的光电检测器和一个碰撞开关,利用IOB4、IOB5、IOB6用扫描的方式来控制拐弯和返回;利用单片机的IOB8-IOB11控制继电器选择小车的正、反向行驶;凌阳SPCE061A 十六位单片机提供了丰富的时基信源和时基中断,给设计者以大量的选择空间,并给设计者提供精确的时基计数,其加减速通过大功率电阻消耗功率来实现。整体框架如图1,这种方案可以使程序简单,易于控制。
方案二:
此方案也采用凌阳SPCE061A 十六位单片机,与第一种方案不同之处在于利用单片机的IOB8 、IOB9产生控制调速的脉宽和控制小车的正、反行驶,用凌阳SPCE061A 十六位单片机的TimeA 和TimeB 很容易实现脉宽调制,这大大加强了用脉宽调制控制加减速的可选性,但对继电器要求较高,这里考虑到大众化设计,采用第一个方案。
1.2 SPCE061A 简介
在众多的单片机中,如C51、ARM 、AVR 等,我们选择了凌阳系列的单片机,采用的是凌阳61单片机,因为它本身具有音频处理功能,我们板子上具有音频输出,输入通道,具有麦克风,扬声器等硬件。在凌阳公司提供的开发环境中本身就具有关于音频处理的库函数以及音频压缩软件,在进行处理的时候比较容易,所以我们选择凌阳61的单片机,
基本结构如下图所示:
凌阳61单片机及硬件基本结构
SPCE061A 是凌阳科技研发生产的性价比很高的一款十六位单片机,使用它可以非常方便灵活的实现语音的录放系统,该芯片拥有8 路10 位精度的ADC ,其中一路为音频转换通道,并且内置有自动增益电路。这为实现语音录入提供了方便的硬件条件。两路10 精度的DAC ,只需要外接功放(SPY0030A )即可完成语音的播放。
另外凌阳十六位单片机具有易学易用的效率较高的一套指令系统和集成开发环境。在此环境中,支持标准C 语言,可以实现C 语言与凌阳汇编语言的互相调用,并且,提供了语音录放的库函数,只要了解库函数的使用,就会很容易完成语音录放,这些都为软件开发提供了方便的条件:SPCE061A 片内还集成了一个ICE (在线仿真电路)接口,使得对该芯片的编程、仿真都变得非常方便,而ICE 接口不占用芯片上的硬件资源,结合凌阳科技提供的集成开发环境(unSP IDE)用户可以利用它对芯片进行真实的仿真;而程序的下载(烧写)也是通过该接口进行下载。
SPCE061A 是继μ’nSP系列产品SPCE500A 等之后凌阳科技推出的又一款16位结构的微控制器。与SPCE500A 不同的是,在存储器资源方面考虑到用户的较少资源的需求以及便于程序调试等功能,SPCE061A 里内嵌32K 字的闪存(FLASH )。较高的处理速度使μ’nSP能够非常
容易地、快速地处理复杂的数字信号。因此,与SPCE500A 相比,以μ’nSP为核心的SPCE061A 微控制器是适用于数字语音识别应用领域产品的一种最经济的选择。
1.2.1 SPCE061A 单片机概述
随着单片机功能集成化的发展,其应用领域也逐渐地由传统的控制,扩展为控制处理、数据处理以及数字信号处理(DSP ,Digital Signal Processing)等领域。凌阳的16位单片机就是为适应这种发展而设计的。它的CPU 内核采用凌阳最新推出的μ’nSP(Microcontroller and Signal Processor)16位微处理器芯片(以下简称μ’nSP)。围绕μ’nSP所形成的16位μ’nSP系列单片机(以下简称μ’nSP家族)采用的是模块式集成结构,它以μ’nSP内核为中心集成不同规模的ROM 、RAM 和功能丰富的各种外设接口部件,如图2所示。
μ’nSP内核是一个通用的核结构。除此之外的其它功能模块均为可选结构,亦即这种结构可大可小或可有可无。借助这种通用结构附加可选结构的积木式的构成,便可形成各种不同系列派生产品,以适合不同的应用场合。这样做无疑会使每一种派生产品具有更强的功能和更低的成本。
μ’nSP家族有以下特点:
(1)体积小、集成度高、可靠性好且易于扩展
μ’nSP家族把各功能部件模块化地集成在一个芯片里,内部采用总线结构,因而减少了各功能部件之间的连线,提高了其可靠性和抗干扰能力。另外,模块化的结构易于系统扩展,以适应不同用户的需求。其结构式模块图如下:
μ’nSP家族的模块式结构
(2)具有较强的中断处理能力
μ’nSP家族的中断系统支持10个中断向量及10余个中断源,适合实时应用领域。
(3)高性能价格比
μ’nSP家族片内带有高寻址能力的ROM 、静态RAM 和多功能的I/O口。另外,μ’nSP的指令系统提供具有较高运算速度的16位×16位的乘法运算指令和内积运算指令,为其应用增添了DSP 功能,使得μ’nSP家族运用在复杂的数字信号处理方面既很便利,又比专用的DSP 芯片廉价。
(4)功能强、效率高的指令系统
μ’nSP指令系统的指令格式紧凑,执行迅速, 并且其指令结构提供了对高级语言的支持, 这可以大大缩短产品的开发时间。
(5)低功耗、低电压 。
μ’nSP家族采用CMOS 制造工艺,同时增加了软件激发的弱振方
式、空闲方式和掉电方式,极大地降低了其功耗。
另外,μ’nSP家族的工作电压范围大,能在低电压供电时正常工作,且能用电池供电。这对于其在野外作业等领域中的应用具有特殊的意义。
1.2.2 SPCE061A 的介绍
SPCE061A 是继μ’nSP系列产品SPCE500A 等之后凌阳科技推出的又一款16位结构的微控制器。与SPCE500A 不同的是,在存储器资源方面考虑到用户的较少资源的需求以及便于程序调试等功能,SPCE061A 里内嵌32K 字的闪存(FLASH )。较高的处理速度使μ’nSP能够非常容易地、快速地处理复杂的数字信号。因此,与SPCE500A 相比,以μ’nSP为核心的SPCE061A 微控制器是适用于数字语音识别应用领域产品的一种最经济的选择。
1.2.3 SPCE061A 的结构
SPCE061A的结构
1.3 S PCE061A 单片机强大的语音功能
凌阳音频处理过程:自己录取一段不大于4Kb 的WAV 语音文件或者从原有WAV 语音文件中截取一段不大于4KB 的语音。然后用凌阳语音压缩工具压缩,再将压缩后的文件添加到凌阳公司提供的开发环境中,程序经过单片机处理后,语音通过喇叭播放出来。如图下图所示
:
凌阳音频识别过程
1.3.1 语音识别的原理
首先是语音训练,然后是语音匹配,接着进行语音处理。如果匹配成功就执行相应的功能,否则重新匹配。
如下图所示:
语音识别系统简图
1.3.2 系统的结构框图
如图下图所示
:
智能车系统结构框图
系统组成主要包括以下两部分:SPCE061A 精简开发板、语音小车控制电路板。图中的语音输入部分MIC_ IN、按键输入KEY 、声音输出部分的功率放大环节等已经做到了精简开发板——61板上,为我们使
用提供了很大的方便。在电机的驱动方面,采用全桥驱动技术,利用四个I/O端口分为两组分别实现两个电机的正传、反转和停三态运行。
1.4 语音控制小车设计要求
1.4.1 功能要求
语音控制小车基于SPCE061A 的代表性兴趣产品,它配合61板推出,综合应用了SPCE061A 的众多资源,小车采用语音识别技术,可通过语音命令对其行驶状态进行控制。
1.4.2 语音控制小车的主要功能
可以通过简单的I/O操作实现小车的前进、后退、左转、右转功能;
配合SPCE061A 的语音特色,利用系统的语音播放和语音识别资源,实现语音控制的功能;
可以在行走过程中声控改变小车运动状态;
在超出语音控制范围时能够自动停车
1.4.3 参数说明
车体:双电机两轮驱动
供电:电池(四节AA :1.2V ×4 或1.5V ×4)
工作电压:DC 4V~6V
工作电流:运动时约200mA
1.4.4 注意事项
注意电池的正负极性,切勿装反;
长期不用请将电池取出电池盒,以免造成腐蚀;
由于小车行动比较灵活,速度比较快,在使用时一定要注意保持场地足够大,且保证不会对周围的物体造成伤害;
不要让小车长时间运行在堵转状态(堵转状态:由于小车所受阻力过大,造成小车电机加电但并不转动的现象),这样会造成很大的堵转电流,有可能会损坏小车的控制电路。
2 电路设计及程序设计
2.1 电路设计基础知识
(1) 二极管:英文是diode 。二极管的正、负二个端子(如图8) ;正端A 称为阳极, 负端K 称为阴极。电流只能从阳极向阴极方向移动。一些初学者容易产生这样一种错误认识:“半导体的一‘半’是一半的‘半’;面二极管也是只有一‘半’电流流动(这是错误的) ,所有二极管就是半导体 ”。其实二极管与半导体是完全不同的东西。我们只能说二极管是由半导体组成的器件。半导体无论那个方向都能流动电流。
二极管电子流动图
(2) 三极管:三极管在电子电路中组成震荡电路、放大电路。 ① 已知型号和管脚排列的三极管,可按下述方法来判断其性能好坏
(a) 测量极间电阻。将万用表置于R ×100或R ×1k 挡,按照红、黑表笔的六种不同接法进行测试。其中,发射结和集电结的正向电阻值比较低,其他四种接法测得的电阻值都很高,约为几百千欧至无穷大。但不管是低阻还是高阻,硅材料三极管的极间电阻要比锗材料三极管的极间电阻大得多。
(b) 三极管的穿透电流ICEO 的数值近似等于管子的倍数β
和集电
结的反向电流ICBO 的乘积。ICBO 随着环境温度的升高而增长很快,ICBO 的增加必然造成ICEO 的增大。而ICEO 的增大将直接影响管子工作的稳定性,所以在使用中应尽量选用ICEO 小的管子。
通过用万用表电阻直接测量三极管e -c 极之间的电阻方法,可间接估计ICEO 的大小,具体方法如下:
万用表电阻的量程一般选用R ×100或R ×1k 挡,对于PNP 管,黑表管接e 极,红表笔接c 极,对于NPN 型三极管,黑表笔接c 极,红表笔接e 极。要求测得的电阻越大越好。e -c 间的阻值越大,说明管子的ICEO 越小;反之,所测阻值越小,说明被测管的ICEO 越大。一般说来,中、小功率硅管、锗材料低频管,其阻值应分别在几百千欧、几十千欧及十几千欧以上,如果阻值很小或测试时万用表指针来回晃动,则表明ICEO 很大,管子的性能不稳定。
(c) 测量放大能力(β) 。目前有些型号的万用表具有测量三极管hFE 的刻度线及其测试插座,可以很方便地测量三极管的放大倍数。先将万用表功能开关拨至 挡,量程开关拨到ADJ 位置,把红、黑表笔短接,调整调零旋钮,使万用表指针指示为零,然后将量程开关拨到hFE 位置,并使两短接的表笔分开,把被测三极管插入测试插座,即可从hFE 刻度线上读出管子的放大倍数。
另外:有此型号的中、小功率三极管,生产厂家直接在其管壳顶部标示出不同色点来表明管子的放大倍数β值,其颜色和β值的对应关系如表所示,但要注意,各厂家所用色标并不一定完全相同。
② 检测判别电极
(a) 判定基极。用万用表R ×100或R ×1k 挡测量三极管三个电极中每两个极之间的正、反向电阻值。当用第一根表笔接某一电极,而第二表笔先后接触另外两个电极均测得低阻值时,则第一根表笔所接的那个电极即为基极b 。这时,要注意万用表表笔的极性,如果红表笔接的是基极b 。黑表笔分别接在其他两极时,测得的阻值都较小,则可判定被测三极管为PNP 型管;如果黑表笔接的是基极b ,红表笔分别接触其他两极时,测得的阻值较小,则被测三极管为NPN 型管。
(b) 判定集电极c 和发射极e 。(以PNP 为例) 将万用表置于R ×100或R ×1k 挡,红表笔基极b ,用黑表笔分别接触另外两个管脚时,所测得的两个电阻值会是一个大一些,一个小一些。在阻值小的一次测量中,黑表笔所接管脚为集电极;在阻值较大的一次测量中,黑表笔所接管脚为发射极。
③ 判别高频管与低频管
高频管的截止频率大于3MHz ,而低频管的截止频率则小于3MHz ,一般情况下,二者是不能互换的。
④ 在路电压检测判断法
在实际应用中、小功率三极管多直接焊接在印刷电路板上,由于元件的安装密度大,拆卸比较麻烦,所以在检测时常常通过用万用表直流电压挡,去测量被测三极管各引脚的电压值,来推断其工作是否正常,进而判断其好坏。
2.2 电路方框图及说明
系统原理框图如图1所示。主控元件采用凌阳SPCE061A 单片机,属于凌阳u ’nSP. 系列产品的一个16位结构的微控制器。在存储器资源方面考虑到用户的较少资源的需求以及便于程序调试等功能,SPCE061A 里只内嵌32K 字的闪存(FLASH ),但用在此系统上已经绰绰有余。较高的处理速度使u ’nSP. 能够非常容易地、快速地处理复杂的数字信号。因此以u ’nSP. 为核心的SPCE061A 微控制器也适用在数字语音识别应用领域。SPCE061A 在2.6V ~3.6V 工作电压范围内的工作速度范围为0.32MHz ~49.152MHz ,较高的工作速度使其应用领域更加拓宽。2K 字SRAM 和32K 字FLASH 仅占一页存储空间,32位可编程的多功能I/O端口;两个16位定时器/计数器;32768Hz 实时时钟;低电压复位/监测功能;8通道10位模-数转换输入功能并具有内置自动增益控制功能的麦克风输入方式;双通道10位DAC 方式的音频输出功能,这就为本系统的特定人辨识和语音播报打下了基础。
2.3 各部分电路设计
2.3.1 电机的选择
市场上的电机种类很多,有各自的优缺点。电机类别如表2:
小车控制分为:前进、倒退、左转、右转和停止。如果考虑用单向电机来控制,将不能使电机进行反方向转动,也就不能实现自动左转、右转。再考虑到经济,实惠,决定用直流伺服电动机。
2.3.2 继电器驱动电路的设计
由于单片机I/O口提供的电流太小,不能直接驱动继电器工作。在这里采用8050NPN 管来提供一个开关电压,实现I/O口对继电器的驱动;用IN4007去掉继电器断开时线圈产生的反向电流,保护8050NPN 管不被损坏。继电器驱动电路如下图所示。
继电器驱动电路
2.3.3 行驶状态控制电路设计
如图13所示为行使状态控制电路,整个小车的行驶状态由两个电机MOTOR A和MOTOR B来控制;MOTOR A控制小车的左边两个轮子,MOTOR B控制小车右边两个轮子。具体控制如表4所示
行驶状态控制电路
表4 行驶状态控制表
基于单片机的语音识别系统
注:图中的两个电机完全相同,这样能更好地保持小车的稳定性,在前进上两个电机能在加减速度上完全达到同步,不会走S 路线,如果考虑用一个电机控制转向,而另外一个控制速度和返回的话,由于控制转向的电机电路未接入分压电阻,当速度不处于最快速度时,小车前进不能走直线,而是向一边偏,导致路线不对。
2.3.4 麦克录音输入及AGC 电路
麦克风电路如图16所示。凌阳的SPCE061A 是16位单片机,具有DSP 功能,有很强的信息处理能力,最高时钟可达到49M ,具备运算速度高的优势等等,这为语音的播放、录放、合成及辨识提供了条件。本系统接入MIC 电路如下图所示,MIC 为录制语音辨识命令服务。
麦克录音输入及AGC 电路
下图是MIC 录放流程图。
MIC 录放流程图
下图是简化的语音识别原理图,其中实线部分成为训练模块,虚线部分为识别模块。辨认特定的使用者即特定语者(Speaker Dependent ,SD) 模式,使用者可针对特定语者辨认词汇(可由使用者自行定义,如人名声控拨号) ,即在启动小车前,系统将会提示输入语音命令作简单快速的训练纪录,在这里输入“启动”“停止”“返回”和“模式切换”四个语音命令,通过使用者的声音特性来加以辨认。随着技术的成熟,进入语音适应阶段SA(speaker adaptation),使用者只要对于语音辨识核心,经过一段时间的口音训练后,即可拥有不错的辨识率。
2.3.5 语音播报电路
音频部分的原理图如下所示,在下图中可以看到两个跳线,其作用在于可以测量DAC 的输出波形;另外拔掉跳线,可以断开DAC 到喇
叭放大的通路,使得DAC 通道处于开路状态。这样便于用DAC 做其他用途,用户可以用过这个跳线来加入自己的外围电路。
音频原理及放大电路图
凌阳音频压缩算法根据不同的压缩比分为以下几种: SACM-A2000:压缩比为8:1,8:1.25,8:1.5 SACM-S480: 压缩比为80:3,80:4.5 SACM-S240: 压缩比为80:1.5 按音质排序:A2000>S480>S240
用凌阳Compress Tool事先把所需要的语音信号录制好,本系统共包括十多个语音资源,整个语音信号经凌阳SACM_S480压缩算法压缩只占有13.2K 存储空间,SPCE061A 单片机具有32k 闪存,使用内部flash 即可满足要求。凌阳SPCE061A 单片机自带双通道DAC 音频输出, DAC1、DAC2转换输出的模拟量电流信号分别通过AUD1和AUD2管脚输出, DAC输出为电流型输出,所以DAC 输出经过SPY0030音频放大,以驱动喇叭放音,放大电路如图19(只列出了DAC1,DAC2类似) ,这为单片机的音频设计提供了极大方便。在它们后面接一个简单的音频放大电路和喇叭即可实现语音播报功能,音频的具体功能主要通过程序来实现。
3 软件设计
软件设计部分是小车控制的的核心,通过软件编程来控制小车的行驶状态。
3.1 软件流程图及设计思路说明
软件流程图
3.1.1 程序设计
主程序见附录(1)
3.2 模块设计
3.2.1 中断流程图部分
SPCE061单片机有两个外部中断,分别为EXT1和EXT2,两个外部输入脚分别为B 口的IOB2和IOB3的复用脚。EXT1(IOB2)和EXT2(IOB3)两条外部中断请求输入线,用于输入两个外部中断源的中断请求信号,并允许外部中断以负跳沿触发方式来输入中断请求信号。
EXT1(IOB2)为黑线检测,确定小车位置,EXT2(IOB3)为轮子转数检测用于计算路程。IRQ4用做整个行程的时间计数。
中断服务流程图
3.2.2 语音识别部分
在这里我们用的是SPCE061的特定语者辨识SD (Speaker Dependent ),SD 即语音样板由单个人训练,也只能识别训练某人的语音命令,而他人的命令识别率较低或几乎不能识别。
(1) 语音的准备:
可利用计算机进行录音,选择录音效果一般的MIC 比较好,因为小车跑动时要受环境的影响,效果一般的MIC 录制的音更加接近凌阳单片机上的MIC 所录制的。录制语音可为:“yeah ”,“烦不烦”,“前进”,“倒退”,“拐就拐”。分别保存名称为:yeah.48k 、qj.48k 、dt.48k zg.48k、yg.48k.
语音录制时,注意录制属性设置,最好选择为8Khz, 16位,单声道。语音录制好后,保存格式为“.wav ”,利用凌阳单片机光盘内目录“\TOOLS\s480\”下的工具进行语音压缩后放在程序目录“\voice”下边,然后修改配置文件“Makefile ”中的OBJFILES 的值以及对应的语音文件的目录地址值和“clean ”的值 ,并且配置值顺序必须对应于语音训练的过程。
该程序模块包括三部分:训练样本、识别、语音提示。具体程序见主程序。见下图整体框图。
语音辨识整体框图
在程序中我们通过五条语句的训练演示特定人连续音识别,其中第一条语句为触发名称。另外四条为命令,训练完毕开始辨识当识别出触发名称后,开始发布命令,则会听到自己设置的应答,具体流程
图如图22。
(2) 关于语音识别库函数的算法分析:
众所周知,嵌入式语音识别最大难点在于如何在硬件资源相对有限(相对与PC 机而言)的情况下,实现大量数据处理的语音识别算法。特别的,SPCE061A 自带2K 字的RAM ,这样小容量的RAM 空间是如何存储数据量较大的语音命令,是值得探讨的问题。
时域分析中,语音信号作为缓慢时变的信号,在一小段时间里,例如10ms ~20ms ,语音信号的特性基本不变,这些短段具有固定特性,短段间经常有一定的重叠,组合成一段语音,我们把语音信号分成这样的小段(称为“帧”) 作为提取语音信号特性的单元,这样的方法称为“短时”处理法。
当以8K/S的速率采集语音信号时,假设以20ms 为帧周期,加上12ms 的帧移,帧长32ms, 即每帧包括256个语音采集点,一个帧的特性参数占用1个字RAM ,则存储一条2S 长的语音命令信号占用
2s/20ms*1=100字,与直接存储采样的语音数据相比更能节省嵌入式系统有限的硬件资源。 在外界噪音的干扰下,对语音起止点的判别非常重要,若声音指令信号提取的不恰当,那么所得到的声音指令信号和我们发出的指令信号就会有很大的出入,不但会延迟语音识别的时效性,甚至会降低对
这些语音信号的识别率。对语音信号的提取,主要是确定音头和音尾的位置,即端点识别。常用的方法有短时能量和过零率等几种。
短时能量表示了语音信号的幅度,其定义式为:
E =
n 2
*n n =1(公式3)
语音辨识具体流程图
短时平均过零率为一帧语音信号穿越零电平的次数,表示了短时信号的频率,其定义如下:
z =0. 5/N *∑|Sgn [x (n )]-Sgn [x (n -1)]|两式中的N 为一帧语音的采集点数。
(公式4)
语音采集过程中,计算当前一帧或多帧数据的能量或过零率数值,当大于预先设定的阈值时,即认为找到了语音命令的起始点,结束点的确定方法类似。
在截取音头音尾间的信号并分帧后,我们就可以以帧为单位进行特征参数的提取,如线性预测倒谱系数法。选择合适的特征参数,与语音样板参数通过动态时间弯折算法匹配,即可得出相应的识别结果。
4 连接和操作说明
4.1 硬件模块连接图
连线图
4.1.1 功能说明
1. 小车运动控制:
通过SPCE061A 的I/O端口,驱动控制板的H 桥电路,进而控制前
轮电机和后轮电机。
2. 声控功能:
利用特定人语音识别实现小车的名称和动作训练,并根据相应的语音指令输入执行前进、后退、左转、右转、停车等动作。
3. 定时控制功能:
利用时基定时器设定运行时间,小车运行同时启动定时器,时间到小车停止运行。
4.1.2 代码下载
硬件连接完成之后,检查无误,接下来就可以下载程序了。具体的步骤为:
第一步:打开集成开发环境,打开“CarDemo.spj”文件,编译链接。(注意:如果看不到CarDemo.spj ,请在弹出的对话框中选择打开类型为spj 或者所有文件)
第二步:点击菜单Project ->Select Body
,或者直接点击图标打开如图 3-2所示的对话框:
图 7-3 Select Body对话框
第三步:在弹出的对话框中选择Body Name为SPCE060A_061A,选择Probe 为Auto ,点击OK 按钮确定。
第四步:点击IDE 工具栏上的图标
选择Use ICE模式。
第五步:按F8快捷下载按钮,下载代码。
4.1.3 训练小车
成功下载程序以后,去掉下载线并复位系统(如果使用EZ-Probe 还应将Probe 选择跳线S5拔去),小车就会提示对它进行训练。训练采用应答式训练,每条指令的训练次数为两次,每一条命令的训练过程都是一样的,以“前进”为例说明:
步骤一:小车提示“前进”;
步骤二:告诉小车“前进”;
步骤三:小车提示“请再说一遍”(重复训练提示音);
步骤四:再次告诉小车“前进”(重复训练一次)。
这是一个完整的训练过程,如果训练成功,小车会自动进入下一条指令的训练,并会提示下一条指令对应的动作;如果没有训练成功,小车会提示“说什么暗语呀”或者“没有听到任何声音”等信息,这样的话就要重复刚才所说的四个步骤,直到成功为止。
整个的训练过程共有5次这样的训练,依次为:名称——前进——后退——左拐
——右拐。整个的训练流程如下图所示:
小车训练流程图
4.1.4 声控小车
训练完小车之后,怎样进行声控操作,让小车运动或者停下来呢?
可以直接对小车说前进,或者倒车、左拐、右拐等,小车如果识别出指令会有一个回应信号,告知你它要执行的动作,然后执行该动作。如果想要小车执行其它动作,直接告诉小车将要执行动作对应的指令即可。比如在前进时告诉小车“倒车”,小车识别出之后就会直接倒车。
如果在小车训练过程中想要小车停下来,可以直接呼叫小车的名字,小车准确识别之后就会停下来。
4.1.5 重新训练
在实际的使用过程当中,可能会对训练的结果不满意,或者其他
人也想对它进行训练、控制。这样就要求小车可以被重新训练。为此,我们把61板的KEY3键定义为重新训练按钮,系统运行之后就会不断的扫描61板的KEY3键。如果检测到KEY3键按下,那么程序首先会把训练标志位(0xe000)单元擦除,并会进入一个死循环等待复位的到来。复位到来之后,程序检测到训练标志单元内容为0xffff ,认为小车没有经过训练,就会要求对它进行训练。
总结
本设计综合应用了SPCE061A 丰富的软硬件资源,成功的实现了语音控制功能。下面简单的介绍一下实际应用中的一些资源优势:在硬件方面,较高的执行速度、内置的硬件乘法器、ADC 和DAC 功能、内置的AGC 自动增益环节,这些为语音处理提供了强大基础。在软件方面,标准的C 语言编程,丰富的语音资源函数为编程提供了很大的方便。
该设计方案结构简单,以单芯片实现了语音播放与识别以及电机控制功能,相当于“语音识别芯片+普通单片机”的功能。但是比“语音识别芯片+普通单片机”方案实现起来要简单很多,而且成本也会降低很多。
该语音控制小车操作比较简单,训练和识别成功的几率也比较高,是一个典型的语音识别应用方案。
最后敬请各位专家、老师和同学对论文和今后的研究工作提出宝贵的指导意见和建议。
致谢
参考文献
[1] 罗亚飞. 凌阳16位单片机应用基础[M]. 北京航空航天出版社.
[2] 张彦斌, 薛钧义. 凌阳16位单片机原理及应用[M]. 清华大学出版社
[3] 赵亮. 单片机应用系统设计与产品开发[M]. 人民邮电出版社
[4] 耿德根 詹卫前, 李青. 单片机创新开发与机器人制作[M]. 北京航天航天大学
[5] David Cook 毕树生. 机器人制作提高篇[M].北京航空航天大学出版社
[6] 凌阳大学计划网www.unsp.com.cn
附件1 系统程序说明
主控制源程序:
//===================================================== // 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 (volatile unsigned 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 *)0x700C #define P_TimerB_Ctrl (volatile unsigned int *)0x700D #define P_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 int uiTimeset = 3;//运行时间定时,调整该参数控制运行时间 unsigned int uiTimecont; //运行时间计时
//===================================================== // 语法格式: void Delay();
// 实现功能: 延时
// 参数: 无
// 返回值: 无
//===================================================== void Delay()
{
unsigned int i;
for(i=0;i
{
*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)
{
case -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();
// 实现功能: 存储语音模型函数
// 参数: 无
// 返回值: 无
//===================================================== void 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
g_Ret=BSR_ExportSDWord(commandID);
while(g_Ret!=0) //模型导出成功?
g_Ret=BSR_ExportSDWord(commandID);
for(i=0;i
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
{
for(k=0;k
{
Ret=*p;
BSR_SDModel[k]=Ret; //装载语音模型 p+=1;
}
g_Ret=BSR_ImportSDWord();
while(g_Ret!=0) //模型装载成功?
g_Ret=BSR_ImportSDWord(); }
}
//===================================================== // 语法格式: 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");
uiTimecont = 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) //有语音触发? {
*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);
// 实现功能: 主函数
// 参数: 无
// 返回值: 无
//===================================================== 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); //初始化存储器RAM
BS_Flag=*(unsigned int *)0xe000; //读存储单元0xe000
if(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);