我先来讲一下这个模块方便在什么地方:
(我没有做广告哈,有一说一)

1,有SPI-flash,USB的接口直接连电脑显示U盘,替换音频很方便

2,默认情况下有IO口按键触发,很方便播放指定的曲目,说白了你把那个接口用手捏着就可以播放,方便吧;

3,IO口的触发的功能还可以自定义

4,支持单线串口,与双线串口通讯(UART)

还有一个原因就是引脚是焊接好的,对于新手而言,焊接排针还是有点点难度的

端口定义与参数


和单片机或者说是串口助手连线的时候,TX,RX交替连接。VPP是一线串口的引脚

接的喇叭功放要求2W,8欧以下,电源端最高不可以超过5.2V。

配置方式

1,IO口触发播放

2,双线串口

3,单线串口

1,IO口触发播放


注意音频文件命名与端口触发对照表;

当然端口也可以复用:

按照配置软件配置就行,主要是要实现在端口上的开始/暂停,上一曲/下一曲,这些操作

2,双线串口

这种方式也是我们最常用的一种方式,通过TX,RX与单片机通讯,接受单片机串口发送过来的指令进行事先通讯约定的操作:

重点关注的部分我已经用红线标明了:

一定一定注意这个和校验,每次修改指令的时候都要将校验码(SM)修改一遍,不然发送指令可能无响应。

详细的其他指令:




​ 看到这里你大概明白怎么操作了吧,就是调用串口发送函数将这些十六进制指令都发送到单片机,那么为了方便,我们一般呢将一个指令用数组的形式储存起来,然后调用由串口通讯单字节发送函数封装的指定字节发送函数就行。然后还有就是可以调用资料里面的串口软件直接生成相关指令,但是我一点那个软件就卡退。所以这里还是将每一条指令手编的。

我将常用的指令封装成数组,供大家参考:

(复制到keil5里面显示注释,这里md文档用utf-8显示的是乱码)

u8 code Mode0[] = {0xAA, 0x18, 0x01, 0x00, 0xC3};//Ñ­»·²¥·Åģʽ
u8 code Mode1[] = {0xAA, 0x18, 0x01, 0x01, 0xC4};
u8 code Mode2[] = {0xAA, 0x18, 0x01, 0x02, 0xC5};
u8 code Mode3[] = {0xAA, 0x18, 0x01, 0x03, 0xC6};
u8 code Mode4[] = {0xAA, 0x18, 0x01, 0x04, 0xC7};
u8 code Mode5[] = {0xAA, 0x18, 0x01, 0x05, 0xC8};
u8 code Mode6[] = {0xAA, 0x18, 0x01, 0x06, 0xC9};
u8 code Mode7[] = {0xAA, 0x18, 0x01, 0x07, 0xCA};u8 code PrevFile[] = {0xAA, 0x05, 0x00, 0xAF};//ÉÏÒ»Ê×
u8 code NextFile[] = {0xAA, 0x06, 0x00, 0xB0};//ÏÂÒ»Ê×
u8 code Play[] = {0xAA, 0x02, 0x00, 0xAC};    //²¥·Å
u8 code Stop[] = {0xAA, 0x04, 0x00, 0xAE};    //Í£Ö¹
u8 code Pause[] = {0xAA, 0x03, 0x00, 0xAD};    //Í£Ö¹
u8 code Path[] = {0xAA, 0x08, 0x10, 0x02, 0x2F, 0xB9, 0xE3, 0xB8, 0xE6, 0x2A, 0x2F, 0xD0, 0xA1, 0xC3, 0xD7, 0x2A, 0x4D, 0x50, 0x33, 0x8B, }; // flash   /¹ã¸æ*/СÃ×*MP3
u8 code Voiceup[] = {0xAA, 0x14, 0x00, 0xBE};  //ÒôÁ¿Ôö
u8 code Voicedown[] = {0xAA, 0x15, 0x00, 0xBF};//ÒôÁ¿¼õu8 code Play1[] = {0xAA, 0x07, 0x02, 0x00, 0x01, 0xB4}; //Ö¸¶¨²¥·ÅµÚ1Ê×
u8 code Play2[] = {0xAA, 0x07, 0x02, 0x00, 0x02, 0xB5}; //Ö¸¶¨²¥·ÅµÚ2Ê×
u8 code Play3[] = {0xAA, 0x07, 0x02, 0x00, 0x03, 0xB6}; //Ö¸¶¨²¥·ÅµÚ3Ê×
u8 code Play4[] = {0xAA, 0x07, 0x02, 0x00, 0x04, 0xB7}; //Ö¸¶¨²¥·ÅµÚ4Ê×
u8 code Play5[] = {0xAA, 0x07, 0x02, 0x00, 0x05, 0xB8}; //Ö¸¶¨²¥·ÅµÚ5Ê×
u8 code Play6[] = {0xAA, 0x07, 0x02, 0x00, 0x06, 0xB9}; //Ö¸¶¨²¥·ÅµÚ6Ê×
u8 code Play7[] = {0xAA, 0x07, 0x02, 0x00, 0x07, 0xBA}; //Ö¸¶¨²¥·ÅµÚ7Ê×
u8 code Play8[] = {0xAA, 0x07, 0x02, 0x00, 0x08, 0xBB}; //Ö¸¶¨²¥·ÅµÚ8Ê×
u8 code Play9[] = {0xAA, 0x07, 0x02, 0x00, 0x09, 0xBC}; //Ö¸¶¨²¥·ÅµÚ9Ê×u8 code Combine[] = {0xAA, 0x1B, 0x04, 0x30, 0x31 ,0X30 ,0X32 ,0x8C}; //×éºÏ²¥·ÅZHÎļþ¼ÐϵÄ01£¬02Îļþ

