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

文章简介:
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.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 新冠病毒尚未撤去

猜你喜欢

转载自blog.csdn.net/weixin_42899627/article/details/104978102