嵌入式
返回首页

【CW32模块使用】JQ8900语音播报模块

2025-06-20 来源:elecfans

一、模块来源

模块实物展示:

wKgZO2flNVeAbAFRAABAhDLsu-A072.jpg

二、规格参数

输入电压:2.8V-5.5V

IO电压:3.3V(模块引脚输出电压)

额定电流:500uA~10mA

控制方式:串口

以上信息见厂家资料文件

三、移植过程

3.1查看资料

此芯片最大的优势在于能够灵活的更换 SPI-flash 内的语音内容,省去了传统语音芯片需要安装上位机更换语音的麻烦,SPI FLASH 直接模拟成 U 盘,跟拷贝 U 盘一样,非常方便。使得产品研发和生产变得便捷简单。一线串口控制模式、RX232 串口控制可选,为研发提供更多的选择性。

USB 数据线连接芯片,插上电脑,电脑会自动识别,如下图所示:出厂内部自带了10首语音。

注意语音内容不可太长,防止内存不够。

wKgZPGflNViAMm9_AAAKyPqxJ6s135.jpg

电脑自动识别

wKgZO2flNViAKKV_AAB6xIEDNfs719.jpg

U盘内部

该模块分有单独IO控制、一线串行控制、两线串口控制。

单独IO口控制

如果需要更新语音,把要放置的声音拷贝过去按照相应格式命名即可。按 5 位数字进行命名,即 00001、00002......00007。

wKgZPGflNVmAAtnGAAAzRsUaYe4351.jpg

一线串行控制

wKgZO2flNVmAWrr3AAA7Ei5FCRM166.jpg

wKgZPGflNVmAF5UJAABYPmCaY54138.jpg

wKgZO2flNVqARMKdAABBckeJ_j0474.jpgwKgZPGflNVqAPpLeAACY-HcQqCo313.jpg

两线串口控制

波特率为 9600,数据位:8 ,停止位 1 位,检验位 N

3.2引脚选择

wKgZO2flNVuAU48IAACJqj2qbzk467.jpgwKgZPGflNVuAcSyyAACztIIqoBA012.jpgwKgZO2flNVyAQ_yqAAj1GCCoh-8548.jpg

模块接线图

3.3移植至工程

移植步骤中的导入.c和.h文件与【CW32模块使用】DHT11温湿度传感器相同,只是将.c和.h文件更改为bsp_jq8900.c与bsp_jq8900.h。这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_jq8900.c中,编写如下代码。



/*

 * Change Logs:

 * Date           Author       Notes

 * 2024-06-25     LCKFB-LP    first version

 */

#include 'bsp_jq8900.h'

#include 'stdio.h'

#include 'string.h'



unsigned char JQ8900_RX_BUFF[JQ8900_RX_LEN_MAX];

unsigned char JQ8900_RX_FLAG = 0;

unsigned char JQ8900_RX_LEN = 0;



/************************************************************

 * 函数名称:JQ8900_USART_Init

 * 函数说明:连接JQ8900的初始化

 * 型    参:bund=串口波特率

 * 返 回 值:无

 * 备    注:无

*************************************************************/

void JQ8900_USART_Init(unsigned int bund)

{

    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体


    BSP_JQ8900_GPIO_RCC_ENABLE();        // 使能GPIO时钟

    BSP_JQ8900_UART_RCC_ENABLE();        // 使能UART时钟


    GPIO_InitStruct.Pins = BSP_JQ8900_TX_PIN;            // GPIO引脚

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;          // 推挽输出

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;             // 输出速度高

    GPIO_Init(BSP_JQ8900_GPIO_PORT, &GPIO_InitStruct);   // 初始化


    GPIO_InitStruct.Pins = BSP_JQ8900_RX_PIN;            // GPIO引脚

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;       // 上拉输入

    GPIO_Init(BSP_JQ8900_GPIO_PORT, &GPIO_InitStruct);   // 初始化


    BSP_JQ8900_AF_UART_TX(); // UART_TX复用

    BSP_JQ8900_AF_UART_RX(); // UART_RX复用


    // 配置UART

    USART_InitTypeDef USART_InitStructure;


    USART_InitStructure.USART_BaudRate = bund;                                     // 波特率

    USART_InitStructure.USART_Over = USART_Over_16;                     // 配置USART的过采样率。

    USART_InitStructure.USART_Source = USART_Source_PCLK;               // 设置时钟源

    USART_InitStructure.USART_UclkFreq = 64000000;                      //设置USART时钟频率(和主频一致即可)

    USART_InitStructure.USART_StartBit = USART_StartBit_FE;             //RXD下降沿开始

    USART_InitStructure.USART_StopBits = USART_StopBits_1;              // 停止位1

    USART_InitStructure.USART_Parity = USART_Parity_No ;                // 不使用校验

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 不使用流控

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;     // 收发模式

    USART_Init(BSP_JQ8900_UART, &USART_InitStructure);                  // 初始化串口2


    // 优先级,无优先级分组

    NVIC_SetPriority(BSP_JQ8900_IRQ, 0);


    // UARTx中断使能

    NVIC_EnableIRQ(BSP_JQ8900_IRQ);


    // 使能UARTx RC中断

    USART_ITConfig(BSP_JQ8900_UART, USART_IT_RC, ENABLE);

}


