MY1690-12P语音模块实现特定的语音提示功能

(22) 2024-04-02 07:01:01

一、MY1690 MP3解码模块介绍

MY1690-12P是深圳市迈优科技有限公司自主研发的一款小巧的微集成MP3模块。采用MY1690-SOP16 MP3主控芯片,支持MP3、WAV格式双解码。模块最大支持32G TF卡;也可外接U盘或USB数据线连接电脑更换SD卡音频文件。该模块内置3W功放,可以直接驱动3W的喇叭,使用更方便。

 

二、串口控制协议

MY1690-12P内置标准UART异步串口接口,为3.3V TTL电平接口。可通过MAX3232芯片转换成RS232电平或者通过USB转TTL模块与PC通讯进行调试。通讯数据格式是:起始位:1位;数据位:8位;奇偶位:无;停止位:1位。3.3V TTL电平,波特率9600。USB转TTL模块与MY1690-12P的连接图如下。

MY1690-12P语音模块实现特定的语音提示功能 (https://mushiming.com/)  第1张

                                                                          图1 USB转TTL模块与MY1690-12P的连接图

 

使用电脑串口调试助手,需要正确设置串口的参数,设置如下图:

协议命令格式:

起始码

长度

操作码

参数

校验码

结束码

0x7E

见下文

见下文

见下文

见下文

0xEF

注意: 数据全部为十六进制数。

“长度”是指:长度+操作码+参数(有些没有参数,有些有两位参数)+校验码的个数;

“校验码”是指:长度<异或>操作码<异或>参数的值,既按顺序分别异或的值。

 

校验码客户可通过计算器计算得到:

例如,设置音量指令为  7E 04 3119 2C EF

    长度04是这样得到:就是“04”,“31”,“19”,“2C” 4个数。

校验码2C是这样得到:

首先打开计算器选择程序员模式,然后选择16进制、双字,最后点击进行计算:

04 Xor 31 Xor19 = 2C

 

注:以上内容来自深圳市迈优科技的官方网站的相关资料,详细内容前往官网下载模块使用说明书,MY1690-12P的使用说明书链接:http://www.maiyout.com/col.jsp?id=103

 

三、项目应用场景

在实际项目中,我们通常使用这种MP3解码模块运用于语音提示的场景中。例如,当水加热达到指定温度时,关闭加热设备,并语音提示:“加热已完成!”还可以进行组合语音提示,例如,当水加热达到65摄氏度时,语音提示:“水温已达到”“六”“十”“五”“摄氏度”五段语音组合播放,但是组合播放最多连续播放20段语音文件,且对应的语音文件命名方式为:0001 XXX.mp3。

官方网站下载的程序只是串口通信+几个常用指令的例程,在实际项目中还远远不够,需要根据需要写好驱动程序。

项目中需要使用串口通信的模块有3个,而STC15F2K60S2中只有2个串口通信资源,所以需要将语音模块放置在串口1可硬件引脚切换的位置,当需要进行语音提示播放时,操作切换串口通信硬件引脚的寄存器即可,涉及到硬件引脚切换的程序如下。

MY1690-12P语音模块实现特定的语音提示功能 (https://mushiming.com/)  第2张

/****************************************************************
                 STC15系列单片机串口通信硬件引脚切换
****************************************************************/

#define S1_S0 0x40              //P_SW1.6

#define S1_S1 0x80              //P_SW1.7



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

当sw_flag=0时,P3.0/RxD, P3.1/TxD;

当sw_flag=1时,P3.6/RxD_2, P3.7/TxD_2

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

void UART1_switch(uchar sw_flag)

{

     if(sw_flag)

    {

         ACC = P_SW1;

         ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0

         ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)

         P_SW1 = ACC;

    }     

    else

    {

        ACC = P_SW1;

        ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0

        P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)

    }     

}

四、MY1690 MP3语音模块驱动程序

1.头文件

#ifndef _MY1690_H_

#define _MY1690_H_



#include <STC15F2K60S2.H>

#include "UART.h"



#ifndef uchar

#define uchar unsigned char

#endif

#ifndef uint

#define uint unsigned int

#endif





//void send_3dat_cmd(uchar cmd,uchar jy);

//void send_4dat_cmd(uchar cmd,uchar cs,uchar jy);

