之前一直想做一个MP3播放器,普遍的方案都比较复杂,用音频解码芯片还有其他芯片的方案,开发起来不太容易。偶然的一个机会看到这种简单的串口播放器,就跟大家分享一下这个过程,大家也可以自己制作下,弄个好的造型,外加功放和喇叭,那就更完美,放在枕边听着,舒服。
设计使用的是MY1690-12P语音模块,支持UART 异步串口控制:支持播放、暂停、上下曲、音量加减、选曲播放、插播等。模块最大支持32GTF卡;也可外接U盘或USB数据线连接电脑更换SD卡音频文件。该模块内置3W功放,可以直接驱动3W的喇叭,使用更方便。
越简单、越容易实现的东西,功能不太完善,在另一个程度上就比较麻烦。第一点是歌名必须按照0000、0001这样修改,不然播放不了;第二就是单片机控制需要挺多按键;断电不能保持进度等。没用到那个就ADKEY的功能。
用串口发送16进制的指令来控制模块,这个就很简单的,先创建几个控制命令的数据,打包一个串口发送的子程序,发命令是用按键触发调用发送子函数。确实会很简单。所以我用手上的stm32板(ufun没有把串口接出来)来完成这些功能。很简单的程序,我硬是折腾了几个晚上。
按键部分:
5个按键控制:暂停播放,上下切歌、调音量大小。想用一个按键实现两种功能:单击和双击(不是单击两次,有区别的),当时没搞出来。有一个简单的用延时的方法,我没有用。中断和定时器方案有时间在研究,估计也不难。
第二部分:串口发送部分
可能大家会觉得很简单,但是可能有人不太注意一些细节,在我介绍毕设(超声波测距)的有提过说串口发送数据的问题。
首先大家现在开发板用串口发送e802 b4如下程序,不要放在while循环里面,保证上电只运行一次。发送代码如下:
- USART_SendData(USART1,0xe8);
- while((USART1->SR&0X40)==0);
- // while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
- delay_us(40);
- USART_SendData(USART1,0x02);
- while((USART1->SR&0X40)==0);
- delay_us(40);
- // while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
- USART_SendData(USART1,0xb4);
- while((USART1->SR&0X40)==0);
打开电脑串口助手,你会发现一下问题:
第一次发送e8 02 b4少了e8,丢失第一个字节数据。不知大家平时有没有遇到。
查阅stm32f10x参考手册,找到这样一句话:
TC:发送完成
当包含有数据的一帧发送完成后,由硬件将该位置位。如果USART_CR1中的TCIE为1,则产生中断。由软件序列清除该位(先读USART_SR,然后写入USART_DR)。TC位 也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。 【 0:发送还未完成;1:发送完成】
TC:发送完成
当包含有数据的一帧发送完成后,由硬件将该位置位。如果USART_CR1中的TCIE为1,则产生中断。由软件序列清除该位(先读USART_SR,然后写入USART_DR)。TC位 也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。 【 0:发送还未完成;1:发送完成】
注意到这一句:由软件序列清除该位(先读USART_SR,然后写入USART_DR)。 也就是说,要先read USART_SR,然后write USART_DR,才能完成TC状态位的清除。而硬件复位后,串口发送的首个数据之前没有read SR的操作,是直接write DR,也就是说,TC没有被清除掉。
详情请看参考手册,建议是看官方英文的,翻译版不准确的话,理解起来也费劲。
前面要加
- USART_ClearFlag(USART2,USART_FLAG_TC)
语句就可避免这个错误,好像还有另外一个函数可以解决这个问题。当然,一直循环发送而忽视第一次发送是没问题,但是对一些只能发送一次的命令,就不太适用;或者加入一个无关的数据来丢失。不过是否每次发送前都要这要,我就没有去验证,估计是硬件复位会的第一次发送会丢失。有兴趣的可以去验证下。所以我把这个语句写进串口发送的子函数里面,每次发送都去清除标志位。
串口子函数部分:
串口子函数部分用数组作为形参,就用到了指针,不多做解释,因为我也是刚学习这个指针的。这个子函数能节省好多行代码,不用一个一个的单独发送。
最重要的串口丢失首位数据的问题解决了和串口发送子函数写好了,剩下的就不是问题了。当然还有一些可以扩展地方,比如说可以拓展一个0.91寸OLED屏幕,用来显示歌名,是可以做到,不过工作量有点大,外接功放和喇叭,那会更棒,欢迎大家提供更多的方案,一起交流。
用ufun的同学需要提醒一下,记得改晶振哦
*******************************************************************************分割线********************************************************************************
有兴趣的小伙伴自行某宝搜索MY1690-12P模块,说明书也很容易的找到。
分享代码:
继续阅读本篇相关更多标签
全部回复 2