JQ8400是一个语音模块,可以用多种方式来播放事先录制好的wav和mp3文件,其具备一线串口ONE LINE的引脚,单片机可以通过这个引脚发送指令,控制语音模块的工作。一线串口的指令格式如下图:
由于语音模块使用的是5V电源,但评测板上却没有5V电源的输出引脚(开始未曾想起arduino接口),只好在评测板上查看,结果在电源芯片旁找到一个5V电源焊盘(下图红色箭头所示):
于是在此焊上了一根排针:
在调试引脚时序的延时,开始使用的是例程提供的delay_ms函数,测试发现会对系统正常延时产生较大的干扰,最后还是另写了一个延时小函数才测试通过。
最后通过逻辑分析仪来调整一线串口的时序,将时序调整到协议的要求。高电平的持续时间要求是1200ms,我调整到约1300ms:
低电平的持续时间是400ms,我调整到432ms,满足了协议要求:
下图为测试过程:
测试结束时忽然想起评测板上提供了arduino接口,这个接口标准上应该会有5V电源,于是又将评测板上的杜邦线取下,检查发现其中的VCC就是5V电源接口:
然后在arduino电源接口上焊上排针,重新将LCD显示屏、DS1307日历模块以及JQ8400语音模块重新连接好:
下面是JQ8400语音模块添加的代码:
#include "jq8400.h"
extern uint16_t son_buf[10];
/***************************************************
*程 序 名:delayms()
*作 用:毫秒延时程序
*输入参数:延时时间(毫秒)
*返回参数:无
*备 注:
***************************************************/
void delayms(uint16_t xms)
{
uint16_t x,y;
for(x=xms;x>0;x--)
for(y=4;y>0;y--);
}
/***************************************************
*程 序 名:JQ8400_Config()
*作 用:配置引脚
*输入参数:无
*返回参数:无
*备 注:使用PD3作数据通讯
***************************************************/
void JQ8400_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/***************************************************
*程 序 名:JQ8400Send(uint8_t dat)
*作 用:发送数据到JQ8400(单总线)
*输入参数:dat (要发送的数据)
*返回参数:无
*备 注:低位先,高低电平1:3=0,高低电平3:1=1
***************************************************/
void JQ8400Send(uint8_t dat)
{
uint8_t i;
Dat_H();
delayms(1000); //拉高1毫秒
Dat_L(); //发出引导信号
delayms(2000); //拉低2毫秒
//测试情况
//可用 1500:500,1200:400,900:300,750:250
//不可用 300:100,
//不稳定 600:200
//
//
for ( i=0; i<8; i++ )
{
Dat_H(); //拉高,准备延时>2ms
if( dat & 0x01 ) //高电平,延时3:1表示数据位1
{
delayms(1200); //750(>1.2ms)
Dat_L();
delayms(400); //250(>0.4ms)
}
else //低电平,延时1:3表示数据位0
{
delayms(400);
Dat_L();
delayms(1200);
}
dat >>= 1;
}
Dat_H();
delayms(20); //间隔>10毫秒
}
/***************************************************
*程 序 名:JQ_Vol(uint8_t vol)
*作 用:设置音量大小(0~30)
*输入参数:vol (1~3)
*返回参数:无
*备 注:
***************************************************/
void JQ_Vol(uint8_t vol)
{
uint8_t n;
JQ8400Send(0x0a);
n = vol / 10;
JQ8400Send(n); //十位
n = vol % 10;
JQ8400Send(n); //个位
JQ8400Send(0x0c);
}
/***************************************************
*程 序 名:JQ_Stop()
*作 用:停止放音
*输入参数:无
*返回参数:无
*备 注:
***************************************************/
void JQ_Stop(void)
{
JQ8400Send(0x13);
}
/***************************************************
*程 序 名:JQ_Next()
*作 用:下一曲
*输入参数:无
*返回参数:无
*备 注:
***************************************************/
void JQ_Next(void)
{
JQ8400Send(0x15);
}
/***************************************************
*程 序 名:JQ_All(uint16_t nb)
*作 用:播放指定语音
*输入参数:文件名(序号)
*返回参数:无
*备 注:文件名应为全数字字符
***************************************************/
void JQ_All(uint16_t nb)
{
uint8_t n,b; //当前位数字,b=1 有效数字开始
JQ8400Send(0x0a); //清零数字
n = nb / 10000; //万位
if(n>0){
JQ8400Send(n);
b = 1;
}
n = nb % 10000 / 1000;//千位
if(n > 0 | b > 0){
JQ8400Send(n);
b = 1;
}
n = nb % 1000 / 100; //百位
if(n > 0 | b > 0){
JQ8400Send(n);
b = 1;
}
n = nb % 100 / 10; //十位
if(n > 0 | b > 0){
JQ8400Send(n);
}
n = nb % 10; //个位
JQ8400Send(n);
JQ8400Send(0x0b); //选曲确认
JQ8400Send(0x11); //开始播放
}
|