void send_5dat_cmd(uchar cmd,uchar cs,uchar gq,uchar jy);

void Voice(uchar a,int b);

uchar Check(uchar cs);



#endif

2.主程序

#include "MY1690.h"



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

 - 功能描述: 串口1初始化

 - 注:      设置为9600波特率

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

//void Serial_init(void)

//{

//  TMOD = 0x20;                // 设置 T1 为波特率发生器

//  SCON = 0x50;                // 0101,0000 8位数据位, 无奇偶校验     

//  PCON = 0x00;                //PCON=0;

//  TH1=256-(OSC_FREQ/COMM_BAUD_RATE/32/12);//设置为9600波特率

//  TL1=256-(OSC_FREQ/COMM_BAUD_RATE/32/12);

//    TR1     = 1;            //定时器1打开

//    REN     = 1;            //串口1接收使能

//    ES      = 1;            //串口1中断使能

//}

//

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

* 【函 数 名】: void write_COM(uchar dat)

* 【功    能】: 串口发送数据命令                     

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

//void write_COM(uchar dat)

//{

//  SBUF=dat;          //发送指令到SBUF

//  while(!TI);        //等待发送结束

//  TI=0;              //清除结束标志,以便再发送数据

//}

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

* 【函 数 名】: void send_3dat_cmd(uchar cmd,uchar dat)

* 【功    能】: 除了起始和结束标志外,发三位长度的数据

*send_3dat_cmd(0x11,0x12);   // 播放

*send_3dat_cmd(0x12,0x11);    //暂停

* send_3dat_cmd(0x13,0x10);    // 下一曲

* send_3dat_cmd(0x14,0x17);   //上一曲

*send_3dat_cmd(0x15,0x16);   //音量加

*send_3dat_cmd(0x16,0x15);   //音量减

* send_3dat_cmd(0x1A,0x19);      //快进

*send_3dat_cmd(0x1B,0x18);     //快退

* send_3dat_cmd(0x1C,0x1F);       //播放/暂停                    

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

//void send_3dat_cmd(uchar cmd,uchar jy)

//{

//  write_COM(0x7E);       //发送“开始命令”到SBUF

//  write_COM(0x03);       //发送“命令长度”到SBUF

//  write_COM(cmd);    //发送“命令”到SBUF

//  write_COM(jy);       //  发送校验码到SBUF

//  write_COM(0xEF);       //发送“结束指令”到SBUF

//}

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

* 【函 数 名】: void send_4dat_cmd(uchar cmd,uchar cs,uchar jy )

* 【功    能】: 除了起始和结束标志外,发四位长度的数据  

*  send_4dat_cmd(0x32,0x00,0x36 ) ;         //设置EQ

*  send_4dat_cmd(0x34,0x01,0x31 ) ;         //文件切换

*  send_4dat_cmd(0x35,0x01,0x30 ) ;     //设备切换                  

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

//void send_4dat_cmd(uchar cmd,uchar cs,uchar jy )

//{

//  write_COM(0x7E);       //发送“开始命令”到SBUF

//  write_COM(0x04);       //发送“命令长度”到SBUF

//  write_COM(cmd);    //发送“插播指令”到SBUF

//  write_COM(cs);     // 发送参数 到SBUF

//  write_COM(jy);     //  发送校验码到SBUF

//  write_COM(0xEF);       //发送“结束指令”到SBUF

//}

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

* 【函 数 名】: void send_5dat_cmd(uchar cmd,uchar cs,uchar gq,uchar jy )

* 【功    能】: 除了起始和结束标志外,发四位长度的数据

* send_5dat_cmd(0x43,0x00,0x03,0x45);      //插播功能

* send_5dat_cmd(0x44,0x01,0x06,0x46) ;    //插播指定文件夹的歌曲播放,本指令为文件夹01的第6首歌曲                      

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

void send_5dat_cmd(uchar cmd,uchar cs,uchar gq,uchar jy )

{

   

    write_COM(0x7E);       //发送“开始命令”到SBUF

    write_COM(0x05);       //发送“命令长度”到SBUF

    write_COM(cmd);    //发送“插播指令”到SBUF

    write_COM(cs);     // 发送参数 到SBUF   

    write_COM(gq);     //发送第几首歌曲到SBUF

    write_COM(jy);     //  发送校验码到SBUF

    write_COM(0xEF);       //发送“结束指令”到SBUF

   

}                             

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

