基于 STM32 的智能婴儿车:语音识别报警监控系统的设计与实现

语音识别模块的开发

0 简介

大家好,我是丹程学长,今天给大家介绍一个单片机项目

基于stm32的智能婴儿车和婴儿床

你可以用它来做课程设计或者毕业设计

单片机-嵌入式毕业论文题目列表及项目分享:

1 项目目标

本项目最终实现的功能为:当用户说出指定语音时,硬件系统(由STM32和LD3320组成)能够识别并在液晶屏上显示,同时触发预设的报警电路(由蜂鸣器和LED灯组成)。并开发了相应的上位机(运行在PC机上),上位机可以显示硬件系统的状态,也可以控制硬件系统的状态。

2 项目背景及意义

首先,我们研发的语音识别报警监控系统可以解放工厂工人的双手,让他们通过说话就可以控制设备,更加方便、快捷。

其次,当现场工作人员忙于操作设备,无法腾出手来发出警报,或者距离报警系统较远,无法手动发出警报时,可以使用语音识别系统发出警报。

最后我们还开发了上位机,使得工作人员无需呆在工业现场就可以在办公室查看当前设备的报警状态,还可以通过上位机发出特定的报警。

3 需求分析3.1 功能需求

语音识别系统能够读取不同报警类型的语音并以波形显示出来;利用单片机对不同报警类型的语音进行匹配识别,根据识别结果输出声音报警、光指示报警,要求误报率小于10%;对语音进行预处理,提取语音信号的特征参数;通过STM32单片机编写控制程序;实现上位机的开发,完成嵌入式系统与上位机的交互。

3.2 非功能性需求

考虑相关的社会、健康、安全、法律和环境等约束条件;讨论、分析或预测本项目所采用或涉及的相关新技术或新产品、新工艺对本项目的积极意义和对社会、安全、健康、法律和文化等可能产生的积极和消极影响。提供两种设计方案并进行论证。

4 设备 4.1 STM32 MCU

具体型号为STM32F103,其开发所用的语言为C语言,编译器为keil5。

4.2 LD3320语音识别芯片

LD3320是一款非特定人语音识别芯片,芯片内部集成了语音识别处理器和一些信号调制电路,具有高性能的A/D转换器、D/A转换器、麦克风音频信号输入接口、音频解码输出接口等。用户只需要用软件编辑需要识别的关键词列表即可,LD3320最多可以支持50个关键词和短语,这些列表以字符的形式传输到芯片中,对需要识别的语音信号进行相似度分析,识别完成后输出结果。

4.3 TFT-LCD显示屏

TFT-LCD,即薄膜场效应晶体管,是一种有源矩阵液晶显示器(AM-LCD)。

5 设计

语音识别报警监控系统主要由STM32单片机、LD3320语音识别模块、报警电路模块和上位机模块组成。

将LD3320语音识别芯片和自己设计的报警电路连接到STM32单片机上,编写STM32单片机程序处理输入的语音信号,触发相应的报警电路,编程语言为C语言,编程软件为KEIL5。LD3320采集语音,STM32单片机对识别结果进行逻辑判断,使输出端口产生相应的输出信号。由显示屏、LED灯、蜂鸣器组成的报警电路模块用于显示报警效果。上位机软件采用C#语言编写,安装在PC机上,上位机通过串口与下位机(STM32单片机)通讯。

6 语音识别模块开发

硬件方面,语音识别芯片LD3320与微控制器STM32连接。

具体端口连接:LD3320的MISO端口连接到STM32的PA6端口,MOSI端口连接到PA7端口,SCK端口连接到PA5端口,NSS端口连接到PA4端口,RST端口连接到PB15端口,WR端口连接到PB13端口,IRQ端口连接到PB12端口,NC端口悬空。

软件方面,通过编写STM32的C语言程序来处理语音信号。

语音识别的操作顺序为:语音识别的初始化(包括通用的初始化)→写入识别列表→开始识别,准备中断响应函数,打开中断使能位。

这里要注意的是,如果不使用中断模式,也可以使用查询模式。“开始识别”后,读取寄存器B2H的值,如果是21H,则表示产生了识别结果。之后读取候选项等操作与中断模式相同。

首先进行通用初始化,然后进行语音识别的初始化,接着编写识别列表。列表的规则是每个识别条目对应一个特定的数字(1字节),不同识别条目的数字可以相同,不必连续。芯片最多支持50个识别条目,每个识别条目都是标准的普通话拼音(小写),每两个字符之间有一个空格(中文拼音)。我们添加了四个关键字,分别是“全开”、“全关”、“闪光”、“流光”,这些关键字仅供我们测试使用,在实际现场可以根据实际情况添加、删除、修改关键字。

接下来就是开始识别了。代码中用变量nAsrStatus来表示主程序中程序运行的状态,有几种状态:LD_ASR_NONE表示没有进行ASR识别,LD_ASR_RUNING表示LD3320正在进行ASR识别,LD_ASR_FOUNDOK表示识别过程完成后有识别结果,LD_ASR_FOUNDZERO表示识别过程完成后没有识别结果,LD_ASR_ERROR表示识别过程中LD3320芯片内部出现不正确的状态。编程时,该状态的设置要放在LD3320芯片正式开始识别之前。在ASR识别过程完成后,得到ASR识别结果,通过C语言的switch语句匹配语音识别的结果,从而触发相应的报警电路代码、上位机代码等。

