加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入

嵌入式外設(shè)集-語(yǔ)音播報(bào)模塊(JR6001)驅(qū)動(dòng)

03/20 16:37
1萬(wàn)
服務(wù)支持:
技術(shù)交流群

完成交易后在“購(gòu)買成功”頁(yè)面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長(zhǎng)和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購(gòu)買后不支持退換且無(wú)法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
實(shí)物圖
相關(guān)方案
  • 方案介紹
    • 一、模塊介紹
    • 二、移植使用(資料代碼中沒有移植后的代碼,需要自行移植)
    • 三、參考
  • 相關(guān)文件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

一、模塊介紹

JR6001是一種語(yǔ)音播放模塊,具有以下特性:

1. 自帶USB接口,可以靈活地替換SPI-flash中的語(yǔ)音內(nèi)容,無(wú)需安裝主機(jī)電腦來(lái)替換傳統(tǒng)語(yǔ)音芯片的語(yǔ)音。SPI FLASH直接模擬為U盤,就像復(fù)制U盤一樣,非常方便。任何計(jì)算機(jī)系統(tǒng)都可以支持它【7?source】。

2. 支持MP3、WAV高質(zhì)量音頻格式,聲音優(yōu)美。

3. 24位DAC輸出,動(dòng)態(tài)范圍支持90dB,信號(hào)比85dB。

4. 支持兩線串口控制,AD控制。

5. USB更新語(yǔ)音文件,無(wú)需安裝驅(qū)動(dòng)程序,無(wú)需安裝軟件,直接復(fù)制,快速方便。支持XP系統(tǒng),WIN7,WIN8,WIN10系統(tǒng)。

6. 支持上一首歌,下一首歌,播放,暫停,停止,選歌,和其他常見功能控制。 7. 支持自由組合播放。 8. 支持30級(jí)音量調(diào)整。

9. 支持周期號(hào)設(shè)置,更多應(yīng)用,更人性化。

10. 專用BUSY信號(hào)輸出指示。

11. 成熟的指令和指令分析使應(yīng)用更穩(wěn)定。

12. 專用支持主機(jī)電腦,快速使用,易于調(diào)試,命令自動(dòng)生成【8?source】。


關(guān)注微信公眾號(hào)--星之援工作室 發(fā)送關(guān)鍵字(JR6001)

????

使用的注意事項(xiàng)

1.只需要配置一個(gè)串口即可,波特率為9600

二、移植使用(資料代碼中沒有移植后的代碼,需要自行移植)

1.串口配置

usart2.c

