语音模块学习——LSYT201B模组(实际操作篇)

目录

一、定制词条

二、直接用串口通信

三、使用单片机通信


理论篇在这,依旧是深圳雷龙发展的语音模块。

http://t.csdnimg.cn/2SzJL

一、定制词条

因为我想后面加到我的毕设上加个语音模块,所以定制的词条都是和芯测相关的。

动作词条播报串口输出(9600)
开机播报
10S自动退出唤醒有需要再叫我
唤醒词你好小龙我在FE 04 00 00 02 FD
命令词录制音频开始录制FE 04 00 01 03 FD
播放音频开始播放FE 04 00 02 04 FD
显示红色显示红色FE 04 00 03 05 FD
显示多色显示多色FE 04 00 04 06 FD
调节背光调节背光FE 04 00 05 07 FD
时钟测试开始测试FE 04 00 06 08 FD
四八五测试开始测试FE 04 00 07 09 FD
看测试开始测试FE 04 00 08 0A FD
按键测试开始测试FE 04 00 09 0B FD
查看温度查看温度FE 04 00 0A 0C FD
开始网络通信开始网络通信FE 04 00 0B 0D FD
关闭网络通信关闭网络通信FE 04 00 0C 0E FD
关闭显示器关闭显示器FE 04 00 0D 0F FD
打开显示器打开显示器FE 04 00 0E 10 FD
查看环境温度查看环境温度FE 04 00 0F 11 FD
查看环境湿度查看环境湿度FE 04 00 10 12 FD
查看当前位置查看单签位置FE 04 00 11 13 FD
前进前进FE 04 00 12 14 FD
后退后退FE 04 00 13 15 FD
停止停止FE 04 00 14 16 FD

二、直接用串口通信

 

起始码长度方向动作IDSUM结束码
0xFE0x040x000xXX0xXX0xFD

和技术人员沟通电源最好用5V的供电,我直接接串口用PC做了下测试

        因为这个接线柱是2.0的所以不能直接用杜邦线,杜邦线是2.54的。所欲我就扒了个皮给他焊上了,防止不同接线柱之间连电,这里需要保留一部分塑料。

        

        随便测了几个指令这里拾音度是真的高很灵敏。比我之前做的那个灵敏。但是还是那个缺点,不能自己改语音指令有点难受。

        为了低功耗,所以这类语音模块都是那种唤醒词形式的。像咱们的手机小爱同学,hi,Siri等等这种,我的这个叫你好小龙。

        总体来说可定制化很高比那种自己可以拿SDK烧写的要高很多,缺点是没SDK。

        音量的调节也比较麻烦需要修改电阻的大小。具体怎么修改到时候可以问技术人员

大概就是修改这两个电阻。 

三、使用单片机通信

        重点来咯,怎么用单片机实现,之前想着用I.MAX6ULL来着,但是我现在没时间,就用经典c8t6来做个demo吧。很好一年没写32的程序了已经忘的差不多了哈哈。

        先说说思路,初始化串口1和串口2.串口2接我们的模块,接收到指令后分析一下转化成对应语句打印到串口1很简单的程序,为什么不真的来控制一下呢,还是那句话,没时间。c8t6最小系统没有板载传感器,连灯泡也就一个。难受的很我要自己焊接,属实麻烦嘿嘿。各位读者朋友见谅哈。作者要做毕设,时间紧任务重呀,用韦东山老师的板子本来以为有移植好的鸿蒙和驱动,我只做服务器客户端还有通信就可用呢。但是被骗了,裸机写的驱动程序,和鸿蒙没有一毛钱关系。我要开发14个驱动程序还要学习鸿蒙应用层开发,以及最难的。把鸿蒙移植到I.MAX6ULL上。所以木有办法咯,抱歉抱歉后面有机会再来好好写写怎么用语音模块。

 下面是串口2的驱动程序,基于标准库的,为什么叫ESP8266因为我懒所以拿那个代码改的哈哈。

/* 函数体 --------------------------------------------------------------------*/
/**
  * 函数功能: 初始化ESP8266用到的GPIO引脚
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
static void ESP8266_GPIO_Config ( void )
{
	/*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;

	/* 配置 CH_PD 引脚*/
	RCC_APB2PeriphClockCmd( ESP8266_RST_CLK, ENABLE ); 	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	
	/* 配置 RST 引脚*/									   
	GPIO_InitStructure.GPIO_Pin = ESP8266_RST_PIN;
	GPIO_Init ( ESP8266_RST_PORT, & GPIO_InitStructure );		
  
  /* 拉高WiFi模块的复位重启引脚	*/
  GPIO_ResetBits( ESP8266_RST_PORT, ESP8266_RST_PIN );
  
}

