嵌入式外设集 — 语音播报模块(JR6001)

嵌入式外设集 — 语音播报模块(JR6001)JR6001 是一种语音播放模块 具有以下特性 1 自带 USB 接口 可以灵活地替换 SPI flash 中的语音内容 无需安装主机电脑来替换传统语音芯片的语音

大家好,欢迎来到IT知识分享网。

目录

一、模块介绍

关注微信公众号–星之援工作室 发送关键字(JR6001)

使用的注意事项

二、移植使用(资料代码中没有移植后的代码,需要自行移植)

1.串口配置

usart2.c

usart2.h

2.JR6001的功能代码编写

JR6001.c

JR6001.h

三、参考


一、模块介绍

JR6001是一种语音播放模块,具有以下特性:

1. 自带USB接口,可以灵活地替换SPI-flash中的语音内容,无需安装主机电脑来替换传统语音芯片的语音。SPI FLASH直接模拟为U盘,就像复制U盘一样,非常方便。任何计算机系统都可以支持它【7†source】。

2. 支持MP3、WAV高质量音频格式,声音优美。

3. 24位DAC输出,动态范围支持90dB,信号比85dB。

4. 支持两线串口控制,AD控制。

5. USB更新语音文件,无需安装驱动程序,无需安装软件,直接复制,快速方便。支持XP系统,WIN7,WIN8,WIN10系统。

6. 支持上一首歌,下一首歌,播放,暂停,停止,选歌,和其他常见功能控制。 7. 支持自由组合播放。 8. 支持30级音量调整。

9. 支持周期号设置,更多应用,更人性化。

10. 专用BUSY信号输出指示。

11. 成熟的指令和指令分析使应用更稳定。

12. 专用支持主机电脑,快速使用,易于调试,命令自动生成【8†source】。

嵌入式外设集 -- 语音播报模块(JR6001)


关注微信公众号–星之援工作室 发送关键字(JR6001)

➡️🫡🫡🫡🫡🫡🫡🫡🫡➡️

嵌入式外设集 -- 语音播报模块(JR6001)

使用的注意事项

1.只需要配置一个串口即可,波特率为9600

二、移植使用(资料代码中没有移植后的代码,需要自行移植)

1.串口配置

usart2.c

因为我们使用的JR6001模块是需要使用串口进行通信控制(详情可在获取的资料中查看),我们只需要用到该串口的发送端口即可,不需要处理JR6001回传的数据,所以接收中断中的数据处理可略过 ~~ (引用GPS的串口配置)