因?yàn)槲覀兪褂玫腏R6001模塊是需要使用串口進(jìn)行通信控制(詳情可在獲取的資料中查看),我們只需要用到該串口的發(fā)送端口即可,不需要處理JR6001回傳的數(shù)據(jù),所以接收中斷中的數(shù)據(jù)處理可略過 ~~?(引用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中斷服務(wù)程序
// 注意,讀取USARTx->SR能避免莫名其妙的錯(cuò)誤
char USART_RX2_BUF[USART2_REC_LEN]; // 接收緩沖,最大USART_REC_LEN個(gè)字節(jié).
// 接收狀態(tài)
// bit15,	接收完成標(biāo)志
// bit14,	接收到0x0d
// bit13~0,	接收到的有效字節(jié)數(shù)目
u16 USART2_RX_STA = 0; // 接收狀態(tài)標(biāo)記

void Usart2_Init(u32 bound)
{

	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // GPIOB時(shí)鐘
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 串口3時(shí)鐘使能

	USART_DeInit(USART2);					  // 復(fù)位串口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; // 復(fù)用推挽輸出
	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;										// 波特率一般設(shè)置為9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						// 字長(zhǎng)為8位數(shù)據(jù)格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							// 一個(gè)停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								// 無(wú)奇偶校驗(yàn)位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 無(wú)硬件數(shù)據(jù)流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					// 收發(fā)模式

	USART_Init(USART2, &USART_InitStructure); // 初始化串口	3

	USART_Cmd(USART2, ENABLE); // 使能串口

	// 使能接收中斷
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 開啟中斷

	// 設(shè)置中斷優(yōu)先級(jí)
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 搶占優(yōu)先級(jí)3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		  // 子優(yōu)先級(jí)3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							  // 根據(jù)指定的參數(shù)初始化VIC寄存器

	CLR_Buf(); // 清空緩存
}

void USART2_IRQHandler(void) // 串口1中斷服務(wù)程序
{
	u8 Res;
#ifdef OS_TICKS_PER_SEC // 如果時(shí)鐘節(jié)拍數(shù)定義了,說明要使用ucosII了.
	OSIntEnter();
#endif
	if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
	{
		Res = USART_ReceiveData(USART2); //(USART1->DR);	//讀取接收到的數(shù)據(jù)

		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"這一幀數(shù)據(jù)
		{
			if (Res == 'n')
			{
				memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);	 // 清空
				memcpy(Save_Data.GPS_Buffer, USART_RX2_BUF, point1); // 保存數(shù)據(jù)
				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 // 如果時(shí)鐘節(jié)拍數(shù)定義了,說明要使用ucosII了.
	OSIntExit();
#endif
}

u8 Hand(char *a) // 串口命令識(shí)別函數(shù)
{
	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

功能函數(shù)的定義(引用GPS的串口配置)

#ifndef __USART2_H
#define __USART2_H
#include "stdio.h"	
#include "sys.h"
#include "string.h"

//V1.3修改說明 
//支持適應(yīng)不同頻率下的串口波特率設(shè)置.
//加入了對(duì)printf的支持
//增加了串口接收命令功能.
//修正了printf第一個(gè)字符丟失的bug
//V1.4修改說明
//1,修改串口初始化IO的bug
//2,修改了USART_RX_STA,使得串口最大接收字節(jié)數(shù)為2的14次方
//3,增加了USART_REC_LEN,用于定義串口最大允許接收的字節(jié)數(shù)(不大于2的14次方)
//4,修改了EN_USART1_RX的使能方式
//V1.5修改說明
//1,增加了對(duì)UCOSII的支持
#define USART2_REC_LEN  			200  	//定義最大接收字節(jié)數(shù) 200
#define EN_USART2_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern char  USART_RX2_BUF[USART2_REC_LEN]; //接收緩沖,最大USART_REC_LEN個(gè)字節(jié).末字節(jié)為換行符 
extern u16 USART2_RX_STA;         		//接收狀態(tài)標(biāo)記	



#define false 0
#define true 1

//定義數(shù)組長(zhǎng)度
#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數(shù)據(jù)
	char isParseData;	//是否解析完成
	char UTCTime[UTCTime_Length];		//UTC時(shí)間
	char latitude[latitude_Length];		//緯度
	char N_S[N_S_Length];		//N/S
	char longitude[longitude_Length];		//經(jīng)度
	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. 配置完串口后,我們需要開始編寫我們的控制函數(shù),包括模塊的讀忙,發(fā)送相關(guān)的功能控制函數(shù)等基礎(chǔ)功能

JR6001.c

功能函數(shù)的編寫

#include "JR6001.h"

#include "usart.h"
#include "delay.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
// 延時(shí)函數(shù)重定義 JR6001延時(shí)函數(shù)定義,用戶自行更改為自己的延時(shí)函數(shù)
#define JR6001_ms(ms) delay_ms(ms)
#define JR6001_us(us) delay_us(us)

void JR6001_Volumecontrol(u8 num);

void JR6001_Init(void)
{
	// GPIO端口設(shè)置
	GPIO_InitTypeDef GPIO_InitStructure;

#ifdef JR6001_BUSY // 查忙引腳配置

	RCC_APB2PeriphClockCmd(JR6001_BUSY_GPIO_CLK, ENABLE); // 使能POR時(shí)鐘
	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); // 設(shè)置音量
	JR6001_ms(100);
}

// 串口發(fā)送數(shù)據(jù)
void JR6001_SendCode(u8 *str, u8 busy)
{
	u16 len, i;
	len = strlen((char *)str);
	printf("%sn", str);

	if (busy == 1 && JR6001_BUSY_IO == 0)
	{
		for (i = 0; i <= len; i++) // 循環(huán)發(fā)送數(shù)據(jù)
		{
			while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
				; // 循環(huán)發(fā)送,直到發(fā)送完畢
			USART_SendData(USART2, str[i]);
		}
	}
	else if (busy == 0)
	{
		for (i = 0; i <= len; i++) // 循環(huán)發(fā)送數(shù)據(jù)
		{
			while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
				; // 循環(huán)發(fā)送,直到發(fā)送完畢
			USART_SendData(USART2, str[i]);
		}
	}
	JR6001_ms(10);
}
// 基礎(chǔ)指令發(fā)送
void JR6001_Instruction(u8 *str, u8 busy)
{
	u8 JR6001_Buff[20];
	sprintf((char *)JR6001_Buff, "%srn", 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%drn", num);
		JR6001_SendCode(JR6001_Buff, busy);
	}
	else if (num < 100)
	{
		sprintf((char *)JR6001_Buff, "A7:000%drn", num);
		JR6001_SendCode(JR6001_Buff, busy);
	}
	else
	{
		sprintf((char *)JR6001_Buff, "A7:00%drn", num);
		JR6001_SendCode(JR6001_Buff, busy);
	}
}
// 音量選擇
void JR6001_Volumecontrol(u8 num)
{
	u8 JR6001_Buff[20];
	sprintf((char *)JR6001_Buff, "AF:%drn", num);
	JR6001_SendCode(JR6001_Buff, 0);
}

/*
	JR6001_Init();
	JR6001_SongControl(5,0);

*/

JR6001.h

功能函數(shù)的定義

#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);
// 串口發(fā)送數(shù)據(jù)
void JR6001_SendCode(u8 *str, u8 busy);
// 基礎(chǔ)指令發(fā)送
void JR6001_Instruction(u8 *str, u8 busy);
// 曲目選擇
void JR6001_SongControl(u8 num, u8 busy);
// 音量選擇
void JR6001_Volumecontrol(u8 num);
#endif

三、參考

【STM32】 JR6001語(yǔ)音播放icon-default.png?t=N7T8https://blog.csdn.net/m0_56051805/article/details/125116764?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170200319216800184185082%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170200319216800184185082&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-125116764-null-null.142^v96^pc_search_result_base7&utm_term=stm32JR6001&spm=1018.2226.3001.4187


完整代碼請(qǐng)關(guān)注衛(wèi)星公眾號(hào)進(jìn)行獲取和咨詢


聯(lián)系方式 微信號(hào):13648103287

  • 聯(lián)系方式.docx

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

方案定制,程序設(shè)計(jì)方案、單片機(jī)程序設(shè)計(jì)與講解、APP定制開發(fā)。本公眾號(hào)致力于向讀者傳遞關(guān)于程序設(shè)計(jì)和開發(fā)的相關(guān)知識(shí),并分享一些關(guān)于軟件開發(fā)的最佳實(shí)踐。如果您有什么問題或建議,請(qǐng)隨時(shí)聯(lián)系我們。我們將竭誠(chéng)為您服務(wù)