STM32+JR6001语音播报

这篇具有很好参考价值的文章主要介绍了STM32+JR6001语音播报。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 

文章目录

  • 前言
  • 一、JR6001怎么用?
  • 二、使用步骤
    • 1.合成语音
    • 2.STM32代码
  • 总结

前言

  最近在做一个利用STM32最小系统实现语音播报的小项目,加入到智能家居远程控制系统中,用来提示上位机对应操作的播报,于是就选择了JR6001作为语音播报模块,接下来就是学习过程。


提示:以下是本篇文章正文内容,下面案例可供参考

一、JR6001怎么用?

    首先使用JR6001模块,就先要从模块的资料中获取信息,话不多说,上链接!!!

    链接: https://pan.baidu.com/s/1IYiga8Af0XBrcd2ONAGTrw?pwd=qwer 提取码: qwer 

    当然,如果想要快速了解JR6001模块,可以移步到CSDN博主「顾城沐心」的文章
    原文链接:https://blog.csdn.net/m0_56051805/article/details/125116764

二、使用步骤

1.合成语音

    JR6001语音播报模块有内置4MB内存(插入USB连接PC即可弹出U盘),足够做项目使用。

STM32+JR6001语音播报

    接下来就是合成想要实现播报的语音,就要用到JR6001资料包里的语音合成软件,使用方法资料包里也有(资料包-语音合成软件-使用说明),就不详细展开介绍了。根据使用手册使用语音合成软件即可,自己动手操作!!!

STM32+JR6001语音播报

     合成后的语音格式是.wav格式,我们还想要将其转换成.mp3格式。当然,JR6001资料包里还有MP3格式转换器(资料包-MP3格式转换器-使用说明图),使用方式如下图所示。

 STM32+JR6001语音播报

    最后就是将转换后的语音.mp3格式,存放在JR6001内置U盘里,并正确按顺序命名。文件编号必须是按照以下顺序存放,例如00001···00011 ,才能保证发送正确指令(其它命名试过,不能正常使用)。

STM32+JR6001语音播报

    通过JR6001使用手册可以了解到,使用串口发送指令可以实现语音模块的播报,在项目中主要通过 6、指定曲目(A7),实现对应语音播报。

STM32+JR6001语音播报

	USART_SendString(USART3, "A7:00001\r\n");

2.STM32代码

代码如下:

串口定义了三个,自行选择(本次以USART3为例),需要注意的是要定义发送字符串,部分串口例程里没有定义,这里需要注意(因为“A7:00001”是以字符串的形式发送)。

void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);//发送字符前清空标志位(否则缺失字符串的第一个字符)
	while(DataString[i] != '\0')		//字符串结束符
	{
		USART_SendData(USARTx,DataString[i]);	//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);	//等待数据发送成功
		USART_ClearFlag(USARTx,USART_FLAG_TC);					//发送字符后清空标志位
		i++;
	}
}

usart.c

#include "sys.h"
#include "usart.h"	  
 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif

