欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

语音模块(JQ8400-FL)+stm32f103vet6(野火)含代码(亲测有效)

程序员文章站 2024-02-23 16:09:40
...
文章简介:
1.JQ8400-FL语音模块,带3W功放,有4M的存储空间,可通过USB拷贝声音文件,通过单片机串口控制
2.听说可以一线串口通信,我没试过,也不知道行不行,我才用的是二线串口通信
3.使用的是stm32板子上串口2的GPIO,分别是PA2<-->RX,PA3<-->TX,代码是没问题的,已经运行过的
4.stm32f103vet6的板子是野火的,语音模块是在淘宝上买的
5.我没有打广告的意思,纯粹分享一下知识,希望能有帮助
6.说明书和代码我会直接把资料链接放出来,你们自己下载就好,说明书其实你自己买模板商家会给的
STM32F103VET6

usart2                  |   jq8400
PA2(tx推挽复用模式)      |     RX
PA3(rx浮空输入模式)      |     TX

APB1时钟总线

语音模块

引脚 标示 说明
1 ONE LINE 一线串口脚
2 BUSY 忙信号脚,播放时为高,其它为低
3 RX 芯片串口接收脚,接MCU的TX脚
4 TX 芯片的串口发送脚,接MCU的RX脚
5 GND 芯片数字地
6 DC-5V 芯片供电脚,3.3-5.0V
7 DAC-R DAC音频输出右声道
8 DAC-L DAC音频输出左声道
9 SPK- 接喇叭
10 SPK+
语音模块(JQ8400-FL)+stm32f103vet6(野火)含代码(亲测有效)
语音模块(JQ8400-FL)+stm32f103vet6(野火)含代码(亲测有效)

代码部分

jq8400.h

#ifndef __JQ8400_H
#define	__JQ8400_H


#include "stm32f10x.h"

/*串口2总线*/

/*串口2GPIO*/
// RX
#define USART2_TX_PORT    	    GPIOA			              /* GPIO端口 */
#define USART2_TX_CLK 	        RCC_APB2Periph_GPIOA		/* GPIO端口时钟 */
#define USART2_TX_PIN		        GPIO_Pin_2			        /* 连接到SCL时钟线的GPIO */

// TX
#define USART2_RX_PORT    	    GPIOA			              
#define USART2_RX_CLK 	        RCC_APB2Periph_GPIOA		
#define USART2_RX_PIN		        GPIO_Pin_3			        

// BUSY
//#define JQ8400_BUSY    	    GPIOA			              /* GPIO端口 */
//#define JQ8400_BUSY_CLK 	  RCC_APB1Periph_GPIOA		/* GPIO端口时钟 */
//#define JQ8400_BUSY_PIN		  GPIO_Pin_5			        /* 连接到SCL时钟线的GPIO */


void Usart2_Send8bit( USART_TypeDef * pUSARTx, uint8_t eight);
void USART2_Config(void);
void Usart2_Send32bit( USART_TypeDef * pUSARTx, uint32_t ch);
void asong_stop(void);
void playsong(int i);

#endif /* __JQ8400_H */

jq8400.c

#include "jq8400.h"   

 /*
  * @brief  初始化控制JQ8400的串口2
  */
void USART2_Config(void)
{		
		GPIO_InitTypeDef GPIO_InitStructure;
	  USART_InitTypeDef USART2_InitStructure;

		RCC_APB2PeriphClockCmd( USART2_RX_CLK | USART2_TX_CLK , ENABLE);//串口GPIO时钟
	  RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2 ,ENABLE);//串口外设时钟
	
		GPIO_InitStructure.GPIO_Pin = USART2_TX_PIN;	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(USART2_TX_PORT, &GPIO_InitStructure);
	
	  GPIO_InitStructure.GPIO_Pin = USART2_RX_PIN;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
		GPIO_Init(USART2_RX_PORT, &GPIO_InitStructure);	
		
	
	  USART2_InitStructure.USART_BaudRate = 9600;
	  USART2_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
	  USART2_InitStructure.USART_Parity = USART_Parity_No;
	  USART2_InitStructure.USART_StopBits = USART_StopBits_1 ;
	  USART2_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	  USART2_InitStructure.USART_WordLength = USART_WordLength_8b;
		
		USART_Init( USART2,&USART2_InitStructure);
		
		USART_Cmd( USART2,ENABLE);
		
}

