语音交互(第一篇)_ 呼唤STM32让舵机转动和停止

这篇具有很好参考价值的文章主要介绍了语音交互(第一篇)_ 呼唤STM32让舵机转动和停止。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

嵌入式之路,贵在日常点滴

                                                                ---阿杰在线送代码

目录

一、 LD3320模块介绍(类似于耳朵)

1、简介

2、 有三个工作模式

3、板上管脚资源

二、MP3模块(类似于嘴巴)

1、简介

2、板上管脚资源 

3、 MP3模块播放的指令和格式

三、LD3320和MP3之间的对话 

四、功能实现 


一、 LD3320模块介绍(类似于耳朵)

1、简介

LD3320是一颗基于非特定人语音识别(SI-ASR:Speaker-Independent Automatic Speech Recognition)技术的语音识别芯片,或者说是语音声控芯片。 

非特定人语音识别是什么

通俗点讲就是不用针对指定发音人的识别技术,这种语音识别技术不分年龄、性别,只要发音人说的是相同的语言就可以识别。再说得简单点,就是说只要是拼音可以拼出的发音,都是可以输入芯片进行识别的。

这个语音识别模块它不是智能的,不是说我们问它什么它就可以回答什么,它不像我们手机上的语音助手比如小爱或者Siri那样,能跟我们对答如流。这个模块能识别的内容,是需要我们提前设定好的,我们把要识别的关键词语列好,然后把这些关键词语以字符的形式传送到 LD3320 内部,这样才可以对用户说出的关键词语进行识别,而且在同一时刻,它最多是在50条关键词语中进行识别。

2、 有三个工作模式

1、普通模式:不同的工作模式可以通过程序编程来实现

2、口令模式:模块工作时,我们先要说出一个一级口令,比如“芝麻开门”,模块在识别到正确的一级口令后才进行下一级的识别

3、按键触发模式:模块工作时,我们在进行语音识别之前,需要先按一下按键,接下来才能进行下一步的识别

(不同的工作模式可以通过程序编程来实现)

这三个模式我觉得口令模式比较实用,本实验,我用的就是口令模式。

3、板上管脚资源

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止

如上图中这个语音识别模块的图片,红色框框中的引脚就是我们可以用的IO,竖着那一排由下而上标着P10~P17有八个,横着那一排从左往右是P34、P33,P23~P27,P41,也有8个,这样我们可以用的IO口就有16个啦,这16个IO口可以用来控制继电器,LED,或者接单片机的IO口。 

上图中,最左边由下而上标着5V,GND,TX,RX的四个引脚就是用来给模块下载程序的地方,串口就在这里了。我们通过串口给其它模块或者单片机发数据也是从这里接。 

二、MP3模块(类似于嘴巴)

1、简介

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止模块型号名称是MP3-TF-16P,别看它体积不大,功能可是很强大的。简单来说,它就是一个音乐播放器,可以用来播放U盘、TF卡、NOR FLASH里的MP3、WAV、WMA格式的音频文件,同时它也可以作为电脑的声卡,用来播放电脑的声音。它也可以作为读卡器,通过USB连接电脑后就可以更新TF卡里的内容,用来更新文件。 

这个小东西能用来放音乐,放广播,它不仅支持通过按键来选曲、调音量,还可以通过单片机来操作,这也就是说,我们可以通过编程,通过串口来发指令,指定它什么时候放哪首歌曲,放多大的音量,中途插不插播广告等,根本不用我们动手,程序上就解决了。 

2、板上管脚资源 

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止

一共有16个脚,左上角为第一个脚,是模块的电源输入引脚,输入电压范围是3.3-5V,建议用5V供电。

第一个脚是VCC,接5V电

第二个脚是RX,是UART 串行数据输入。

第三个脚是TX,是UART 串行数据输出

第四个脚是DAC_R,是音频输出右声道,可驱动耳机或者输出音频信号给功放。

第五个脚是DAC_L,是音频输出左声道。

第六个脚是SPK2,是接小喇叭+的,可以驱动小于3W的喇叭

第七个脚是GND,接电源负极

第八个脚是SPK1,是接小喇叭-的

第九个脚是IO1,是触发口,默认上一曲(长按音量-)。

第十个脚也是GND。

