一.了解JQ8400模块
1.管脚说明
引脚 | 标示 | 说明 |
1 | ONE LINE | 一线串口脚 |
2 | BUSY | 忙信号脚,播放时为高,其他为低 |
3 | RX | 芯片串口接收脚,接MCU的TX |
4 | TX | 芯片串口发送脚,接MCU的RX |
5 | GND | 芯片数字地 |
6 | DC-5V | 芯片供电脚,3.3-5V |
7 | DAC-R | DAC音频输出右声道 |
8 | DAC-L | DAC音频输出左声道 |
9 | SPK- | 接喇叭 |
10 | SPK+ |
2.一线串口通信协议
SDA为数据发送端口,发送语音地址,先发送低位。
3.一线数据指令
指令(HEX) | 功能 | 说明 |
00 | 数字0 | 数字0-9可以用于需要数字的功能, 比如选曲、设置音量、设置EQ、 设置循环模式、设置通道、设置插播曲目 先发数字后发功能指令。 |
01 | 数字1 | |
02 | 数字2 | |
03 | 数字3 | |
04 | 数字4 | |
05 | 数字5 | |
06 | 数字6 | |
07 | 数字7 | |
08 | 数字8 | |
09 | 数字9 | |
0A | 清零数字 | 清除发送的数字 |
0B | 选曲确认 | 配 合 数 字 实 现 |
0C | 设置音量0-30 | |
0D | 设置EQ | |
0E | 设置循环模式 | |
0F | 设置通道 | |
10 | 设置插播曲目 | |
11 | 播放 | 单字节控制指令, 仅需发送一个控制指令即可。 |
12 | 暂停 | |
13 | 停止 | |
14 | 上一曲 | |
15 | 下一曲 | |
16 | 上一目录 | |
17 | 下一目录 | |
18 | 选择SD卡 | |
19 | 选择U盘 | |
1A | 选择FLASH | |
1B | 系统睡眠 |
4.一线串口MP3文件命名规则
(1)文件名需为5位数字,该五位数即为文件的曲目号。
(2)文件需放在根目录下。
5.一线串口说明和注意事项
(1)引导码延时要求大于2MS,建议使用4MS延时
(2)脉冲比例基数在2-5都可以识别
(3)两个字节之间延时建议在10MS以上
二.模块基本使用
1.下载对应语音
2.格式化JQ8400移入语音
链接typec口
注意格式
必须是按顺序进行
3.代码实现
jq8400.c
#include "jq8400.h"
/*
* @brief 初始化控制JQ8400的串口2
*/
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd( USART_RX_CLK | USART_TX_CLK , ENABLE);//串口GPIO时钟
RCC_APB1PeriphClockCmd( UserPeriph_USARTx ,ENABLE);//串口外设时钟
GPIO_InitStructure.GPIO_Pin = USART_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USART_TX_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USART_RX_PORT, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1 ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init( UserUSARTx,&USART_InitStructure);
USART_Cmd( UserUSARTx,ENABLE);
}
/***************** 发送一个 32 位数 **********************/
void Usart_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 Usart_Send8bit( USART_TypeDef * pUSARTx, uint8_t eight)
{
/* 发送一个字节数据到 USART */
USART_SendData(pUSARTx,eight);
/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/***************** 循环模式:单曲停止 **********************/
void asong_stop(void)
{
Usart_Send32bit( UserUSARTx, 0xAA180102);
Usart_Send8bit( UserUSARTx, 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(u16 i)
{
Usart_Send32bit( UserUSARTx,0xAA070200);
Usart_Send8bit( UserUSARTx, 0x00+i);
Usart_Send8bit( UserUSARTx, 0xB3+i);//控制指令要48位,故拆分开,32位+8位+8位
}
jq8400.h
#ifndef __JQ8400_H
#define __JQ8400_H
#include "stm32f10x.h"
/*串口2总线*/
#define UserUSARTx USART2
#define UserPeriph_USARTx RCC_APB1Periph_USART2
/*串口2GPIO*/
// RX
#define USART_TX_PORT GPIOA /* GPIO端口 */
#define USART_TX_CLK RCC_APB2Periph_GPIOA /* GPIO端口时钟 */
#define USART_TX_PIN GPIO_Pin_2 /* 连接到SCL时钟线的GPIO */
// TX
#define USART_RX_PORT GPIOA
#define USART_RX_CLK RCC_APB2Periph_GPIOA
#define USART_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 Usart_Send8bit( USART_TypeDef * pUSARTx, uint8_t eight);
void USART_Config(void);
void Usart_Send32bit( USART_TypeDef * pUSARTx, uint32_t ch);
void asong_stop(void);
void playsong(u16 i);
void playsong2(u16 i,u16 a);
#endif /* __JQ8400_H */
main.c
//用于判断数据播报
void numberPlay(int number) {
switch (number) {
case 1:
playsong(1);
break;
case 2:
playsong(2);
break;
case 3:
playsong(3);
break;
case 4:
playsong(4);
break;
case 5:
playsong(5);
break;
case 6:
playsong(6);
break;
case 7:
playsong(7);
break;
case 8:
playsong(8);
break;
case 9:
playsong(9);
break;
// 可以添加一个默认情况来处理非1-9的数字(可选)
default:
// 这里可以添加一些代码来处理未知的数字,或者什么都不做
break;
}
}
//处理数据播报
u8 Q8400temp;
int integer_part,tens_place,units_place,first_decimal_place,second_decimal_place;
float decimal_part;
void ProcessingDataBroadcast(float res){
// 整数部分和小数部分的分离
integer_part = (int)res;
decimal_part = res - integer_part;
// 提取十位
tens_place = (integer_part / 10) % 10;
// 提取个位
units_place = integer_part % 10;
// 提取小数点后一位
decimal_part *= 10; // 将小数点右移一位
first_decimal_place = (int)decimal_part % 10;
// 提取小数点后二位
decimal_part = res - (int)res - first_decimal_place / 10.0; // 更新小数部分,去掉已处理的一位
decimal_part *= 100; // 将小数点右移两位
second_decimal_place = (int)decimal_part % 10;
// 输出最大值100
if (res == 100) {
delay_ms(600);
playsong(1);
delay_ms(600);
playsong(12);
}
// 输出20-99
if(res<=99&&res>=20){
delay_ms(600);
numberPlay(tens_place);
delay_ms(600);
playsong(11);
delay_ms(600);
numberPlay(units_place);
}
//十位数据播报
if(res>=10&&res<=20){
delay_ms(600);
playsong(11);
delay_ms(600);
numberPlay(units_place);
}
//个位数
if(res<10){
delay_ms(600);
numberPlay(units_place);
}
//处理小数位
if(first_decimal_place!=0||second_decimal_place!=0){
delay_ms(600);
playsong(21);
delay_ms(600);
//处理第一位为0的情况
if(first_decimal_place==0){
delay_ms(600);
playsong(10);
delay_ms(600);
}
playsong(first_decimal_place);
delay_ms(800);
playsong(second_decimal_place);
delay_ms(600);
}
}
//直接调用此函数 在当前函数中修改值
void q8400_out(){
delay_ms(800);
//温度
playsong(18);
delay_ms(800);
ProcessingDataBroadcast(wd);
delay_ms(600);
//温度
playsong(19);
delay_ms(800);
ProcessingDataBroadcast(zd);
delay_ms(800);
//温度
playsong(20);
delay_ms(1000);
ProcessingDataBroadcast(ph);
}
语音编号说明
编号 | 描述 |
---|---|
00001 | 1-9 |
00002 | - |
00003 | - |
00004 | - |
00005 | - |
00006 | - |
00007 | - |
00008 | - |
00009 | - |
00010 | 0 |
00011 | 十 |
00012 | 百 |
00013 | 千 |
00014 | ph值过高 |
00015 | ph值过低 |
00016 | 浑浊度过高 |
00017 | 温度过高 |
00018 | 温度 |
00019 | 浊度 |
00020 | 浊度 |
00021 | 点 |