#include "delay.h" #include "usart2.h" #include "stdarg.h" #include "stdio.h" #include "string.h" char rxdatabufer; u16 point1 = 0; _SaveData Save_Data; #if EN_USART2_RX // 如果使能了接收 // 串口1中断服务程序 // 注意,读取USARTx->SR能避免莫名其妙的错误 char USART_RX2_BUF[USART2_REC_LEN]; // 接收缓冲,最大USART_REC_LEN个字节. // 接收状态 // bit15, 接收完成标志 // bit14, 接收到0x0d // bit13~0, 接收到的有效字节数目 u16 USART2_RX_STA = 0; // 接收状态标记 void Usart2_Init(u32 bound) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 串口3时钟使能 USART_DeInit(USART2); // 复位串口3 // USART3_TX PB10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // PB10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PB10 // USART3_RX PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入 GPIO_Init(GPIOA, &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(USART2, &USART_InitStructure); // 初始化串口 3 USART_Cmd(USART2, ENABLE); // 使能串口 // 使能接收中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启中断 // 设置中断优先级 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); // 根据指定的参数初始化VIC寄存器 CLR_Buf(); // 清空缓存 } void USART2_IRQHandler(void) // 串口1中断服务程序 { u8 Res; #ifdef OS_TICKS_PER_SEC // 如果时钟节拍数定义了,说明要使用ucosII了. OSIntEnter(); #endif if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { Res = USART_ReceiveData(USART2); //(USART1->DR); //读取接收到的数据 if (Res == '$') { point1 = 0; } USART_RX2_BUF[point1++] = Res; if (USART_RX2_BUF[0] == '$' && USART_RX2_BUF[4] == 'M' && USART_RX2_BUF[5] == 'C') // 确定是否收到"GPRMC/GNRMC"这一帧数据 { if (Res == '\n') { memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); // 清空 memcpy(Save_Data.GPS_Buffer, USART_RX2_BUF, point1); // 保存数据 Save_Data.isGetData = true; point1 = 0; memset(USART_RX2_BUF, 0, USART2_REC_LEN); // 清空 } } if (point1 >= USART2_REC_LEN) { point1 = USART2_REC_LEN; } } #ifdef OS_TICKS_PER_SEC // 如果时钟节拍数定义了,说明要使用ucosII了. OSIntExit(); #endif } u8 Hand(char *a) // 串口命令识别函数 { if (strstr(USART_RX2_BUF, a) != NULL) return 1; else return 0; } void CLR_Buf(void) // 串口缓存清理 { memset(USART_RX2_BUF, 0, USART2_REC_LEN); // 清空 point1 = 0; } void clrStruct() { Save_Data.isGetData = false; Save_Data.isParseData = false; Save_Data.isUsefull = false; memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length); // 清空 memset(Save_Data.UTCTime, 0, UTCTime_Length); memset(Save_Data.latitude, 0, latitude_Length); memset(Save_Data.N_S, 0, N_S_Length); memset(Save_Data.longitude, 0, longitude_Length); memset(Save_Data.E_W, 0, E_W_Length); } #endif 

usart2.h

功能函数的定义(引用GPS的串口配置)

#ifndef __USART2_H #define __USART2_H #include "stdio.h" #include "sys.h" #include "string.h" //V1.3修改说明 //支持适应不同频率下的串口波特率设置. //加入了对printf的支持 //增加了串口接收命令功能. //修正了printf第一个字符丢失的bug //V1.4修改说明 //1,修改串口初始化IO的bug //2,修改了USART_RX_STA,使得串口最大接收字节数为2的14次方 //3,增加了USART_REC_LEN,用于定义串口最大允许接收的字节数(不大于2的14次方) //4,修改了EN_USART1_RX的使能方式 //V1.5修改说明 //1,增加了对UCOSII的支持 #define USART2_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART2_RX 1 //使能(1)/禁止(0)串口1接收 extern char USART_RX2_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART2_RX_STA; //接收状态标记 #define false 0 #define true 1 //定义数组长度 #define GPS_Buffer_Length 80 #define UTCTime_Length 11 #define latitude_Length 11 #define N_S_Length 2 #define longitude_Length 12 #define E_W_Length 2 typedef struct SaveData { char GPS_Buffer[GPS_Buffer_Length]; char isGetData; //是否获取到GPS数据 char isParseData; //是否解析完成 char UTCTime[UTCTime_Length]; //UTC时间 char latitude[latitude_Length]; //纬度 char N_S[N_S_Length]; //N/S char longitude[longitude_Length]; //经度 char E_W[E_W_Length]; //E/W char isUsefull; //定位信息是否有效 } _SaveData; void Usart2_Init(u32 bound); extern char rxdatabufer; extern u16 point1; extern _SaveData Save_Data; void CLR_Buf(void); u8 Hand(char *a); void clrStruct(void); #endif 

2.JR6001的功能代码编写

1. 配置完串口后,我们需要开始编写我们的控制函数,包括模块的读忙,发送相关的功能控制函数等基础功能

JR6001.c

功能函数的编写