第十一个脚是IO2,也是触发口,默认下一曲(长按音量+)。

第十二个脚是ADKEY1,AD口1,当触发时是第一段(长按循环第一段)。

第十三个脚是ADKEY2,AD口2,当触发时是第五段(长按循环第五段)。

第十四个脚是USB+,USB+ DP,接U盘或插电脑的USB口。

第十五个脚是USB-,USB- DM,接U盘或插电脑的USB口。

最后一个是BUSY引脚,它是播放指示,有音频播放时是输出低电平,没有音频播放时是输出高电平。

串口接线电路图:

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止 

3、 MP3模块播放的指令和格式

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止指定播放一个MP3文件的指令是这样的:7E FF 06 03 00 00 01 FE F7 EF 

--》03 00 00 01这四个字节,代表的就是指定播放第一首歌曲,不需要信息反馈

从语音模块(LD3320)通过串口给MP3模块发这一串东西,MP3模块收到后就知道这是要播放第几个MP3文件 

7E 是起始位,固定不变的,都要有它

FF 这是这个模块的版本信息,也是固定不变的

06 指的是从上一字节开始,到后面的字节个数,也就是说,从FF开始,到06 03 00 00 01为止,一共有六个字节 

03 在这里,指的是指定曲目播放,也是固定不变的

00 在这里指的是不需要反馈信息。如果是01,就是要反馈信息,这里的反馈信息指的是MP3播放模块反馈给语音识别模块的信息

00 01 这里指的是歌曲序号,00是数据高字节,01是数据低字节,低字节01在这里表示的就是播放第一首歌曲

FE和F7指的是累加和校验,是用来给数据查错的

最后一位EF是结束位,当接收到这一位,就说明整个数据发送完毕了

-》设置那么复杂的指令是为了提高数据传输时的准确性

三、LD3320和MP3之间的对话 

思路:对于命令的传输我们通过串口来发送,当语音识别模块(LD3320)识别到我们的命令后,让它通过串口给这个MP3模块发送一串指令,这MP3模块接收到指令后,就播放相对应的MP3文件,这样不就实现了系统对我们的应答了嘛。 

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止

比如我设置这个语音识别模块的一级口令为“阿杰在线送代码”,我叫一声“阿杰在线送代码”,语音识别模块识别成功后就给MP3模块发送一个指令,指定播放一个MP3文件,而这个文件的内容是“主人,我在”,这样就完成了一个交互的过程。

好,先把硬件连接好,来个简单的电路图: 

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止左边这个是语音识别模块,右边的是MP3模块,它们电源正极和地都需要接,这个不用说,然后就是数据的传输了,通过串口来,它们的RX和TX交叉来接,RX接TX,TX接RX,这就完成了,很简单。 

四、功能实现 

通过语音识别模块(LD3320)识别想要执行的动作,MP3给出回应开始执行动作。 

实现:

一级指令:科技之城

MP3:主人,我在

二级指令:转动舵机

MP3:好的,开始转动舵机 (此时STM32读取LD3320给出的高低电平状态来开始执行动作)

一级指令:科技之城

MP3:主人,我在

二级指令:恢复原位

MP3:好的,恢复原位 (此时STM32读取LD3320给出的高低电平状态来开始执行动作)

程序我们直接利用商家给的初始化程序,我们去做修改即可。

需要修改的地方

语音交互(第一篇)_ 呼唤STM32让舵机转动和停止语音交互(第一篇)_ 呼唤STM32让舵机转动和停止语音交互(第一篇)_ 呼唤STM32让舵机转动和停止语音交互(第一篇)_ 呼唤STM32让舵机转动和停止废话不说上代码

*LDChips.c

uint8 LD_AsrAddFixed()
{	
    ...
    #define DATE_A 9   /*数组二维数值*/
	#define DATE_B 24		/*数组一维数值*/
	uint8 code sRecog[DATE_A][DATE_B] = {
														"ke ji zhi cheng",\		
														"kai shi shao shui",\
														"guan bi shao shuii",\
														"kai shi pao cha",\
														"hui shou di yi ge bei zi",\
													    "kai shi xi cha bei",\
														"zhuan dong duo ji",\
														"hui fu yuan wei",\
														"yin lue"
										};	/*添加关键词,用户修改*/
	uint8 code pCode[DATE_A] = {
															CODE_CMD,\
															CODE_KSSS,\
															CODE_GBSS,\
															CODE_KSPC,\
															CODE_HSDYGBZ,\
															CODE_KSXCB,\														
															CODE_ZDDJ,\
															CODE_HFYW,\
															CODE_YL
							  };	/*添加识别码,用户修改*/	
    ....
}
*LDChips.h