串口通讯函数

/************************************************************************
¹¦ÄÜÃèÊö£º ´®¿Ú·¢ËÍ×Ö·û´®Êý¾Ý
Èë¿Ú²ÎÊý£º  *DAT£º×Ö·û´®Ö¸Õë
·µ »Ø Öµ£º none
ÆäËû˵Ã÷£º API ¹©ÍⲿʹÓã¬Ö±¹Û£¡
**************************************************************************/
void UART1_SendString(u8 *DAT,u8 Len)
{while(Len--){UART1_SendByte(*DAT);DAT++;}
}
/********************************************************************
¹¦ÄÜÃèÊö£º ´®¿Ú·¢ËÍ×Ö½ÚÊý¾Ý
Èë¿Ú²ÎÊý£º  *DAT£º×Ö·û´®Ö¸Õë
·µ »Ø Öµ£º none
ÆäËû˵Ã÷£º API ¹©ÍⲿʹÓã¬Ö±¹Û£¡
********************************************************************/
void UART1_SendByte(u8 value)
{ES=0; //¹Ø±Õ´®¿ÚÖжÏTI=0; //Çå·¢ËÍÍê±ÏÖжÏÇëÇó±ê־λSBUF=value; //·¢ËÍwhile(TI==0); //µÈ´ý·¢ËÍÍê±ÏTI=0; //Çå·¢ËÍÍê±ÏÖжÏÇëÇó±ê־λES=1; //ÔÊÐí´®¿ÚÖжÏ
}

串口初始化函数(11.0592MHz的晶振,9600波特率)

void UartInit(void)      //9600bps@11.0592MHz
{PCON &= 0x7F;     //²¨ÌØÂʲ»±¶ËÙSCON = 0x50;     //8λÊý¾Ý,¿É±ä²¨ÌØÂÊTMOD &= 0x0F;      //Çå³ý¶¨Ê±Æ÷1ģʽλTMOD |= 0x20;       //É趨¶¨Ê±Æ÷1Ϊ8λ×Ô¶¯ÖØ×°·½Ê½TL1 = 0xFD;      //É趨¶¨Ê±³õÖµTH1 = 0xFD;      //É趨¶¨Ê±Æ÷ÖØ×°ÖµET1 = 0;     //½ûÖ¹¶¨Ê±Æ÷1ÖжÏTR1 = 1;      //Æô¶¯¶¨Ê±Æ÷1
}