/******************************************************************

 * 函 数 名 称:JQ8900_USART_Send_Bit

 * 函 数 说 明:向JQ8900模块发送单个字符

 * 函 数 形 参:ch=字符

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:无

******************************************************************/

void JQ8900_USART_Send_Bit(unsigned char ch)

{

    USART_SendData(BSP_JQ8900_UART, (uint8_t)ch);


    while( RESET == USART_GetFlagStatus(BSP_JQ8900_UART, USART_FLAG_TXE) ){} // 等待发送数据缓冲区标志置位

}



/******************************************************************

 * 函 数 名 称:JQ8900_USART_send_String

 * 函 数 说 明:向JQ8900模块发送字符串

 * 函 数 形 参:str=发送的字符串

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:无

******************************************************************/

void JQ8900_USART_send_String(unsigned char *str, unsigned int len)

{

        while( len-- )

        {

                JQ8900_USART_Send_Bit(*str++);

        }

}

//清除串口接收的数据

/******************************************************************

 * 函 数 名 称:Clear_JQ8900_RX_BUFF

 * 函 数 说 明:清除JQ8900发过来的数据

 * 函 数 形 参:无

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:无

******************************************************************/

void Clear_JQ8900_RX_BUFF(void)

{

        unsigned char i = JQ8900_RX_LEN_MAX-1;

        while(i)

        {

                JQ8900_RX_BUFF[i--] = 0;

        }

        JQ8900_RX_LEN = 0;

        JQ8900_RX_FLAG = 0;

}




/******************************************************************

 * 函 数 名 称:JQ8900_Init

 * 函 数 说 明:JQ8900模块初始化

 * 函 数 形 参:无

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:JQ8900的默认波特率是9600

******************************************************************/

void JQ8900_Init(void)

{

    JQ8900_USART_Init(9600);//默认波特率为9600


    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体


    BSP_JQ8900_GPIO_RCC_ENABLE();        // 使能GPIO时钟


    GPIO_InitStruct.Pins = GPIO_JQ8900_APP;              // GPIO引脚

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;          // 推挽输出

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;             // 输出速度高

    GPIO_Init(BSP_JQ8900_GPIO_PORT, &GPIO_InitStruct);   // 初始化


    SET_JQ8900_APP(1);

}




/**********************************************************

 * 函 数 名 称:SendData

 * 函 数 功 能:一线串行通信控制

 * 传 入 参 数:addr=发送的指令

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:无

**********************************************************/

void SendData ( unsigned char  addr )

{

    unsigned char i;

    SET_JQ8900_APP(1); /*开始拉高  */

    delay_us ( 500 );

    SET_JQ8900_APP(0);/*开始引导码*/

    delay_ms ( 4 );/*此处延时最少要大于2ms,官方建议4MS  */

    for ( i = 0; i < 8; i++ ) /*总共8位数据,从低位开始  */

    {

                //数据总是从1开始

        SET_JQ8900_APP(1);

        if ( addr & 0x01 )

        {

            delay_us ( 1300 );/*3:1表示数据位1,每个位用两个脉冲表示  */

           SET_JQ8900_APP(0);

            delay_us ( 500 );

        }

        else

        {

            delay_us ( 500 );/*1:3表示数据位0 ,每个位用两个脉冲表示  */

            SET_JQ8900_APP(0);

            delay_us ( 1300 );

        }

        addr >>= 1;

    }

    SET_JQ8900_APP(1);

        delay_ms(10);//两个字节之间延时建议在10ms以上

}




/******************************************************************

 * 函 数 名 称:JQ8900_USART_IRQHandler

 * 函 数 说 明:连接JQ8900的串口中断服务函数

 * 函 数 形 参:无

 * 函 数 返 回:无

 * 作       者:LC

 * 备       注:无

******************************************************************/