//识别码客户修改处 
#define CODE_CMD  0x00   //该命令码0x00用户不可进行修改。
#define CODE_GBSS	0x01		//开始烧水
#define CODE_KSSS	0x02		//关闭烧水
#define CODE_KSPC 0x04			//开始泡茶
#define CODE_HSDYGBZ 0x05		//回收第一个杯子
#define CODE_KSXCB 0x06			//开始洗茶杯
#define CODE_ZDDJ 0x07			//转动电机
#define CODE_HFYW 0x08			//恢复原位
#define CODE_YL 	0x09			//音乐
*usart.c
//直接在MP3的串口调试移植,需要修改一点东西

#include "config.h"
#define FOSC 22118400L      //System frequency
uint32_t baud=9600;           //UART baudrate
unsigned char Send_buf[20];				/*指针溢出了*/
/************************************************************************
函 数 名: 串口初始化
功能描述: STC10L08XE 单片机串口初始化函数
返回函数: none
其他说明: none
**************************************************************************/
void UartIni(void)
{
    SCON = 0x50;            //8-bit variable UART
    TMOD = 0x20;            //Set Timer1 as 8-bit auto reload mode
    TH1 = TL1 = -(FOSC/12/32/baud); //Set auto-reload vaule
    TR1 = 1;                //Timer1 start run
    ES = 1;                 //Enable UART interrupt
    EA = 1;                 //Open master interrupt switch
}
/***********************************************************
* 名    称: 
* 功    能: 
* 入口参数: 无 
* 出口参数:无
* 说    明: 					 
**********************************************************/
void Uart_Isr() interrupt 4 using 1
{	
	if(RI)
	{	
		  
	}

}
/************************************************************************
功能描述: 	串口发送一字节数据
入口参数:	DAT:带发送的数据
返 回 值: 	none
其他说明:	none
**************************************************************************/
void Uart_PutByte(uint8_t DAT)
{
	ES  =  0;
	TI=0;
	SBUF = DAT;
	while(TI==0);
	TI=0;
	ES = 1;
}
/************************************************************************
功能描述: 串口发送字符串数据
入口参数: 	*DAT:字符串指针
返 回 值: none
其他说明: API 供外部使用,直观!
**************************************************************************/
void PrintCom(uint8_t *DAT)
{
	while(*DAT)
	{
	 	Uart_PutByte(*DAT++);
	}	
}

void SendCmd(int len) 
{ 
	int a = 0;
	Uart_PutByte(0x7E); //起始
	for(a=0; a<len; a++)//数据
	{ 
		Uart_PutByte(Send_buf[a]) ; 
	} 
	Uart_PutByte(0xEF) ;//结束
} 

void DoSum(unsigned char *Str,unsigned char len) 
{ 
	int xorsum = 0; 
	unsigned char a; 
	for(a=0; a<len; a++) 
	{ 
		xorsum = xorsum + Str[a]; 
	} 
	xorsum = 0 -xorsum; 
	*(Str+a) = (unsigned char)(xorsum >>8); 
	*(Str+a+1) = (unsigned char)(xorsum & 0x00ff); 
} 
void Uart_SendCMD(unsigned char CMD ,unsigned char feedback ,int dat) 
{ 
	Send_buf[0] = 0xff; //保留字节 
	Send_buf[1] = 0x06; //长度
	Send_buf[2] = CMD; //控制指令
	Send_buf[3] = feedback;//是否需要反馈
	Send_buf[4] = (unsigned char )((dat >> 8)&0xFF);//datah 
	Send_buf[5] = (unsigned char )(dat&0xFF); //datal 
	DoSum(Send_buf,6); //校验
	SendCmd(8); //发送此帧数据
}
*main.c