/***************** 发送一个 32 位数 **********************/
void Usart2_Send32bit( USART_TypeDef * pUSARTx, uint32_t ch)
{
   uint8_t temp_1, temp_2, temp_3, temp_4; //4个8位

   /* 取出第一八位 */
   temp_1 = (ch&0XFF000000)>>24;
   /* 取出第二八位 */
   temp_2 = (ch&0X00FF0000)>>16;
	 /* 取出第三八位 */
   temp_3 = (ch&0X0000FF00)>>8;
   /* 取出第四八位 */
   temp_4 = (ch&0X000000FF);

   /* 发送第一八位 */
   USART_SendData(pUSARTx,temp_1);
   while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
   /* 发送第二八位 */
   USART_SendData(pUSARTx,temp_2);
   while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
	 /* 发送第三八位 */
   USART_SendData(pUSARTx,temp_3);
   while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
   /* 发送第四八位 */
   USART_SendData(pUSARTx,temp_4);
   while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
 }

/***************** 发送一个 8 位数 **********************/ 
void Usart2_Send8bit( USART_TypeDef * pUSARTx, uint8_t eight)
{
   /* 发送一个字节数据到 USART */
   USART_SendData(pUSARTx,eight);

   /* 等待发送数据寄存器为空 */
   while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
 
/***************** 循环模式:单曲停止 **********************/ 
void asong_stop(void)
{
	 Usart2_Send32bit( USART2, 0xAA180102);
	 Usart2_Send8bit( USART2, 0xC5);
}

/***************** 播放模式:指定歌曲(playsong(1):播放00001曲目) **********************/ 
//曲目的文件名需要按指定格式来保存的,使用说明书上有写
/*
指定曲目(07)
指令:AA 07 02 曲目高 曲目低 SM
返回:无
和检验(SM):为之前所有字节之和的低8位,即前面的数据相加后取低8位
例如:  AA 07 02 00 08 BB 指定播放当前盘符第8首(AA+07+02+00+08=BB取低8位,即为BB)
*/
void playsong(int i)
{
	switch(i)
	{
		case 1:	 
	    Usart2_Send32bit( USART2,0xAA070200);
	    Usart2_Send8bit( USART2, 0x01);
	    Usart2_Send8bit( USART2, 0xB4);//控制指令要48位,故拆分开,32位+8位+8位
		  break;
		case 2:	 
	    Usart2_Send32bit( USART2,0xAA070200);
	    Usart2_Send8bit( USART2, 0x02);
	    Usart2_Send8bit( USART2, 0xB5);
		  break;
		case 3:	 
	    Usart2_Send32bit( USART2,0xAA070200);
	    Usart2_Send8bit( USART2, 0x03);
	    Usart2_Send8bit( USART2, 0xB6);
		  break;
		case 4:	 
	    Usart2_Send32bit( USART2,0xAA070200);
	    Usart2_Send8bit( USART2, 0x04);
	    Usart2_Send8bit( USART2, 0xB7);
		  break;
		default:
			Usart2_Send32bit( USART2,0xAA070200);
	    Usart2_Send8bit( USART2, 0x05);
	    Usart2_Send8bit( USART2, 0xB8);

	}

}

main.c

#include "stm32f10x.h"
#include "jq8400.h"

#define SOFT_DELAY Delay(0xFFFFFF);

void Delay(__IO u32 nCount); 

int main(void)
{	
	/* 串口2初始化 */
	USART2_Config();
	
	playsong(1);	
	 SOFT_DELAY;	
	playsong(5);
	
	while (1)
	{
	}
}

void Delay(__IO uint32_t nCount)	 //简单的延时函数
{
	for(; nCount != 0; nCount--);
}


我是做毕设才接触到这个玩意,语音模块找了很久才决定买这个试一试,毕竟串口通信相对熟悉一些,买回来一个上午就弄好了,我当时借鉴了一位博主的代码,本来想放上链接,只是当时没有保存,一时之间也找不到,总之CSDN这里还是很多有用的东西的,看很多东西都会有启发,希望继续努力。
——写于2020/3/20 新冠病毒尚未撤去