* 【函 数 名】: Voice(a,b)

* 【功    能】:

a(0:温度   1:水量  2:叫水)

b(温度:0:加热开始   1:加热完成;

  水量:0:已换新水   2:水已不足;

  叫水:宿舍号)   

例如:Voice(2,1517);//语音提示:你好,请送水到1517。

          Voice(0,0);//语音提示:加热开始!

            Voice(1,0);//语音提示:已换上新的饮用水!

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

void Voice(uchar a,int b)

{

    uchar check_flag = 0x00,check1 = 0x00,check2 = 0x00,check3 = 0x00,check4 = 0x00;//校验码

    uchar Voice_number[] = {0,0,0,0};//宿舍号

    uchar i=0;

    UART1_switch(1);//uart1切换到P3^6\P3^7

    if(a == 0)//温度部分

    {

        if(b == 0)//加热开始 语音提示

        {

            check_flag = Check(0x0C);//校验码计算    

          send_5dat_cmd(0x41,0x00,0x0C,check_flag);//播放加热开始(0012)语音文件

        }

        if(b == 1)//加热完成 语音提示

        {

            check_flag = Check(0x0B);//校验码计算    

          send_5dat_cmd(0x41,0x00,0x0B,check_flag);//播放加热开始(0011)语音文件

        }      

    }

    else if(a == 1)//水量部分

    {

        if(b == 0)//已换新水 语音提示

        {

            check_flag = Check(0x0E);//校验码计算    

          send_5dat_cmd(0x41,0x00,0x0E,check_flag);//播放已换新水(0014)语音文件

        }

        if(b == 1)//水已不足 语音提示

        {

            check_flag = Check(0x0D);//校验码计算    

          send_5dat_cmd(0x41,0x00,0x0D,check_flag);//播放水已不足(0013)语音文件

        }  

    }

    else if(a == 2)//叫水部分

    {

         check_flag = Check(0x0F);//校验码计算   

         

         

         Voice_number[0] = b/1000%10;

         Voice_number[1] = b/100%10;

         Voice_number[2] = b/10%10;

         Voice_number[3] = b%10;

         for(i=0;i<4;i++)//如果结果是0x00,因为数字0对应的文件是0x10,所以要加0x10

        {

                if(Voice_number[i] == 0)

                   Voice_number[i] = Voice_number[i]+0x10;

        }

         check1 = Check(Voice_number[0]);//校验码计算             

         check2 = Check(Voice_number[1]);//校验码计算    

         check3 = Check(Voice_number[2]);//校验码计算    

         check4 = Check(Voice_number[3]);//校验码计算

       

         send_5dat_cmd(0x41,0x00,0x0F,check_flag);//播放请送水到(0015)语音文件

         send_5dat_cmd(0x41,0x00,Voice_number[0],check1);//播放宿舍号

         send_5dat_cmd(0x41,0x00,Voice_number[1],check2);

         send_5dat_cmd(0x41,0x00,Voice_number[2],check3);    

         send_5dat_cmd(0x41,0x00,Voice_number[3],check4);

       

//      check_flag = Check(0x0F);//校验码计算   

//      send_5dat_cmd(0x41,0x00,0x0F,check_flag);//播放请送水到(0015)语音文件

//      send_5dat_cmd(0x41,0x00,Voice_number[0],check1);//播放两遍宿舍号

//      send_5dat_cmd(0x41,0x00,Voice_number[1],check2);

//      send_5dat_cmd(0x41,0x00,Voice_number[2],check3);    

//      send_5dat_cmd(0x41,0x00,Voice_number[3],check4);

    }

    else //系统出错

//      buzz = 0;//蜂鸣器报警,出错

    {

   

    }

    UART1_switch(0);//uart1重新初始化

    check_flag = 0x00,check1 = 0x00,check2 = 0x00,check3 = 0x00,check4 = 0x00;

   

}



/*********************校验码算法****************************/

uchar Check(uchar jy)//校验码计算(异或运算)

{

    jy = jy^0x44;

    return jy;

}

 

THE END

发表回复