文章目录

  • 前言
  • 一、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盘),足够做项目使用。

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

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

     

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

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

    	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)

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

    总结

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

        随便蹭一下“五一定制限量奖章”,真的很帅!!!

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32+JR6001语音播报

    发表回复