语音模块(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.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 新冠病毒尚未撤去