另外想插一个便捷控制组合播放的函数:(指令代号1B)

如果按之前的配置方法,那么需要将我们需要组合播放的曲目名换成高低位的十六进制表示,但是因为组合播放要求是mp3文件放在名为“ZH”的文件夹下,而且曲目名只能是两个字节,例如说01,02这样子。

配置方法也很简单就是将十位数字+0x30作为高位,将个位数字+0x30作为低位数字。

下面是示例中配置的组合播放01,02的数组代码,用串口发送字节依次发送即可。

u8 code Combine[] = {0xAA, 0x1B, 0x04, 0x30, 0x31 ,0X30 ,0X32 ,0x8C};

但是每次都要重新编写数组的话不免有些复杂:下面这个函数就是替代了将十位数字+0x30作为高位,将个位数字+0x30作为低位数字,这个操作。

同样的如果我们要组合播放01,02,那么只需要向函数穿入数组 i[1,2] 就行,数组长度Len传入2。

/************************************************************************
¹¦ÄÜÃèÊö£º×éºÏ²¥±¨º¯Êý
Èë¿Ú²ÎÊý£º  *DAT£º×Ö·û´®Ö¸Õë,Len×Ö·û´®³¤¶È
·µ »Ø Öµ£º none
ÆäËû˵Ã÷£º ½«ÐèÒª²¥±¨µÄÎļþÃû·ÅÈëÊý×éÖÐ×÷ΪÐβμ´¿É
**************************************************************************/
void  JQ_8x00_ZuHeBoFang(u8 *DATA,u8 Len)
{u16 CRC_data=0,i = 3;u8 Buffer[ZH_MAX] ={0xaa,0x1b};Buffer[2] = Len*2;         //¼ÆËãÊý¾Ý³¤¶È(ÿ¸öÇúÄ¿ÓɸßλÓëµÍλ¹¹³É£¬ËùÒÔ³ËÒÔ2)CRC_data = CRC_data + 0xaa + 0x1b + Buffer[2];while(Len--){Buffer[i] = *DATA/10+0x30;          //È¡³öʮ룬ºó¼ÓÈë0x30CRC_data = CRC_data + Buffer[i];i++;Buffer[i] = *DATA%10+0x30;          //È¥³ý¸÷룬ºó¼ÓÈë0x30CRC_data = CRC_data + Buffer[i];i++;DATA++;}Buffer[i] = CRC_data;//УÑéλUART1_SendString(Buffer,i+1);
}

下面我想补充一个知识点:

就是我在编写串口连续发送函数的时候:

void UART1_SendString(u8 *DAT,u8 Len)
{while(Len--){UART1_SendByte(*DAT);DAT++;}
}

每次传入的数组还要数有几个元素,再将Len传入函数。是在是复杂。而且这个函数最大的缺点是,如果你数数,数少了。那么不会报错,而且芯片也没有反应。但是多了是没有问题的。

我第一想到构造的函数是这样的:进行数组大小次发送,每次发送完了以后数组的地址+1;

void UART1_SendData(u8 *DAT)
{unsigned char i;for(i=0; i<sizeof(DAT); i++){UART1_SendByte(*DAT);DAT++;}
}

但是实际上,传递到函数的数组名是数组的首地址,用sizeof(DAT)并不能求出数组的长度,得到的是指针变量DAT的内存大小,依据操作系统不同而异。

详细如下:

所以我用的这个函数:

void UART1_SendData(u8 *DAT)
{unsigned char i;for(i=0; i<6; i++){UART1_SendByte(*DAT);DAT++;}
}