#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

 
 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART1_RX_BUF[USART1_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART1_RX_STA=0;       //接收状态标记	  
  
void uart1_init(u32 bound){
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据		
		if((USART1_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART1_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
				else USART1_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART1_RX_STA|=0x4000;
				else
					{
					USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ;
					USART1_RX_STA++;
					if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 

#endif	

#if EN_USART2_RX
u8  USART2_RX_BUF[USART2_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
u16 USART2_RX_STA = 0;         			//接收状态标记	

void uart2_init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStrue;
	USART_InitTypeDef USART_InitStrue;
	NVIC_InitTypeDef NVIC_InitStrue;
	
	// 外设使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
	USART_DeInit(USART2);  //复位串口2 -> 可以没有
	
	// 初始化 串口对应IO口  TX-PA2  RX-PA3
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStrue);
	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_3;
	GPIO_Init(GPIOA,&GPIO_InitStrue);
	
	// 初始化 串口模式状态
	USART_InitStrue.USART_BaudRate=bound; // 波特率
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; // 硬件流控制
	USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; // 发送 接收 模式都使用
	USART_InitStrue.USART_Parity=USART_Parity_No; // 没有奇偶校验
	USART_InitStrue.USART_StopBits=USART_StopBits_1; // 一位停止位
	USART_InitStrue.USART_WordLength=USART_WordLength_8b; // 每次发送数据宽度为8位
	USART_Init(USART2,&USART_InitStrue);
	
	USART_Cmd(USART2,ENABLE);//使能串口
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启接收中断
	
	// 初始化 中断优先级
	NVIC_InitStrue.NVIC_IRQChannel=USART2_IRQn;
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStrue);
}
 
void USART2_IRQHandler(void) // 串口2中断服务函数
{
	u8 res;
	if(USART_GetITStatus(USART2,USART_IT_RXNE)) // 中断标志
	{
		res= USART_ReceiveData(USART2);  // 串口2 接收
//		USART_SendData(USART2,res);   // 串口2 发送
		if((USART2_RX_STA&0x8000)==0)//接收未完成
		{
		if(USART2_RX_STA&0x4000)//接收到了0x0d
			{
			if(res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
			else USART2_RX_STA|=0x8000;	//接收完成了 
			}
		else //还没收到0X0D
			{	
			if(res==0x0d)USART2_RX_STA|=0x4000;
			else
				{
				USART2_RX_BUF[USART2_RX_STA&0X3FFF]=res ;
				USART2_RX_STA++;
				if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		} 
	}
}

#endif

#if EN_USART3_RX
u8  USART3_RX_BUF[USART3_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
u16 USART3_RX_STA = 0;         			//接收状态标记	

void uart3_init(u32 bound)
{

	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	// GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能
 
 	USART_DeInit(USART3);  //复位串口3
		 //USART3_TX   PB10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10
   
    //USART3_RX	  PB11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB11
	
	USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART3, &USART_InitStructure); //初始化串口	3
  
 
	USART_Cmd(USART3, ENABLE);                    //使能串口 
	
	//使能接收中断
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断   
	
	//设置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	USART3_RX_STA=0;		//清零
}
 
void USART3_IRQHandler(void) // 串口3中断服务函数
{
	u8 res;
	if(USART_GetITStatus(USART3,USART_IT_RXNE)) // 中断标志
	{
		res= USART_ReceiveData(USART3);  // 串口3 接收
//		USART_SendData(USART2,res);   // 串口3 发送
		if((USART3_RX_STA&0x8000)==0)//接收未完成
		{
		if(USART3_RX_STA&0x4000)//接收到了0x0d
			{
			if(res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
			else USART3_RX_STA|=0x8000;	//接收完成了 
			}
		else //还没收到0X0D
		{	
			if(res==0x0d)USART3_RX_STA|=0x4000;
			else
				{
				USART3_RX_BUF[USART2_RX_STA&0X3FFF]=res ;
				USART3_RX_STA++;
				if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
		}
	} 
	}
}


void USART_SendString(USART_TypeDef* USARTx, char *DataString)
{
	int i = 0;
	USART_ClearFlag(USARTx,USART_FLAG_TC);										//发送字符前清空标志位(否则缺失字符串的第一个字符)
	while(DataString[i] != '\0')												//字符串结束符
	{
		USART_SendData(USARTx,DataString[i]);									//每次发送字符串的一个字符
		while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == 0);					//等待数据发送成功
		USART_ClearFlag(USARTx,USART_FLAG_TC);									//发送字符后清空标志位
		i++;
	}
}


#endif

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" 

#define USART1_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1			//使能(1)/禁止(0)串口1接收 	
extern u8  USART1_RX_BUF[USART1_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART1_RX_STA;         			//接收状态标记	
void uart1_init(u32 bound);

#define USART2_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART2_RX 			1			//使能(1)/禁止(0)串口2接收
extern u8  USART2_RX_BUF[USART2_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART2_RX_STA;         			//接收状态标记	
void uart2_init(u32 bound);

#define USART3_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART3_RX 			1			//使能(1)/禁止(0)串口2接收
extern u8  USART3_RX_BUF[USART3_REC_LEN]; 	//接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART3_RX_STA;         			//接收状态标记	
void uart3_init(u32 bound);

void USART_SendString(USART_TypeDef* USARTx, char *DataString);
#endif

main.c

#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "usart.h"	
int main(void)
{	
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
//	uart1_init(9600);	                //串口1初始化波特率为9600
//	uart2_init(9600);							   //串口2初始化波特率为9600
	uart3_init(9600);							   //串口3初始化波特率为9600
    delay_init();	                               //延时初始化                                   
	USART_SendString(USART3, "A7:00001\r\n");
	delay_ms(10);
	while(1)
	{
		USART_SendString(USART3, "A7:00002\r\n");
		delay_ms(10);
	}
}
 

需要注意的是,串口波特率的设置必须与JR6001的波特率一致(9600)

STM32+JR6001语音播报

	uart3_init(9600);							   //串口3初始化波特率为9600

总结

    接下来就是动手实践了,不懂的也可以直接下载程序源码(评论区留言发送)。当然,根据上面操作也是可以实现的,还是自己动手来的更有意义。

    随便蹭一下“五一定制限量奖章”,真的很帅!!!文章来源地址https://www.toymoban.com/news/detail-458694.html

到了这里,关于STM32+JR6001语音播报的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于STM32的SYN6288语音播报模块驱动实验(代码开源)

    前言: 本文为手把手教学  SYN6288 语音播报模块的驱动实验,本教程的  MCU  采用 STM32F103ZET6 。通过  CubeMX  软件配置 UART 串口协议驱 SYN6288 模块进行规定的语音播报。考虑到  SYN6288 模块的集成化与智能化很高,所以该模块的使用是极其便利的。( 文末代码开源! ) 硬件

    2024年02月13日
    浏览(41)
  • 基于STM32的SYN6288语音播报模块驱动实验(代码开源)_syn6288语音模块

    SYN6288 中文语音合成芯片是北京宇音天下科技有限公司于2010年初推出的一款性/价比更高,效果更自然的一款中高端语音合成芯片。 SYN6288 通过异步串口( UART )通讯方式,接收待合成的文本数据,实现文本到语音(或TTS语音)的转换。 宇音天下于 2002 年最早研制出国内首款

    2024年04月25日
    浏览(64)
  • STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072

    STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072 Proteus 仿真小实验: STM32 Proteus仿真语音播报SGP30火灾报警器温度湿度-0072 功能: 硬件组成:STM32F103C6单片机 +0.960LED显示屏+DHT11温度湿度+电位器模拟SGP30二氧化碳传感器+蜂鸣器LED+串口模拟语音播报+电机模拟电风扇换气+多

    2024年02月16日
    浏览(36)
  • STM32系列——手把手教你将SYN6288语音播报模块的标准库程序转为hal库使用

    目录 前言 1. 原理 2. Cubmx配置 3. keil5编写代码 3.1 main.c 3.2 syn6288.c 3.3 syn6288.h 本教程基于 stm32f103c8t6 最小系统板, hal库 开发。 操作简单,讲解直接清楚,旨在让大家少走弯路。 SYN6288就是用到一个串口资源即可,用STM32开发起来不难。 配置串口3为异步通信模式 ,注意波特率

    2024年02月07日
    浏览(64)
  • 【ESP32S3 Sense接入语音识别+MiniMax模型+TTS模块语音播报】

    讲解视频: ESP32S3 AI助手使用MiniMax大模型生产工具1 大家好,今天的教程将围绕如何实现精准的语音播报功能展开,我们用到了ESP32S3 Sense接入语音识别+MiniMax模型对话+SNR9816TTS模块。 目前这是我使用的ESP32S3官方硬件👍👍👍(小小的身材有大大的力量)只需要35元加摄像头麦

    2024年04月12日
    浏览(42)
  • 【vue 语音播报(文字转语音)】

    查看代码 参考 1.speak-tts: https://github.com/tom-s/speak-tts 2.Vue中使用speak-tts插件实现点击按钮后进行语音播报(TTS/文字转语音) :https://www.cnblogs.com/badaoliumangqizhi/p/15822975.html 3.vue 语音播报(文字转语音)https://www.icode9.com/content-4-864733.html

    2024年02月11日
    浏览(50)
  • uniapp小程序使用文字转语音播报类似支付宝收款播报

    第一步:登陆微信公众平台,侧边栏的设置-----第三方设置-----插件管理----添加插件(搜索–同声传译) 第二步:打开 hbiuider-x,找到当前项目,打开manifest.json,找到源码视图,配置插件     第三步,页面引入使用  

    2024年02月12日
    浏览(36)
  • uniapp 语音文本播报功能

    最近uniapp项目上遇到一个需求 就是在接口调用成功的时候加上语音播报 , ‘创建成功’ ‘开始成功’ ‘结束成功’ 之类的。 因为是固定的文本 ,所以我先利用工具生成了 文本语音mp3文件,放入项目中,直接用就好了。 这里用到的工具: 知意配音 链接地址:https://peiy

    2024年02月15日
    浏览(37)
  • Android文字转语音播报

    Android文字转语音播报可以通过Android自带TTS和第三方语音框架实现。 代码如下(示例): 代码如下(示例): 1.包名、应用名: com.svox.pico 系统自带不支持中文语音 com.baidu.duersdk.opensdk 度秘语音引擎3.0 不支持5.0以下系统,大小11.95M com.google.android.tts 谷歌文字转语音引擎,不

    2023年04月08日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包