完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
案例主控板如不做特殊说明的话,均默认是Arduino UNO控制板。
本次实验以UNO发送串口协议控制语音播放器播放歌曲,语音播放模块选型DY-SV5W。 一、硬件选择 1. Arduino UNO Arduino UNO板子,啥子东西你懂的,不做详细介绍,略过。 2. DY-SV5W
2、支持采样率(KHz):8/11.025/12/16/22.05/24/32/44.1/48。 3、24位DAC输出,动态范围支持90dB,信噪比支持85dB。 4、完全支持FAT16/FAT32文件系统,最大支持32G的TF卡。 5、自带5W D类功放,可直接驱动4Ω,3~5W喇叭。 6、支持UART串口控制语音播报功能,可控制播放,暂停,选曲,音量加减等功能,最大选曲65535 首曲目,波特率9600 bit/s。 7、支持IO触发播放功能,8个IO 口单独触发8首曲目或8个IO口组合触发255首曲目。 8、支持One_line单总线串口控制,可控制播放,暂停,选曲,音量加减等功能。 9、支持3个配置IO 进行多达7种工作模式选择。
语音模块可以控制的模式如上表中7种模式,当你有幸拿到这块板的时候想必也拿到了厂商给的模块配套使用资料,该文章中博主就比较实用的串口指令模式做简单说明。 1. UART模式拨码开关设置
采用全双工串口通信; 波特率为9600,数据位:8 ,停止位1位,检验位 N。 起始码-指令类型-数据长度(n)-数据1-数据 n-和检验(SM) ※ 指令码 :固定为 AA。 ※ 指令类型 : 用来区分指令类型。 ※ 数据长度:指令中的数据的字节数。 ※ 数据 :指令中的相关数据,当数据长度为 1时,表示只有CMD,没有数据位。 ※ 和检验 :为之前所有字节之和的低8位,即起始码到数据相加后取低 8位。 ※ 数据格式:发送的数据或命令,高8位数据在前,低 8位在后。 4. 通信机制 1)我方做为从机处理,上电默认等待状态,所有播放操作全由主机控制。 2)从机不会主动发起通信,所有通信都是由主机发起。 3)串口是3.3V的TTL 电平,如果主机系统是 5V电平请在中间串1K 电阻。 4)如未特别说明,协议中所有数据都是表示十六进制数据。 实操验证了在语音模块串口RX、TX威廉希尔官方网站 已焊接了1k电阻,无需考虑主机和从机的串口电平问题 5. 协议约定 以下是模块芯片返回和能识别的数据定义。 1)播放状态定义 :系统上电处于停止状态。 ※ 00(停止) 01(播放) 02(暂停) 2) 盘符定义: 切换盘符后处于停止状态。 ※ USB:00 SD:01 FLASH:02 NO_DEVICE:FF 3)音量:音量总共为 31级,0-30级,上电默认为 20级。 4)播放模式定义:上电默认为单曲停止。 ※ 全盘循环(00):按顺序播放全盘曲目,播放完后循环播放。 ※ 单曲循环(01):一直循环播放当前曲目。 ※ 单曲停止(02):播放完当前曲目一次停止。 ※ 全盘随机(03):随机播放盘符内曲目。 ※ 目录循环(04):按顺序播放当前文件夹内曲目,播放完后循环播放,目录不 包含子目录。 ※ 目录随机(05): 在当前目录内随机播放,目录不包含子目录。 ※ 目录顺序播放(06):按顺序播放当前文件夹内曲目,播放完后停止,目录不 包含子目录。 ※ 顺序播放(07):按顺序播放全盘曲目,播放完后停止。 5)EQ定义:上电默认 EQ 为NORMAL(00)。 ※ NORMAL(00) POP(01) ROCK(02) JAZZ(03) CLASSIC(04) 6)DAC输出通道定义:上电默认为 MP3播放通道(00)。 ※ MP3播放通道(00): 播放MP3通道,DAC输出的声音为音乐播放的声音。 ※ AUX通道(01):DAC输出的声音为P26和P27 输入的声音。 ※ MP3+AUX(02):AUX通道MP3同时打开,DAC输出的声音是音乐播放的声 音和P26、P27输入的声音混合输出。 7)组合播放定义:组合播放是按文件名来组合,文件要求存储在“ZH”文件夹下, 可以把要组合的文件名称更改为两个字节的名称,一般建议用数字表示。如: 01.mp3,02.mp3,也可以用两个字母或一个汉字命名。 6. 通信指令(部分常用指令,非全部) 查询播放状态(01) 指令:AA 01 00 AB 返回:AA 01 01 播放状态 SM 说明:在任何时候都可以查询当前的播放状态 播放状态:00 停止;01播放;02 暂停 播放(02) 指令:AA 02 00 AC 返回:无 说明:在任何时候发此命令都会从头开始播放当前曲目 暂停(03) 指令:AA 03 00 AD 返回:无 停止(04) 指令:AA 04 00 AE 返回:无 上一曲(05) 指令:AA 05 00 AF 返回:无 下一曲(06) 指令:AA 06 00 B0 返回:无 指定曲目(07) 指令:AA 07 02曲目高 曲目低 SM 返回:无 例如: AA 07 02 00 08 BB 指定播放当前盘符第 8首,曲目数从1-65535(曲目序号是由存储顺序决定) 三、案例器件准备清单 来看看你准备的东西的备齐了没有~
提到按键/触摸/碰撞模块是为了在案例中做语音模块的播放状态控制 杜邦线用于UNO和语音模块的供电和串口控制,以及驱动小喇叭的引脚焊接 因为模块有耳机输出口,没小喇叭情况下可以耳机听歌,常用的3.5mm有线耳机 常见的排针都是2.54间距的,跟模块孔位对得上就行,不要太纠结什么是2.54间距 四、案例实操 1.硬件接线 最最最最激动人心的时刻终于到来了,这里会说明控制案例程序设计,硬件焊接的就不讲了,你们自个搞定,UNO和DY-SV5W语音模块的接线按照下面表格接线
语音模块GND引脚默认连接模块的5V电源负极,只作为GND电平参考引脚,可悬空不接 需要特别注意的是小喇叭引脚有正负之分,请看好了引脚正负再接线
回到代码编写方面,案例代码相对比较简单,不用加头文件,可以在任意Arduino编译平台上编写,其中串口发送简单指令进行语音模块的控制,常用指令如下表所示,需要注意的是要以十六进制格式发送数据。 [tr]控制功能发送指令(十六进制)[/tr]
//bool变量,语音模块是否处于播放状态的状态量 bool mp3_control = false; //setup函数 void setup() { //模块状态控制传感器引脚(按键/触摸传感器/碰撞传感器) pinMode(2, INPUT); //设置串口波特率,语音模块串口波特率为9600,统一波特率 Serial.begin(9600); } void loop() { //控制模块播放歌曲(案例所用触摸传感器高电平触发) if((digitalRead(2) == HIGH)&&(mp3_control == false)) { //延时去抖 delay(500); //修改状态量mp3_control为true(播放状态) mp3_control = true; //发送播放指令 AA 02 00 AC Serial.write(0xAA); Serial.write(0x02); Serial.write(0x00); Serial.write(0xAC); delay(1000); //发送(当前目录)顺序播放指令 AA 18 01 07 CA Serial.write(0xAA); Serial.write(0x18); Serial.write(0x01); Serial.write(0x07); Serial.write(0xCA); }else //控制模块暂停播放(案例所用触摸传感器高电平触发) if((digitalRead(2) == HIGH)&&(mp3_control == true)) { //延时去抖 delay(500); //修改状态量mp3_control为false(暂停状态) mp3_control = false; //发送暂停指令 AA 03 00 AD Serial.write(0xAA); Serial.write(0x03); Serial.write(0x00); Serial.write(0xAD); } } 3.爬坑(print函数和write函数) 看过案例代码后你可能觉得这个案例已经学会了,但这里面有个坑你需要知道,就是串口的print函数和write函数,这两个函数在部分人之间还是存在着争议的,先丢个arduino函数的官网说明上来。 print函数print函数是arduino入门时就接触到的函数,对于程序调试和串口数据显示来说是很实用的,但在串口设备之间进行数据传输,print函数就显然是个大坑了。 在本次案例中明确说到语音模块的串口指令需要以十六进制的形式发送,像发送指令的协议头0xAA,经验不足的人可能在代码中会这么写 Serial.print(0xAA); 在发送给串口设备发现指令没得到体现之后他可能回去用串口监视器查看程序的串口输出是什么,结局就是这样的 Serial.print(0xAA); //串口实际输出(0xAA = 170) 170 然后你可能这么写 Serial.print(0xAA,HEX); 串口输出的结果貌似符合要求 Serial.print(0xAA,HEX); //HEX为数据转十六进制输出 //串口实际输出 AA //然而在串口用十六进制接收的话 41 41 //A = 65(ASCII表) = 41(65的十六进制) 彻底懵圈了,下面简单说一下,print函数和println函数,发送的内容都是以单个字符的形式往外发送的,例如print(0xAA)发送的是 1,7,0 这3个字符,print(0xAA,HEX)发送的是 A,A 这2个字符,这样在串口转十六进制接收时print(0xAA)是以3个十六进制数显示,print(0xAA,HEX)则是以2个十六进制数显示,这达不到我们的串口十六进制接收收到AA的要求。 串口改用write函数发送0xAA Serial.write(0xAA); 串口收到的数据 Serial.write(0xAA); //十六进制接收 AA 这样发送案例语音模块播放指令就是这样的 //AA 02 00 AC Serial.write(0xAA); Serial.write(0x02); Serial.write(0x00); Serial.write(0xAC); //串口十六进制接收 AA 02 00 AC 关于串口发送指令的函数说明有点啰嗦了,但希望你们可以看明白,什么时候该用print函数,什么时候该用write函数,少踩坑。 五、案例实现 这个靠你们自个脑补了,上不来视频,语音模块支持耳机播放和小喇叭播放,但接上小喇叭后耳机就听不到耳音了,反过来也是一样,不能同时支持两端输出。 |
|||||||||||
|
|||||||||||
只有小组成员才能发言,加入小组>>
4527个成员聚集在这个小组
加入小组3340 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4269 浏览 1 评论
4296 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 12:46 , Processed in 0.592653 second(s), Total 74, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号