因为,常用的指令中,一般都是发送4个,5个,最多6个十六进制数据。而组合播放用之前封装的函数也足够了;

3,单线串口

​ 需要单片机在端口处依照严格的时序通过高低电平持续的时间来表示逻辑0和1,优点就不用多说了,对于51单片机而言,只有P3_1与P3_0处的一个串口。如果使用单线通讯可以将串口节省出来用作蓝牙模块的连接啊什么的。单线通讯的连线是1号引脚口VPP引出的,具体看之前的引脚示意图:

这个第三条的脉冲比例基数我没查到词条,但是就我理解的话:

如果脉冲比例基数为4的话,就是示例,即

高定平:低电平=4:1 表示1

高定平:低电平=1:4 表示0

也不知道说的对不对哈,欢迎指正

控制说明的单字节控制就是只需要发送一个指令就行,适用的指令都有标注

然后多字节的话需要先用0x0a清空上次的数字,然后发送2个十六进制数据一个表示十位,一个表示个位。

例如:0x01,0x05表示的是十进制的15

需要区分的是,我们之前说的第二种配置方式:双线串口的指定曲目播放的两个十六进制数据表示的要播放曲目编号的高8位和低8位,所以第二种方式一共可以播放65536首歌曲,这也是为什么第一首,第二首曲目的编号要定义成00001,00002的形式。

一线串口通讯示例:

依旧和双线通讯一样,我将单线通讯的常用函数代码做了一下封装方便大家直接调用:

常用指令集数组:

这里第4行将sda定义为P1^0接口,在diy的时候自己修改就行;

#define u8 unsigned char
#define u16 unsigned intsbit sda=P1^0;//½«µ¥Ïß½Ó¿Úsda¶¨ÒåΪP1^0
void Voiceup (void);
void Voicedown (void);
void Delay1us ( int T );
void SendData ( u8 addr );
void SendDataString(u8 *DAT,u8 Len);//ÒôÁ¿
u8 code Voice0[] = {0x0a,0x00,0x00,0x0c};
u8 code Voice10[] = {0x0a,0x01,0x00,0x0c};
u8 Voice20[] = {0x0a,0x02,0x00,0x0c}; //ÉϵçºóĬÈÏ20
u8 code Voice30[] = {0x0a,0x03,0x00,0x0c};
//²¥·Å
u8 code Play[] = {0x11};
u8 code Pause[] = {0x12};
u8 code Stop[] = {0x13};u8 code Next[] = {0x15};
u8 code Previous[] = {0x14};u8 code Play1[] = {0x0a,0x01,0x0b}; //²¥·ÅµÚÒ»Ê×
u8 code Play2[] = {0x0a,0x02,0x0b}; //²¥·ÅµÚ¶þÊ×
u8 code Play3[] = {0x0a,0x03,0x0b}; //²¥·ÅµÚÈýÊ×u8 code Play11[] = {0x0a,0x01,0x01,0x0b}; //²¥·ÅµÚʮһÊ×
u8 code Play12[] = {0x0a,0x01,0x02,0x0b}; //²¥·ÅµÚÊ®¶þÊ×

时序函数和简单封装的连续发送函数:

/*****************************************************************************º¯ Êý Ãû  : Delay1us¹¦ÄÜÃèÊö  : 1΢ÃëÑÓʱº¯ÊýÊäÈë²ÎÊý  : int TÊä³ö²ÎÊý  : ÎÞ·µ »Ø Öµ  :µ÷Óú¯Êý  :±»µ÷º¯Êý  :
*****************************************************************************/
void Delay1us ( int T )
{T = T - 70;do{;}while ( T-- );
}
/*****************************************************************************º¯ Êý Ãû  : SendData¹¦ÄÜÃèÊö  : Ò»Ïß´®¿Ú·¢Ëͺ¯ÊýÊäÈë²ÎÊý  : u16 NÊä³ö²ÎÊý  : ÎÞ
*****************************************************************************/
void SendData ( u8 addr )
{u8 i;EA = 0;/*·¢ËÍʱ¹ØµôÖжϣ¬·ÀÖ¹ÖжÏÓ°ÏìʱÐò  */sda = 1;/*¿ªÊ¼À­¸ã  */Delay1us ( 1000 );sda = 0;/*¿ªÊ¼Òýµ¼Âë*/Delay1us ( 2200 );/*´Ë´¦ÑÓʱ×îÉÙÒª´óÓÚ2ms£¬´Ë²ÎÊýÑÓʱΪ310ms  */for ( i = 0; i < 8; i++ ) /*×ܹ²8λÊý¾Ý  */{sda = 1;if ( addr & 0x01 ) /*3:1±íʾÊý¾Ýλ1,ÿ¸öλÓÃÁ½¸öÂö³å±íʾ  */{Delay1us ( 500 );sda = 0;Delay1us ( 210 );}else              /*1£º3±íʾÊý¾Ýλ0 ,ÿ¸öλÓÃÁ½¸öÂö³å±íʾ  */{Delay1us ( 210 );sda = 0;Delay1us ( 500 );}addr >>= 1;}sda = 1;EA = 1;
}/************************************************************************
¹¦ÄÜÃèÊö£º µ¥Ïß·¢ËÍÒ»´®Êý¾Ý
Èë¿Ú²ÎÊý£º  *DAT£º×Ö·û´®Ö¸Õë
·µ »Ø Öµ£º none
ÆäËû˵Ã÷£º API ¹©ÍⲿʹÓã¬Ö±¹Û£¡
**************************************************************************/
void SendDataString(u8 *DAT,u8 Len)
{while(Len--){SendData(*DAT);DAT++;}
}

单线通信的音量只能设置一个事先确定好的值,没有连续递增或者递减功能,所以我封装了一个函数:
音量增大,音量减小函数:

u8 Voice20[] = {0x0a,0x02,0x00,0x0c}; //ÉϵçºóĬÈÏ20
void Voiceup (void)//Ôö´óÉùÒô
{ if(Voice20[2]==0x09){Voice20[2]=0x00;Voice20[1]++;}else{Voice20[2]++;};SendDataString(Voice20,4);
}void Voicedown (void)//¼õСÉùÒô
{if(Voice20[2]==0x00){Voice20[2]=0x09;Voice20[1]--;}else{Voice20[2]--;}SendDataString(Voice20,4);
}

