赞
踩
随着技术的不断更新, 语音识别和自动控制的发展将是未来不可避免的趋势。比较更为人性化方面的人机交互的方法是语音交互, LD3320芯片能够对语音识别技术收集以及收集识别语音信息,采用了STC10L08XE芯片当作主控制器并且用此芯片当作语音管理系统,继而将外部存储和控制电路结合起来用于语音识别和控制。
在该文中,通过系统设计以及可行性实验测试的方式,对基于STM32设计的语音识别系统进行探究,通过LD3320芯片实现对语音的转换,进而达到语音识别控制的效果。一般而言,操作者发出相应的系统语言辨别命令,系统收到指令后在内部进行分析、查找, 产生响应控制信号, 从而控制蜂鸣器和LED灯的开关,并且通过语音模块,显示当前时间于 OLED屏。经过试验, 该项目可以完成预期设计的功能, 可决定电路板上LED灯的开关、蜂鸣器的开关、时间的显示。
在该文整体结构叙述中,主要对该语音识别系统的整体设计流程进行具体的叙述,通过采用LD3320芯片技术实现对智能语音识别系统的设计,进而促进我国智能家居控制系统的发展,并对系统的可行性进行相应的测试,进而结合影响系统的相关因素并且根据具体的要求提出了本文的解决方案。
对于语音识别系统而言,主要通过语言识别实现人与机器之间的沟通交流。从下图中可以得知,对于人机交互系统而言,该系统结构主要涉及4部分组成结构:分别为用户目标的设置、输入以及输出模块、对语音信号进行处理的模块以及系统这四部分内容,根据语音信号实现相应的操作执行。
根据芯片LD3320实现对语言识别系统的设计,其具体结构框架从下图可以得知。在该语音识别系统中,主要涉及四部分器件结构:分别是显示屏、语言模块、控制模块以及蜂鸣器等。通过语言识别系统实现对语言的采集识别,并将其输入语音模块、控制模块对语音进行进一步的处理以及识别,最后将识别结果送至主模块,然后主模块识别结果后,利用控制模块达到最终控制的结果。外部存储中的数据在设备运行过程中实时更改,使用写入的主机计算机通过串行端口向主模块发送数据,从而将数据导出到外部存储。
图2.12语音识别系统框架图
在该语言识别系统中,主要选择LD3320芯片作为该系统的控制模块,涉及多方面功能,包括语言指令、语言的收集识别以及处理等,实现了通过语言对系统的控制功能。
本文依靠的课题是语音识别控制系统这一部分,目的是实现语音识别控制,具体需要实现以下功能:
(1)通过识别模块控制LED灯开关,蜂鸣器开关
(2)时间显示,通过语音模块,显示当前时间于OLED屏(平时处于低功耗状态)
对于LD3320芯片而言,其作为整个语言识别系统的中心模块,主要包括MCU芯片以及单片机,主要对芯片寄存器进行相应的控制。
同时,对于该芯片而言,其涉及的功能需要进行相应的测试,只有完成相应的测试,才能符合系统要求。
对于LD3320芯片寄存器而言,主要涉及两种类型:一种是模拟电路、声音控制等二级寄存器;另外一种便是串行以及并行寄存器等,能够对八位地址范围进行相应的读取,范围在00H和FFH之间。
在该语音识别系统的设计中,选择STC10L08XE单片机进行设计,并通过内置内存MCU以及LD3320芯片实现系统的语音识别功能。
在该语音识别系统的整体结构中,其硬件系统的设计主要包括两部分内容,一种是语言识别模块设计,另外一种便是主控制器设计,通过这两部分内容的设计实现对语音的识别,并将识别采集的语言传送至LD3320芯片中进行进一步处理,并将结果传送至主控制模块中,其结果主要通过外部储存模块进行储存回放。另外,通过对模块电压、输入以及输出模块的设计,实现了系统的语音播放的功能。
在该语言识别系统中,对于单片机的选择,主要选择STC10L08XE芯片进行设计,STC10L08XE芯片的机器周期为1T, SRAM为512K,片内RAM为8 K; 指令码相容于传统的8051单晶片,相较于传统的EEP-ROM[5]功能,可提升8051 MCU的速度高达8-12倍, 具有两个定时器,对于MCU而言,其电压处于2.4伏至3.6伏的范围内。
对于主控制器而言,主要用于对设备交换机进行相应的控制,主要处理来自LD3320芯片标识的语音数据,并在最终主控制器分析和识别结果时与外部存储模块进行语音交互,从而将控制命令发送给控制块。
对于LD3320芯片而言,其在语音识别系统的设计中处于十分重要的地位,能够结合主控芯片实现4类读写模式:基于软件的串行SPI读取和基于硬件的串行SPI读取、并行软件模拟。
芯片内部的简单逻辑图如图3.5所示,通过对每个脚的定义,我们可以更加直观地了解一些主要问题。例如,芯片操控的电压范围:高压(逻辑为1) 0.7*VDDIO,低压(逻辑为“0”):0-0.3 * VDDIO。因此,芯片的电压必须保持在3.3v才能运行,而且LD3320芯片要求低于3.3v.
图3.8 芯片内部逻辑图
图4.8 仿真图
附录1.1主程序 #include "delay.h" #include "sys.h" #include "oled.h" #include "bmp.h" #include "usart.h" #include "RTC_Time.h" unsigned char num; u8 flag_time; int main(void) { u8 hour_z,hour_x; u8 min_z,min_x; u8 sec_z,sec_x; delay_init(); OLED_Init(); OLED_ColorTurn(0); OLED_DisplayTurn(0); OLED_Refresh(); uart_init(9600); RTC_Init(); //RTC初始化 while(1) { if(flag_time==1) { OLED_ShowChinese(0,0,0,16); OLED_ShowChinese(16,0,1,16); OLED_ShowChinese(32,0,2,16); OLED_ShowChinese(48,0,3,16); hour_z=calendar.hour/10+'0'; hour_x=calendar.hour%10+'0'; min_z=calendar.min/10+'0'; min_x=calendar.min%10+'0'; sec_z=calendar.sec/10+'0'; sec_x=calendar.sec%10+'0'; OLED_ShowChar(32,48,hour_z,16);//显示ASCII字符 OLED_ShowChar(40,48,hour_x,16);//显示ASCII字符 OLED_ShowChar(48,48,':',16);//显示ASCII字符 OLED_ShowChar(56,48,min_z,16);//显示ASCII字符 OLED_ShowChar(64,48,min_x,16);//显示ASCII字符 OLED_ShowChar(72,48,':',16);//显示ASCII字符 OLED_ShowChar(80,48,sec_z,16);//显示ASCII字符 OLED_ShowChar(88,48,sec_x,16);//显示ASCII字符 OLED_Refresh(); delay_ms(1000); } else if(flag_time==2) { OLED_Clear(); } else {} } } 附录1.2 OLED程序 #include "oled.h" #include "stdlib.h" #include "oledfont.h" #include "delay.h" u8 OLED_GRAM[144][8]; //反显函数 void OLED_ColorTurn(u8 i) { if(i==0) { OLED_WR_Byte(0xA6,OLED_CMD);//正常显示 } if(i==1) { OLED_WR_Byte(0xA7,OLED_CMD);//反色显示 } } //屏幕旋转180度 void OLED_DisplayTurn(u8 i) { if(i==0) { OLED_WR_Byte(0xC8,OLED_CMD);//正常显示 OLED_WR_Byte(0xA1,OLED_CMD); } if(i==1) { OLED_WR_Byte(0xC0,OLED_CMD);//反转显示 OLED_WR_Byte(0xA0,OLED_CMD); } } void OLED_WR_Byte(u8 dat,u8 cmd) { u8 i; if(cmd) OLED_DC_Set(); else OLED_DC_Clr(); OLED_CS_Clr(); for(i=0;i<8;i++) { OLED_SCLK_Clr(); if(dat&0x80) OLED_SDIN_Set(); else OLED_SDIN_Clr(); OLED_SCLK_Set(); dat<<=1; } OLED_CS_Set(); OLED_DC_Set(); } //开启OLED显示 void OLED_DisPlay_On(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵 OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕 } //关闭OLED显示 void OLED_DisPlay_Off(void) { OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能 OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵 OLED_WR_Byte(0xAF,OLED_CMD);//关闭屏幕 } //更新显存到OLED void OLED_Refresh(void) { u8 i,n; for(i=0;i<8;i++) { OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址 OLED_WR_Byte(0x00,OLED_CMD); //设置低列起始地址 OLED_WR_Byte(0x10,OLED_CMD); //设置高列起始地址 for(n=0;n<128;n++) OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); } } //清屏函数 void OLED_Clear(void) { u8 i,n; for(i=0;i<8;i++) { for(n=0;n<128;n++) { OLED_GRAM[n][i]=0;//清除所有数据 } } OLED_Refresh();//更新显示 } //画点 //x:0~127 //y:0~63 void OLED_DrawPoint(u8 x,u8 y) { u8 i,m,n; i=y/8; m=y%8; n=1<<m; OLED_GRAM[x][i]|=n; } //清除一个点 //x:0~127 //y:0~63 void OLED_ClearPoint(u8 x,u8 y) { u8 i,m,n; i=y/8; m=y%8; n=1<<m; OLED_GRAM[x][i]=~OLED_GRAM[x][i]; OLED_GRAM[x][i]|=n; OLED_GRAM[x][i]=~OLED_GRAM[x][i]; } //画线 //x:0~128 //y:0~64 void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2) { u8 i,k,k1,k2,y0; if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2))return; if(x1==x2) //画竖线 { for(i=0;i<(y2-y1);i++) { OLED_DrawPoint(x1,y1+i); } } else if(y1==y2) //画横线 { for(i=0;i<(x2-x1);i++) { OLED_DrawPoint(x1+i,y1); } } else //画斜线 { k1=y2-y1; k2=x2-x1; k=k1*10/k2; for(i=0;i<(x2-x1);i++) { OLED_DrawPoint(x1+i,y1+i*k/10); } } } //x,y:圆心坐标 //r:圆的半径 void OLED_DrawCircle(u8 x,u8 y,u8 r) { int a, b,num; a = 0; b = r; while(2 * b * b >= r * r) { OLED_DrawPoint(x + a, y - b); OLED_DrawPoint(x - a, y - b); OLED_DrawPoint(x - a, y + b); OLED_DrawPoint(x + a, y + b); OLED_DrawPoint(x + b, y + a); OLED_DrawPoint(x + b, y - a); OLED_DrawPoint(x - b, y - a); OLED_DrawPoint(x - b, y + a); a++; num = (a * a + b * b) - r*r;//计算画的点离圆心的距离 if(num > 0) { b--; a--; } } } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //size:选择字体 12/16/24 //取模方式 逐列式 void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1) { u8 i,m,temp,size2,chr1; u8 y0=y; size2=(size1/8+((size1%8)?1:0))*(size1/2); //得到字体一个字符对应点阵集所占的字节数 chr1=chr-' '; //计算偏移后的值 for(i=0;i<size2;i++) { if(size1==12) {temp=asc2_1206[chr1][i];} //调用1206字体 else if(size1==16) {temp=asc2_1608[chr1][i];} //调用1608字体 else if(size1==24) {temp=asc2_2412[chr1][i];} //调用2412字体 else return; for(m=0;m<8;m++) //写入数据 { if(temp&0x80)OLED_DrawPoint(x,y) elseOLED_ClearPoint(x,y); temp<<=1; y++; if((y-y0)==size1) { y=y0; x++; break; } } } } //显示字符串 //x,y:起点坐标 //size1:字体大小 //*chr:字符串起始地址 void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1) { while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符! { OLED_ShowChar(x,y,*chr,size1); x+=size1/2; if(x>128-size1) //换行 { x=0; y+=2; } chr++; } } //m^n u32 OLED_Pow(u8 m,u8 n) { u32 result=1; while(n--) { result*=m; } return result; } 显示2个数字 x,y :起点坐标 len :数字的位数 size:字体大小 void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1) { u8 t,temp; for(t=0;t<len;t++) { temp=(num/OLED_Pow(10,len-t-1))%10; if(temp==0) { OLED_ShowChar(x+(size1/2)*t,y,'0',size1); } else { OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1); } } } //显示汉字 //x,y:起点坐标 //num:汉字对应的序号 //取模方式 列行式 void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1) { u8 i,m,n=0,temp,chr1; u8 x0=x,y0=y; u8 size3=size1/8; while(size3--) { chr1=num*size1/8+n; n++; for(i=0;i<size1;i++) { if(size1==16) {temp=Hzk1[chr1][i];}//调用16*16字体 else if(size1==24) {temp=Hzk2[chr1][i];}//调用24*24字体 else if(size1==32) {temp=Hzk3[chr1][i];}//调用32*32字体 else if(size1==64) {temp=Hzk4[chr1][i];}//调用64*64字体 else return; for(m=0;m<8;m++) { if(temp&0x01)OLED_DrawPoint(x,y); else OLED_ClearPoint(x,y); temp>>=1; y++; } x++; if((x-x0)==size1) {x=x0;y0=y0+8;} y=y0; } } } //num 显示汉字的个数 //space 每一遍显示的间隔 void OLED_ScrollDisplay(u8 num,u8 space) { u8 i,n,t=0,m=0,r; while(1) { if(m==0) { (128,24,t,16); //写入一个汉字保存在OLED_GRAM[][]数组中 t++; } if(t==num) { for(r=0;r<16*space;r++) //显示间隔 { for(i=0;i<144;i++) { for(n=0;n<8;n++) { OLED_GRAM[i-1][n]=OLED_GRAM[i][n]; } } OLED_Refresh(); } t=0; } m++; if(m==16){m=0;} for(i=0;i<144;i++) //实现左移 { for(n=0;n<8;n++) { OLED_GRAM[i-1][n]=OLED_GRAM[i][n]; } } OLED_Refresh(); } } //配置写入数据的起始位置 void OLED_WR_BP(u8 x,u8 y) { OLED_WR_Byte(0xb0+y,OLED_CMD);//设置行起始地址 OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); OLED_WR_Byte((x&0x0f),OLED_CMD); } //x0,y0:起点坐标 //x1,y1:终点坐标 //BMP[]:要写入的图片数组 void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[]) { u32 j=0; u8 x=0,y=0; if(y%8==0)y=0; else y+=1; for(y=y0;y<y1;y++) { OLED_WR_BP(x0,y); for(x=x0;x<x1;x++) { OLED_WR_Byte(BMP[j],OLED_DATA); j++; } } } //OLED的初始化 void OLED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOD3,6 GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_4); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOD3,6 GPIO_SetBits(GPIOC,GPIO_Pin_13); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOD3,6 GPIO_SetBits(GPIOA,GPIO_Pin_11); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOD3,6 GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8); OLED_RST_Set(); delay_ms(100); OLED_RST_Clr();//复位 delay_ms(200); OLED_RST_Set(); OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel OLED_WR_Byte(0x00,OLED_CMD);//---set low column address OLED_WR_Byte(0x10,OLED_CMD);//---set high column address OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD);//-not offset OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1
在本文中,主要采用LD3320芯片实现对智能语音识别系统的设计,同时,随着软件系统以及硬件平台等相关技术的不断发展,为语音识别系统的设计提供了较多的可能性,丰富了其功能,增强了其优势特点,在一定程度上降低了其故障的发生率,全面的提高了该系统的性能和优势。同时,该系统丰富的功能为客户的需求提供了更多的可能性以及便捷性,促进了该语音识别系统的应用推广。另外,对系统的可行性进行相应的测试分析,通过测试,该系统能够满足用户较多的需求,具有较强的识别功能,操作简单便捷,具有较强的可行性。
在该文中,通过对语音识别系统的检测和分析,可能需要对识别性能和硬件大小进行以下改进:
1、首先是在抗噪和抗干扰方面,本文在低信噪比环境中提高了降噪性能,但仍不能很好地识别该特性,所以需要加大对校正识别算法的研究或增加相应的降噪设备,便于该系统的运行;
2.对于该系统的用户交互系统的设计,主要通过串口助手实现对指令的修改操作,这在一定程度上降低了系统的便捷性以及直观性,因此,需要加强对系统窗口以及封装等界面的设计研发,提高系统的便捷性以及直观性,便于语言的识别和处理。
3、同时,对于该系统硬件而言,需增加一定数量的引脚以及接口,以便访问其他设备,还必须根据特定的规格和大小设计和改进硬件输出面板,以确保系统性能良好。
目录
第一章 绪论 1
1.1研究背景及意义 1
1.2 国内外研究现状 1
1.3 本文主要研究内容 2
第二章 系统总体设计方案 3
2.1系统的设计需求 3
2.2系统功能的要求 4
2.3系统总体设计 4
第三章 基于LD3320语音识别芯片的硬件设计 4
3.1 系统的硬件设计结构 4
3.2 LD3220芯片原理与特性 5
3.3 STC10L08XE 单片机介 6
3.4 OLED显示屏的介绍 7
3.5 LD3320芯片电路设计 7
第四章 基于LD3320语音识别芯片的软件设计 8
4.1 软件系统的设计 8
4.2 语音系统的流程设计 9
4.3 LD3320程序模块 9
4.4主程序流程图 10
第五章 总结与探讨 11
参考文献 11
致谢 12
附录1代码 12
附录1.1主程序 12
附录1.2 OLED程序 13
附录2 实物图和电路图 22
附录2.1实物图 22
附录2.2电路图 22
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。