/**
  * 函数功能: 配置 ESP8266 USART 的 NVIC 中断优先级
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
static void ESP8266_USART_NVIC_Configuration ( void )
{
	NVIC_InitTypeDef NVIC_InitStructure; 	
	
	/* Configure the NVIC Preemption Priority Bits */  
	NVIC_PriorityGroupConfig ( NVIC_PriorityGroup_2 );

	/* Enable the USART2 Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = ESP8266_USART_IRQ;	 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

}

/**
  * 函数功能: 初始化ESP8266用到的 USART
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
static void ESP8266_USART_Config ( void )
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;	
	
	/* config USART clock */
	ESP8266_USART_APBxClock_FUN ( ESP8266_USART_CLK, ENABLE );
	ESP8266_USART_GPIO_APBxClock_FUN ( ESP8266_USART_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE );
	
	/* USART GPIO config */
	/* Configure USART Tx as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin =  ESP8266_USART_TX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(ESP8266_USART_TX_PORT, &GPIO_InitStructure);  
  
	/* Configure USART Rx as input floating */
	GPIO_InitStructure.GPIO_Pin = ESP8266_USART_RX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(ESP8266_USART_RX_PORT, &GPIO_InitStructure);
	
	/* USART1 mode config */
	USART_InitStructure.USART_BaudRate = ESP8266_USART_BAUD_RATE;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(ESP8266_USARTx, &USART_InitStructure);
	
	/* 中断配置 */
	USART_ITConfig ( ESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 
	USART_ITConfig ( ESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断 	

	ESP8266_USART_NVIC_Configuration();	
	
	USART_Cmd(ESP8266_USARTx, ENABLE);	
  
  /* 清除发送完成标志 */
	USART_ClearFlag(ESP8266_USARTx, USART_FLAG_TC|USART_FLAG_TXE|USART_FLAG_RXNE);
}

/**
  * 函数功能: 格式化输出,类似于C库中的printf,但这里没有用到C库
  * 输入参数: USARTx 串口通道,这里只用到了串口2,即USART2
  *		        Data   要发送到串口的内容的指针
  *			      ...    其他参数
  * 返 回 值: 无
  * 说    明:典型应用 USART2_printf( USART2, "\r\n this is a demo \r\n" );
  *            		     USART2_printf( USART2, "\r\n %d \r\n", i );
  *            		     USART2_printf( USART2, "\r\n %s \r\n", j );
  */
void USART_printf(USART_TypeDef * USARTx, char * Data, ... )
{
	const char *s;
	int d;   
	char buf[16];
	
	va_list ap;
	va_start(ap, Data);
	while ( * Data != 0 )     // 判断是否到达字符串结束符
	{				                          
		if ( * Data == 0x5c )  //'\'
		{									  
			switch ( *++Data )
			{
				case 'r':							          //回车符
					USART_SendData(USARTx, 0x0d);
					Data ++;
				break;
				case 'n':							          //换行符
					USART_SendData(USARTx, 0x0a);	
					Data ++;
				break;
				default:
					Data ++;
				break;
			}			 
		}
		else if ( * Data == '%')
		{									  //
			switch ( *++Data )
			{				
				case 's':										  //字符串
					s = va_arg(ap, const char *);
					for ( ; *s; s++) 
					{
						USART_SendData(USARTx,*s);
						while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
					}				
					Data++;				
				break;
				case 'd':			
					//十进制
					d = va_arg(ap, int);					
					itoa(d, buf, 10);					
					for (s = buf; *s; s++) 
					{
						USART_SendData(USARTx,*s);
						while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
					}					
					Data++;				
				break;				
				default:
					Data++;				
				break;				
			}		 
		}		
		else USART_SendData(USARTx, *Data++);
		while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET );
	}
}

/**
  * 函数功能: 将整形数据转换成字符串
  * 输入参数: radix =10 表示10进制,其他结果为0
  *           value 要转换的整形数
  *           buf 转换后的字符串
  *           radix = 10
  * 返 回 值: 无
  * 说    明:被USART_printf()调用
  */