单片机语音模块JQ8900-16P的几种触发方式与源码配置相关推荐

  1. 基于stm32单片机的台历日历计时器万年历Proteus仿真(源码+仿真+全套资料)

    资料编号:151 视频讲解: 151-基于stm32单片机的台历日历计时器万年历Proteus仿真(源码+仿真+全套资料) 采用stm32单片机作为主控,LCD屏幕上部分显示电子日历,下半屏幕显示台历 ...

  2. 基于51单片机的室内温度可燃气体检测报警系统Proteus仿真(源码+仿真+全套资料)

    资料编号:133 讲解视频: 133-基于51单片机的室内温度可燃气体检测报警系统Proteus仿真(源码+仿真+全套资料) 功能介绍: 采用51单片机作为主控,LCD1602显示当前温度和可燃气体浓 ...

  3. 基于stm32单片机有害气体监测检测Proteus仿真(仿真+源码+全套资料)

    资料编号:097 检测当前的有害气体浓度,LCD1602显示,并且可以自动打开关闭风扇,也可以通过手动按键打开关闭风扇通风,全套资料齐全,具体功能请看下面演示视频 97-基于stm32单片机有害气体监 ...

  4. 基于51单片机的舞蹈机器人四路步进电机控制仿真(源码+仿真+全套资料)

    资料编号:091 通过51单片机控制4个步进电机旋转,模拟出机器人的四肢动作,全套资料齐全:具体功能请下方看演示视频 91-基于51单片机的舞蹈机器人四路步进电机控制仿真(源码+仿真+全套资料) 单片 ...

  5. 基于STM32单片机闭环步进电机驱动调速仿真(仿真+源码+全套资料)

    资料编号:081 (1) 基本功能:本任务通过输出脉冲控制步进电机的停止.运动.方向.使用 两个按键分别控制步进电机的正转和反转,再次按下这两个按键,步进电机停止, 同时 LCD 显示电机状态信息. ...

  6. 基于51单片机的人体红外探测防盗报警(仿真+源码+全套资料)

     资料编号:128 功能说明: 1.按下紧急报警按键,紧急报警灯闪烁,蜂鸣器报警 2.按下布防按键,布防指示灯开始闪烁,闪烁大约30秒,保持亮的状态,进入布防模式 3.按下取消报警/布防按键,取消布防 ...

  7. 20种看asp源码的方法及工具

    作者:欧杨飘雪  http://blog.csdn.net/flyingsnowy/ 众所周知windows平台漏洞百出,补丁一个接一个,但总是补也补不净.我把我所知道的20种看asp源码的方法总结了 ...

  8. hibernate 三种查询方式源码跟踪及总结

    1.设置环境(以EClipse和hibernate 3.2.6为例) 1)首先,新建一个java 工程. 2) 将hiberante src导入到java的src目录下,此时多半会报错,不用管它! 3 ...

  9. k线顶分型 python_顶底分型-(K线分类及顶底分型的一种数学原理 源码 贴图)...

    好股票软件下载网(www.goodgupiao.com)提示:您正在下载的是:顶底分型-(K线分类及顶底分型的一种数学原理 源码 贴图) 参考缠论,研究了很多天终于将顶底分型进行了具体的数学量化,涵盖 ...

最新文章

  1. TCMalloc:线程缓存的Malloc
  2. PostSharp的AOP设计在.NET Remoting中的应用
  3. TFS2012 服务器安装
  4. 有关锁和内存使用的DMV
  5. php 下载后文件打不开,解决php下载excel无法打开的问题
  6. 基于visual Studio2013解决C语言竞赛题之1044数组处理
  7. JavaScript学习(十三)—节点关系
  8. Java飞机大战项目
  9. serialVersionUID 生成
  10. Android AppWidget控制手机上网APN接入点
  11. 移动硬盘遇到无法访问,参数错误的处理方法
  12. 2017网易笔试矩阵快速幂
  13. group by 和where可以一起使用吗
  14. rt-n13u无线打印机服务器,全能表现 华硕RT-N13U无线路由器评测
  15. iPhone 13怎么关机?苹果iPhone 13关机图文教程
  16. 计算思维导论——第一章:计算机,计算与计算思维
  17. CSI Tool的安装
  18. 设置FLASH的读写保护及解除—零死角玩转STM32-F429系列
  19. Git原理及实践(Fork模式)
  20. 记一次Android全流程开发体验经历以及Android Studio使用【从环境搭建到项目打包发布 + 真实踩坑总结】

热门文章

  1. BCset BC set how entry is inserted to Database table when activated
  2. 计算机编程玫瑰花,c语言实现玫瑰花的方法
  3. 解决xshell6强制更新
  4. 机器人电焊电流电压怎么调_焊接机器人焊机电流电压匹配及行走速度调节(一)...
  5. lpop 原子_Matter:碳载单原子催化剂用于能量转化和存储的最新进展 – 材料牛...
  6. 容器技术在企业落地的最佳实践
  7. 推荐3个Windows电脑上的epub小说阅读器
  8. html+css仿QQ邮箱静态界面
  9. 删除商品时,如何不影响订单里该商品相关的信息显示
  10. 当面试问到自己有哪些缺点应该怎么回答