void JQ8900_USART_IRQHandler(void)

{

    if(USART_GetITStatus(BSP_JQ8900_UART,USART_IT_RC) != RESET) // 接收缓冲区不为空

    {

                                    //接收数据

        JQ8900_RX_BUFF[ JQ8900_RX_LEN ] = USART_ReceiveData(BSP_JQ8900_UART);


        #if DEBUG

                //测试,查看接收到了什么数据

                printf('%c', JQ8900_RX_BUFF[ JQ8900_RX_LEN ]);

        #endif


        //接收长度限制

        JQ8900_RX_LEN = ( JQ8900_RX_LEN + 1 ) % JQ8900_RX_LEN_MAX;


        JQ8900_RX_BUFF[JQ8900_RX_LEN] = '�'; //字符串结尾补 '�'

        JQ8900_RX_FLAG = SET;            // 接收完成


        USART_ClearITPendingBit(BSP_JQ8900_UART, USART_IT_RC); // 清除中断标志位

    }

}



在文件bsp_jq8900.h中,编写如下代码。




/*

 * Change Logs:

 * Date           Author       Notes

 * 2024-06-25     LCKFB-LP    first version

 */


#ifndef _BSP_JQ8900_H_

#define _BSP_JQ8900_H_


#include 'string.h'

#include 'board.h'



//是否开启串口调试,查看WIFI回显数据

#define     DEBUG   1



#define JQ8900_RX_LEN_MAX        250 //串口接收最大长度



/****************************   串口配置    ****************************/

#define BSP_JQ8900_GPIO_RCC_ENABLE()  __RCC_GPIOA_CLK_ENABLE()   // 串口TX的端口时钟

#define BSP_JQ8900_UART_RCC_ENABLE()  __RCC_UART2_CLK_ENABLE()   // 串口2的时钟


#define BSP_JQ8900_AF_UART_TX()       PA02_AFx_UART2TXD()

#define BSP_JQ8900_AF_UART_RX()       PA03_AFx_UART2RXD()


#define BSP_JQ8900_GPIO_PORT          CW_GPIOA          // GPIO的端口


#define BSP_JQ8900_TX_PIN             GPIO_PIN_2        // 串口TX的引脚

#define BSP_JQ8900_RX_PIN             GPIO_PIN_3        // 串口RX的引脚


#define BSP_JQ8900_UART               CW_UART2          // 串口2

#define BSP_JQ8900_IRQ                UART2_IRQn        // 串口2中断

#define BSP_JQ8900_IRQHandler         UART2_IRQHandler  // 串口2中断服务函数


#define GPIO_JQ8900_APP               GPIO_PIN_1


#define SET_JQ8900_APP(x)             GPIO_WritePin(BSP_JQ8900_GPIO_PORT, GPIO_JQ8900_APP, x?GPIO_Pin_SET:GPIO_Pin_RESET);



void JQ8900_Init(void);

void JQ8900_USART_send_String(unsigned char *str, unsigned int len);

void SendData ( unsigned char  addr );

void JQ8900_USART_Send_Bit(unsigned char ch);

#endif



四、移植验证


在自己工程中的main主函数中,编写如下。




/*

 * Change Logs:

 * Date           Author       Notes

 * 2024-06-25     LCKFB-LP    first version

 */

#include 'board.h'

#include 'stdio.h'

#include 'bsp_uart.h'

#include 'bsp_jq8900.h'


int32_t main(void)

{

    //下一曲(没有指定曲目则从1开始一直播报到最后)

    uint8_t send_buff[4] = {0xAA,0x06,0x00,0xB0};


    board_init();

    uart1_init(115200U);


    JQ8900_Init();


    printf('Start...rn');


    while(1)

    {

        //两线串口测试

        JQ8900_USART_send_String(send_buff,4);

        delay_ms(3000);

    }

}



移植现象:


移植现象:持续播报模块内部的全部语音。


模块移植成功案例代码:


链接:https://pan.baidu.com/s/1XcBxcE_BNWIzfEHu9G5c1g?pwd=LCKF


提取码:LCKF


进入嵌入式查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • FollowMe 第二季:3 - EK_RA6M5 开发板入门

  • FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解

  • Azure RTOS step by step workshop

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • 从0到1:树莓派与物联网教程(英文)

精选电路图
  • 1瓦线性调频增强器

  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 红外开关

  • LM317过压保护

  • 0-30V/20A 大功率稳压电源(采用LM338)

    相关电子头条文章