void 	User_handle(uint8 dat)
{
     //UARTSendByte(dat);//串口识别码(十六进制)
		 if(0==dat)
		 {
		  	G0_flag=ENABLE;
//				PrintCom("“主人,我在”命令识别成功\r\n");
				LED=0;
				Uart_SendCMD(0x03,0x00,0x01);
		 }
		 else if(ENABLE==G0_flag)
		 {	
		 		G0_flag=DISABLE;
				LED=1;
			 switch(dat)		   /*对结果执行相关操作,客户修改*/
			  {
				 	case CODE_KSSS:	 /*命令“全开”*/
//		PrintCom("“好的 开始烧水”命令识别成功\r\n");//串口输出提示信息(可删除)
						Uart_SendCMD(0x03,0x00,0x02);
						
													 break;
					case CODE_GBSS:			/*命令“测试”*/
//		PrintCom("“好的 关闭烧水”命令识别成功\r\n"); //串口输出提示信息(可删除)
						Uart_SendCMD(0x03,0x00,0x03);
						
													 break;

					case CODE_KSPC:		/*命令“复位”*/				
//		PrintCom("“好的 开始泡茶”命令识别成功\r\n"); //串口输出提示信息(可删除)
						Uart_SendCMD(0x03,0x00,0x04);						
						PA3=1;//让PA3端口为高电平 
													break;
					case CODE_HSDYGBZ:		/*命令“复位”*/				
//		PrintCom("“好的 回收第一个杯子”命令识别成功\r\n"); //串口输出提示信息(可删除)
						Uart_SendCMD(0x03,0x00,0x05);					
						PA3=0;//让PA3端口为低电平
													break;
					case CODE_KSXCB:		/*命令“复位”*/				
//		PrintCom("“好的 开始洗茶杯”命令识别成功\r\n"); //串口输出提示信息(可删除)
						Uart_SendCMD(0x03,0x00,0x06);					
						PA4=1;//让PA4端口为高电平
													break;
					case CODE_ZDDJ:
						Uart_SendCMD(0x03,0x00,0x07);
						PA1=1;//让PA2端口为高电平
													break;
					case CODE_HFYW:
						Uart_SendCMD(0x03,0x00,0x08);
						PA1=0;//让PA1端口为高电平
													break;
					case CODE_YL:
						Uart_SendCMD(0x03,0x00,0x09);
													break;
																										
							default:
//		PrintCom("请重新识别发口令\r\n"); //串口输出提示信息(可删除)
													break;
				}	
			}	
			else 	
			{
//				PrintCom("请说出一级口令\r\n"); //串口输出提示信息(可删除)	
			}
}	 

上电后,你会发现MP3不给你回应,你可以尝试给MP3重新复位,即地拔掉再插上 

下面是STM32的代码 

 文章来源地址https://www.toymoban.com/news/detail-427538.html

//用来判断语音识别给的是高电平还是低电平来执行动作

#include "duoji.h"

void duoji_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//定义一个结构体变量
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA 使能PC端口时钟 rcc.h-693
		
	
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPD;//PA15 设置成下拉输入
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);//根据设定参数初始化GPIOE.5	

}

#define DUOJI GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)//读取 PA8 电平
main.c


		//舵机调试
		if(DUOJI == 1)	
		{
			TIM_SetCompare1(TIM3,75);//舵机90度		
			delay_ms(500);
			TIM_SetCompare1(TIM3,100);//舵机135度
			delay_ms(500);		
			TIM_SetCompare1(TIM3,125);//舵机180度
			delay_ms(500);		
			TIM_SetCompare1(TIM3,100);//舵机135度
			delay_ms(500);
			TIM_SetCompare1(TIM3,75);//舵机90度		
			delay_ms(500);
			TIM_SetCompare1(TIM3,50);//舵机45度	
			delay_ms(500);
			TIM_SetCompare1(TIM3,20);//舵机45度	
			delay_ms(500);
		}	
		else
		{
			TIM_SetCompare1(TIM3,75);//舵机90度		
			delay_ms(500);
		}	