然后当有声音输入时,无论是否识别出正常结果,都会产生中断。中断程序会根据寄存器的值来分析结果。通过读取BA寄存器的值,可以知道有多少个候选答案,而C5寄存器中的答案就是得分最高、最有可能正确的答案。例如,如果发音是“全亮”,并且成功识别(没有其他候选),那么BA寄存器中的值为1,C5寄存器中的值为对应代码3。

7 报警电路模块开发

报警电路模块主要由一个LCD-TFT、两个LED灯和一个蜂鸣器组成,LED灯和蜂鸣器是STM32单片机直接使用,无需外部连接。对于LCD-TFT,是与STM32单片机相连的,硬件连接图如下:

通过对STM32进行编程,可以控制报警显示的效果。将不同状态对应的报警显示效果分别封装成函数,经过语音识别后选择执行相应的函数,从而触发相应的报警显示效果。预设在“全亮”状态下,两个LED灯都亮,LCD显示“当前状态:全亮”;在“全灭”状态下,两个LED灯都灭,LCD显示“当前状态:全灭”;在“闪”和“报警”状态下,两个LED灯都闪,蜂鸣器响,LCD显示“当前状态:闪动”;在“先闪”状态下,一个LED灯闪,一个LED灯灭,LCD显示“当前状态:先闪”。

通过控制相应引脚的高低电平可以实现LED灯的亮灭,蜂鸣器也是一样。对于LCD显示内容的控制,使用取模工具输入需要的字符,如汉字、数字、字母等,工具会直接生成C语言代码,然后通过LCD_ShowString()、LCD_ShowChinese()两个函数控制LCD显示的内容。

8 上位机模块开发

开发工具为VS,语言为C#。

首先,创建一个新项目,并选择Visual C#语言下的Windows Forms Application。

然后设置窗体的组件,工具箱里有各种组件,如果要使用,可以将需要的组件拖拽到窗体中,根据期望的功能设置窗体,最终的窗体界面如下:

本窗体中预设了两个下拉框用于设置端口和波特率,一个开关用于接通和断开上位机与单片机的通讯,一个文本框用于显示当前的状态,一个文本框用于显示历史接收的数据,一个下拉框用于选择用户希望单片机呈现的状态,一个按钮用于将用户选择的状态信息传送到单片机的一端,从而达到对上位机的控制效果。

private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 20; i++)
            {
                try
                {
                    string str = "COM" + i;
                    serialPort1.PortName = str;
                    serialPort1.Open();
                    comboBox1.Items.Add(str);
                    serialPort1.Close();
                    comboBox1.Text = str;
                }
                catch { }
            }
            comboBox1.Text = "COM3";
            comboBox2.Text = "115200";
        }

以上代码用于自动设置上位机端口号,从而实现上位机与单片机的连接。如果已知端口和波特率,也可以直接将comboBox1.Text设置为已知的端口号,将comboBox2.Text设置为已知的波特率。

private void button1_Click(object sender, EventArgs e)
        {
            if(Button_State)
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text, 10);
                    serialPort1.Open();
                    button1.Text = "断开";
                    Button_State = false;
                }
                catch (Exception)
                {
                    if (serialPort1.IsOpen)
                        serialPort1.Close();
                    MessageBox.Show("端口打开失败,请检查端口", "错误");
                }
            }
            else
            {
                serialPort1.Close();
                button1.Text = "连接";
                Button_State = true;
            }
        }

以上代码是点击“断开/连接”按钮触发的功能代码,变量Button_State用于表示上位机与单片机当前是否连接,根据连接状态通过if语句执行相应代码,函数serialPort1.Close()用于断开连接,serialPort1.PortName用于设置端口号,serialPort1.BaudRate用于设置波特率,serialPort1.Open()用于打开连接。

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            textBox2.Text=serialPort1.ReadExisting();
            if (textBox2.Text.Contains("LCD"))
                textBox2.Text = " ";
            textBox1.AppendText(textBox2.Text);
            if (textBox2.Text.Contains("流")) 
                textBox3.Text = "流水灯";
            else if (textBox2.Text.Contains("闪"))
                textBox3.Text = "闪烁";
            else if (textBox2.Text.Contains("第"))
                textBox3.Text = "第一个";
            else if (textBox2.Text.Contains("灭"))
                textBox3.Text = "全灭";
            else if (textBox2.Text.Contains("亮"))
                textBox3.Text = "全亮";
        }

以上代码用于显示单片机当前的状态,当单片机通过中断向上位机发送数据时,会执行上述代码。在单片机程序中,向上位机发送数据的代码为printf(),在上位机程序中,可以使用textBox2.Text获取发送的数据。Contain()函数表示是否包含某个字符。通过设置textBox3.Text,将当前状态显示在窗体中。

9 项目成果

单片机-嵌入式毕业论文题目列表及项目分享:

9. 最后

单片机

AVR 单片机编程软件(AVR fighter):免费好用的烧录工具

2024-6-4 23:03:45

单片机

省时省力省收益的购彩软件,提供多种玩法和优质服务

2024-6-5 0:05:16

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索