static char * itoa( int value, char *string, int radix )
{
	int     i, d;
	int     flag = 0;
	char    *ptr = string;
	/* This implementation only works for decimal numbers. */
	if (radix != 10)
	{
		*ptr = 0;
		return string;
	}
	if (!value)
	{
		*ptr++ = 0x30;
		*ptr = 0;
		return string;
	}
	/* if this is a negative value insert the minus sign. */
	if (value < 0)
	{
		*ptr++ = '-';
		/* Make the value positive. */
		value *= -1;
	}
	for (i = 10000; i > 0; i /= 10)
	{
		d = value / i;
		if (d || flag)
		{
			*ptr++ = (char)(d + 0x30);
			value -= (d * i);
			flag = 1;
		}
	}
	/* Null terminate the string. */
	*ptr = 0;
	return string;
} /* NCL_Itoa */

/**
  * 函数功能: ESP8266初始化函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void ESP8266_Init ( void )
{
	ESP8266_GPIO_Config ();	
	ESP8266_USART_Config ();	
}

       下面是串口1的初始化和输入输出重定向

void DEBUG_USART_Init(void)
{
  /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 定义USART初始化结构体变量 */
	USART_InitTypeDef USART_InitStructure;
  /* 使能USART时钟 */
  DEBUG_USARTx_ClockCmd(DEBUG_USARTx_CLK,ENABLE);
  /* 使能USART功能GPIO时钟 */
  DEBUG_USARTx_GPIO_ClockCmd(DEBUG_USARTx_TX_CLK | DEBUG_USARTx_RX_CLK | RCC_APB2Periph_AFIO,ENABLE);
  
	/* 调试USART功能GPIO初始化 */
	/* 设定USART发送对应IO编号 */
	GPIO_InitStructure.GPIO_Pin =  DEBUG_USARTx_TX_PIN;
  /* 设定USART发送对应IO模式:复用推挽输出 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  /* 设定USART发送对应IO最大操作速度 :GPIO_Speed_50MHz */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  /* 初始化USART发送对应IO */
	GPIO_Init(DEBUG_USARTx_TX_PORT, &GPIO_InitStructure);    
  
	/* 设定USART接收对应IO编号 */
	GPIO_InitStructure.GPIO_Pin = DEBUG_USARTx_RX_PIN;
  /* 设定USART发送对应IO模式:浮空输入 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  /* 其他没有重新赋值的成员使用与串口发送相同配置 */
  /* 初始化USART接收对应IO */
	GPIO_Init(DEBUG_USARTx_RX_PORT, &GPIO_InitStructure);	
			
	/* USART工作环境配置 */
  /* USART波特率:115200 */
	USART_InitStructure.USART_BaudRate = DEBUG_USARTx_BAUDRATE;
  /* USART字长(有效位):8位 */
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  /* USART停止位:1位 */
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
  /* USART校验位:无 */
	USART_InitStructure.USART_Parity = USART_Parity_No ;
  /* USART硬件数据流控制(硬件信号控制传输停止):无 */
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	/* USART工作模式使能:允许接收和发送 */
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* 初始化USART */
	USART_Init(DEBUG_USARTx, &USART_InitStructure);
	
  /* 使能USART */
	USART_Cmd(DEBUG_USARTx, ENABLE);
	
}

/**
  * 函数功能: 重定向c库函数printf到USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到调试串口 */
  USART_SendData(DEBUG_USARTx, (uint8_t) ch);

  /* 等待串口数据发送完毕 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);		

  return (ch);
}

/**
  * 函数功能: 重定向c库函数getchar,scanf到USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  /* 等待串口输入数据 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

  return (int)USART_ReceiveData(DEBUG_USARTx);
}

        主要是中断处理,在中断接收数据并存入缓冲区然后主函数中对缓冲区内容与ID进行比对,最后打印到串口助手。

void ESP8266_USART_INT_FUN(void)
{
	uint8_t ucCh;
	count++;
	if ( USART_GetITStatus (ESP8266_USARTx, USART_IT_RXNE ) != RESET )
	{
//		ucCh  = USART_ReceiveData(ESP8266_USARTx );
//		ucaRxBuf[count] = ucCh;
		if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
			strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;

	}
	 	 
	if ( USART_GetITStatus(ESP8266_USARTx, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
	{
		if(strEsp8266_Fram_Record .InfBit .FramLength >= 6)
		{	
		    ucTcpClosedFlag = 1;
			strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;
			strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength++ ] = '\0';
		}

		ucCh = USART_ReceiveData(ESP8266_USARTx );
		//ucTcpClosedFlag = strstr(strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
		
    }
	else
	{
		strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;
		//ucTcpClosedFlag = 0;
	}
}

        稍微修改了一下。

        主函数的逻辑大家按照自己的需要去做就行,接收到什么ID对应去操作什么器件。我这里就直接解析并且打印了。

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇努力学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值