到了这里,关于语音交互(第一篇)_ 呼唤STM32让舵机转动和停止的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32单片机与LD3320语音模块的交互方法

    在嵌入式系统中,STM32单片机广泛应用于各种应用领域。而LD3320语音模块是一种常用的语音识别与合成模块。本文将介绍如何在STM32单片机上与LD3320语音模块进行交互,并提供相应的源代码。 硬件连接 首先,我们需要将STM32单片机与LD3320语音模块进行正确的硬件连接。以下是

    2024年03月13日
    浏览(44)
  • 实例4:树莓派GPIO控制舵机转动

    通过背景知识学习,了解舵机的外观及基本运动方式。 了解四足机器人mini pupper腿部单个舵机的组成结构。 通过GPIO对舵机进行转动控制,熟悉PWM。 了解mini pupper舵机组的整体调零。 使用Python语言编程,在编程中使用PWM方法,通过树莓派GPIO控制外部舵机来回摆动,角度范围为

    2024年02月02日
    浏览(28)
  • Arduino通过两个按键开关控制舵机转动(含代码)

    两个开关控制舵机转动 在 Arduino 上控制舵机需要使用到一个 Servo 库,可以通过该库来轻松实现对舵机的控制。下面是两个开关通过 Arduino 控制舵机的步骤: 1.连接硬件:将舵机的 VCC 引脚连接到 Arduino 板子的 5V 引脚,GND 引脚连接到 GND 引脚。将舵机的控制引脚(通常是橙色

    2024年02月12日
    浏览(49)
  • 51单片机实现SG90舵机任意角度转动

    参考单片机——SG90舵机工作原理_掏一淘哆啦A梦的奇妙口袋的博客-CSDN博客​​​​​​ 这位博主做的代码,在此基础上进行简单修改成可以用51单片机的定时器和中断实现SG90舵机任意角度转动 完整代码如下:  这里对主要的内容进行解释。 根据51单片机定时器计数初值的计

    2024年02月16日
    浏览(30)
  • 声控小助手:文本语音呼唤技术的应用与实现

    1. 引言 在当今数字化时代,文本语音呼唤技术正逐渐成为人们生活中不可或缺的一部分。本文将介绍文本语音呼唤技术的原理、实现方法以及其在智能助手、智能家居等领域的应用。 文本语音互换 | 一个覆盖广泛主题工具的高效在线平台(amd794.com) https://amd794.com/textspeech 2. 技

    2024年03月22日
    浏览(44)
  • android实现圆形的ProgressBar停止转动

    先来看看 ProgressBar 的常用属性: android:max: 设置 ProgressBar 的最大值,默认是 100。 android:indeterminate: 设置是否开启不确定模式。true 表示进度条会展示实际的进度;而 false 表示在加载时会无限循环展示 loading 动画。 android:minHeight: 设置最小高度。 android:minWidth: 设置最小宽

    2023年04月08日
    浏览(28)
  • 舵机,模拟舵机,数字舵机(arduino,stm32f103代码开源)

     舵机是一种常见的伺服电机,主要用来控制角度的变化。常见的sg90舵机组成结构如下: 舵机组成图 ​ sg90是模拟舵机,除了模拟舵机外,还有数字舵机,他们的控制区别如下 模拟舵机和数字舵机的控制区别  模拟舵机和数字舵机的机械结构一样;硬件方面数字舵机多了一

    2024年02月05日
    浏览(40)
  • STM32--舵机驱动

    目录 舵机接线: 数字舵机与模拟舵机的区别: 舵机驱动(90度、180度、270度、360度): 90度舵机驱动: 180度舵机驱动: 270度舵机驱动: 360度舵机驱动: STM32定时器配置: stm32f4为例(时钟频率为84Mhz): stm32f1为例(时钟频率为72Mhz): STM32定时器PWM输出配置要点: STM32定时

    2024年04月15日
    浏览(22)
  • STM32——舵机控制

    一、舵机控制原理 (一)概述         舵机是一种位置伺服驱动器器,是一种带有输出轴的小装置。当我们向伺服器发送一个控制信号时,输出轴就可以转到特定的位置。只在控制信号持续不变,伺服机构就会保持相对的角度位置不变。如果控制信号发生变化,输出轴的位

    2024年04月23日
    浏览(32)
  • stm32 舵机 cubemx

    stm32对舵机进行控制,很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此,您可以通过改变PWM信号的占空比来改变舵机的角度。占空比是PWM信号的高电平时间与PWM信号的总周

    2024年02月15日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包