#include "JR6001.h" #include "usart.h" #include "delay.h" #include "stdarg.h" #include "stdio.h" #include "string.h" // 延时函数重定义 JR6001延时函数定义,用户自行更改为自己的延时函数 #define JR6001_ms(ms) delay_ms(ms) #define JR6001_us(us) delay_us(us) void JR6001_Volumecontrol(u8 num); void JR6001_Init(void) { // GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; #ifdef JR6001_BUSY // 查忙引脚配置 RCC_APB2PeriphClockCmd(JR6001_BUSY_GPIO_CLK, ENABLE); // 使能POR时钟 GPIO_InitStructure.GPIO_Pin = JR6001_BUSY_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = JR6001_BUSY_GPIO_Mode; GPIO_Init(JR6001_BUSY_GPIO_PORT, &GPIO_InitStructure); #endif JR6001_Volumecontrol(31); // 设置音量 JR6001_ms(100); } // 串口发送数据 void JR6001_SendCode(u8 *str, u8 busy) { u16 len, i; len = strlen((char *)str); printf("%s\n", str); if (busy == 1 && JR6001_BUSY_IO == 0) { for (i = 0; i <= len; i++) // 循环发送数据 { while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) ; // 循环发送,直到发送完毕 USART_SendData(USART2, str[i]); } } else if (busy == 0) { for (i = 0; i <= len; i++) // 循环发送数据 { while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) ; // 循环发送,直到发送完毕 USART_SendData(USART2, str[i]); } } JR6001_ms(10); } // 基础指令发送 void JR6001_Instruction(u8 *str, u8 busy) { u8 JR6001_Buff[20]; sprintf((char *)JR6001_Buff, "%s\r\n", str); JR6001_SendCode(JR6001_Buff, busy); } // 曲目选择 void JR6001_SongControl(u8 num, u8 busy) { u8 JR6001_Buff[20]; if (num < 10) { sprintf((char *)JR6001_Buff, "A7:0000%d\r\n", num); JR6001_SendCode(JR6001_Buff, busy); } else if (num < 100) { sprintf((char *)JR6001_Buff, "A7:000%d\r\n", num); JR6001_SendCode(JR6001_Buff, busy); } else { sprintf((char *)JR6001_Buff, "A7:00%d\r\n", num); JR6001_SendCode(JR6001_Buff, busy); } } // 音量选择 void JR6001_Volumecontrol(u8 num) { u8 JR6001_Buff[20]; sprintf((char *)JR6001_Buff, "AF:%d\r\n", num); JR6001_SendCode(JR6001_Buff, 0); } /* JR6001_Init(); JR6001_SongControl(5,0); */ 

JR6001.h

功能函数的定义

#ifndef __JR6001_H #define __JR6001_H #include "sys.h" // 查忙使能 #define JR6001_BUSY 0 // 0.失能 1.使能 // JR6001查忙引脚配置 高电平忙 #define JR6001_BUSY_GPIO_CLK RCC_APB2Periph_GPIOA #define JR6001_BUSY_GPIO_PORT GPIOA #define JR6001_BUSY_GPIO_PIN GPIO_Pin_6 #define JR6001_BUSY_GPIO_Mode GPIO_Mode_IPD #define JR6001_BUSY_IO GPIO_ReadInputDataBit(JR6001_BUSY_GPIO_PORT, JR6001_BUSY_GPIO_PIN) // 读取查忙引脚 // JR6001串口命令[播放 暂停 上一曲 下一曲 音量加 音量减] #define Play "A2" #define Suspend "A3" #define On_Song "A5" #define Next_Song "A6" #define Volumeadd "B0" #define Volumesub "B1" void JR6001_Init(void); // 串口发送数据 void JR6001_SendCode(u8 *str, u8 busy); // 基础指令发送 void JR6001_Instruction(u8 *str, u8 busy); // 曲目选择 void JR6001_SongControl(u8 num, u8 busy); // 音量选择 void JR6001_Volumecontrol(u8 num); #endif 

三、参考

嵌入式外设集 — 语音播报模块(JR6001)


完整代码请关注卫星公众号进行获取和咨询


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/151606.html

(0)
上一篇 2025-03-12 19:15
下一篇 2025-03-12 19:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信