STM32 drives JQ8900 voice module

Last time I wrote the esp32 driver JQ8900 module. When I design, I usually implement the peripherals on the esp32 first, and then transplant them to the more complex stm32. Directly upload the dry code that is running normally.


1. Hardware preparation

Any development board of STM32F10x series (here I use f103zet6 punctual atomic development board)
One JQ8900 broadcast module, one speaker, one 12V/5V power adapter, several DuPont lines

2. Programming

1.jq8900.c

code show as below:

#include "jq8900.h"
#include "delay.h"
#include "stm32f10x.h"
 
///
//函	  OnUart_GPIO(void)
//功	  能:语音模块一线串口IO口
//输入参数: void
//输出参数: void
//说	  明:
//
void OnUart_GPIO(void)
{
    
    
	GPIO_InitTypeDef  GPIO_InitStructure;
 
		RCC->APB2ENR|=1<<3;   //GPIOB
		
		//GPIOB.11
		GPIOB->CRH&=0xFFFF0FFF;     //清零 
		GPIOB->CRH|=0x00003000;     //推挽输出	50MHZ
		GPIOB->ODR=~(1<<11);        //B.11低	
 
	
}
void delay1_us(u32 nTimer)
{
    
    
	u32 i=0;
	for(i=0;i<nTimer;i++){
    
    
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
	}
}
///
//函	  数:SendData(u8 addr)
//功	  能:语音模块一线串口
//输入参数: addr要发送的0x数
//输出参数: void
//说	  明:
//
void SendData(u8 addr)//发送函数。
{
    
    
    u8 i;
 
     /*发送时关掉中断,防止中断影响时序  */
    SDA = 1; /*开始拉高*/
    delay1_us ( 1000 );
    SDA = 0; /*开始引导码*/
    delay1_us ( 3200 );/*此处延时最少要大于2ms*/
    for ( i = 0; i < 8; i++ ) /*总共8位数据  */
    {
    
    
        SDA = 1;
        if ( addr & 0x01 ) /*3:1表示数据位1,每个位用两个脉冲表示  */
        {
    
    
            delay1_us ( 600 );
            SDA = 0;
            delay1_us ( 200 );
        }
        else              /*1:3表示数据位0 ,每个位用两个脉冲表示  */
        {
    
    
            delay1_us ( 200 );
            SDA = 0;
            delay1_us ( 600 );
        }
        addr >>= 1;
    }
    SDA = 1;
    
		//恢复中断
}

This code is mainly to initialize and send data to the first-line serial port of the voice module.

In the initialization process, use GPIOB.11 as the data line of a serial port, set it as push-pull output mode, and pull it low.

When sending data, first pull the data line high for 1ms as the start signal, and then send the boot code, which is a low level of more than 2ms, indicating the start of data transmission. Then send data, each data bit is represented by two pulses, in which data bit 1 is represented by two pulses with high level occupying 600us and low level occupying 200us, data bit 0 is represented by high level occupying 200us and low level occupying 200us Two pulses of 600us represent. Finally, pull the data line high to indicate the end of data transmission.

It should be noted that the interrupt needs to be turned off when sending data to prevent the interrupt from affecting the timing. The interrupt needs to be resumed after the data has been sent.

2.jq8900.h

code show as below:

#ifndef __JQ8900_H
#define __JQ8900_H
 
#include "sys.h"
 
#define SDA PBout(11)
 
void SendData ( u8 addr );    //发送函数。
void OnUart_GPIO(void);       //GPIO
void delay1_us(u32 nTimer);
void show_number1();
#endif

3.main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "jq8900.h"

 int main(void)
 {
    
    	
	delay_init();	    //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	OnUart_GPIO();
	while(1)
	{
    
    
    show_number1();
    delay_ms(2000);
	}
 }

A very simple piece of code, after initializing the first-line serial port, call the function show_number1() in an endless loop to play the audio every 2 seconds. Similar to calling audio from esp32, a program to play audio 1 is also written.

void show_number1()
{
    
    
    //设置音量为20
    SendData(0x0a);    //清空数字
    SendData(0x02);    //音量20
    SendData(0x00);
    SendData(0x0c);    //设置音量
    delay_ms(2000);    //延时
    
    //选取曲目1播放
    SendData(0x0a);//清空数字
    SendData(0x01);//曲目数字,对应00001.mp3
    SendData(0x0b);//选曲播放
    delay_ms(2000);
    
    //开始播放
    //SendData(0x11);//开始播放
    //delay(2000);
}

This code is mainly to operate the voice module, realizing functions such as playing the specified track and setting the volume.

When playing the specified track, the voice module is made to play the specified track by sending the number corresponding to the track and the selected track play command. In this code, track 1 is selected to play.

When setting the volume, let the voice module set the specified volume by sending the number corresponding to the volume and the command to set the volume. In this code, the volume is set to 20.

3. Audio Replacement

JQ8900 can be connected to the computer through a data cable, similar to a small U disk, we can use some text-to-language software to generate some desired .MP3 format files, and modify the name to 0000x. Note that the flash of JQ8900 is only 4M, so it is best not to import some large-scale audio, as it will take up too much space.

Summarize

An article was written, but the further application of the JQ8900 module was also completed.

Guess you like

Origin blog.csdn.net/qq_53092944/article/details/130412377