×

基于Cortex-M3的MP3播放器设计资料下载

消耗积分:2 | 格式:pdf | 大小:167.6KB | 2021-04-07

Petc

分享资料个

引言STM32系列微控制器采用ARM公司最新的CortexM3内核\[1\]。VS1003音频解码芯片为VS10xx系列的第三代产品,是芬兰VLSI Solution 公司生产的单片MP3/WMA/MIDI解码和ADPCM编码芯片\[2\]。本文采用STM32系列微控制器,结合解码芯片VS1003、SD卡、LCD等外围设备设计并实现了MP3播放器。其主要功能有:播放VS1003支持的所有音频文件,如MP3、WMA、WAV文件,且音质非常好;通过摇杆控制播放上一首/下一首、音量增减等;通过LCD显示歌曲名字和播放状态;本系统还实现了读卡器功能,PC机可通过USB接口直接对开发板上的SD卡进行读写操作,以方便拷贝音频文件。1 STM32处理器CortexM3是ARM公司最新推出的基于ARMv7体系架构的处理器核,具有高性能、低成本、低功耗的特点,专门为嵌入式应用领域设计。ARMv7架构采用了Thumb2技术,它是在ARM的Thumb代码压缩技术的基础上发展起来的,并且保持了对现存ARM解决方案完整的代码兼容性\[3\]。Thumb2技术比纯ARM代码少使用31%的内存,减小了系统开销,同时能够提供比Thumb技术高出38%的性能。在中断处理方面,CortexM3集成了嵌套向量中断控制器NVIC(Nested Vectored Interrupt Controller)。NVIC是CortexM3处理器的一个紧耦合部分,可以配置1~240个带有256个优先级、8级抢占优先权的物理中断,为处理器提供出色的异常处理能力。同时,抢占(Preemption)、尾链(Tailchaining)、迟到技术(Latearriving)的使用,大大缩短了异常事件的响应时间。CortexM3异常处理过程中由硬件自动保存和恢复处理器状态,进一步缩短了中断响应时间,降低了软件设计的复杂性\[3\]。CortexM3体系架构提出了新的单线调试技术,CortexM3处理器的跟踪调试是通过调试访问端口(Debug Access Port,DAP)来实现的。DAP端口可以作为串行线调试端口(SWDP)或串行JTAG调试端口(SWJDP,允许JTAG或SW协议)使用\[3\]。其中SWDP只需要时钟和数据2个引脚,实现低成本跟踪调试,避免使用多引脚进行JTAG调试,并全面支持RealView编译器和RealView调试产品\[4\]。此外CortexM3还具备高度集成化的特点,大大减小了芯片面积,内部集成了许多紧耦合系统外设,合理利用了芯片空间,使系统满足下一代产品的控制需求。STM32系列是基于CortexM3核的微控制器,它在CortexM3内核的基础上扩展了高性能的外围设备。2 VS1003 MP3/WMA音频编解码器VS1003内部包含1个高性能、低功耗的DSP处理核(VSDSP),1个工作内存,1片可供用户程序使用的5.5 KB RAM,1个串行SPI总线接口,1个高质量的采样频率可调的过采样DAC以及1个16位的采样ADC。VS1003的内部结构如图1所示\[2\]。MP3播放过程是STM32通过SPI1接口将数据从SD卡中取出,然后通过SPI2接口送至解码芯片VS1003解码播放。这里解码模块单独使用一个SPI接口,以减小干扰和噪声、提高音质。3 系统硬件设计本系统在硬件上分为6个模块: 微控制器STM32F103、解码模块VS1003、存储模块SD卡、控制摇杆Joystick、USB接口和显示屏LCD。系统硬件框架如图2所示。下面分别介绍系统的存储模块SD卡、解码芯片VS1003与STM32的硬件连接情况。3.1 SD卡与STM32的连接该系统使用STM32内部接口SPI1与SD卡进行通信,下面介绍其引脚连接情况。PE3:低电平有效,连接到SD卡的片选引脚CD/DAT3。SPI在和SD卡进行通信时,需要将PE3拉低才能对SD卡进行操作。PA7:映射为STM32内部接口SPI1的主输出从输入(MOSI)信号线。这里STM32是主设备,SD卡是从设备。数据流的传输方向是从STM32传输给SD卡。该信号线用于传输一些控制命令来完成SD卡的操作,如读、写等。PA5:已连接到STM32内部接口SPI1的时钟(SCLK)信号线。可设置SPI的时钟频率来调整读取SD卡数据的快慢。PA6:已连接到STM32内部接口SPI1的主输入从输出(MISO)信号线。数据的传输方向是从SD卡传输给STM32,主要返回SD卡的一些状态、内部寄存器值等。PC12:用于检测SD卡是否完全插入。当SD卡完全插入时,PC12为低电平,否则为高电平。3.2 VS1003与STM32的连接该系统使用STM32内部接口SPI2与VS1003进行通信,下面介绍其引脚连接情况。PA3:VS1003的中断请求引脚。当VS1003内部数据已处理完毕,需要新的数据时,将DREQ拉高。STM32根据这个信号来给VS1003发送新的数据流。PB13:已连接到STM32内部接口SPI2的时钟(SCLK)信号线。PB14:已连接到STM32内部接口SPI2的主输入从输出(MISO)信号线。这里STM32是主设备,VS1003是从设备。数据流的传输方向是从VS1003传输给STM32。主要用于读取VS1003的一些状态和内部寄存器值,比如寄存器测试返回的内部寄存器的值。PB15:已连接到STM32内部接口SPI2的主输出从输入(MOSI)信号线。这里STM32是主设备,VS1003是从设备。数据流方向是从STM32传输给VS1003,主要传输给VS1003一些控制命令、MP3/WMA数据流等。PA1:低电平有效,如果拉低该引脚,那么通过SPI传输的是控制信号。控制信号包括读写VS1003的内部寄存器、对VS1003进行初始化、设置左右声道音量等。PA2:低电平有效,如果拉低该引脚,那么通过SPI传输的是数据信号。比如在向VS1003传输MP3/WMA的数据流时需要拉低该引脚。PA0:低电平有效,拉低该引脚则硬件复位VS1003。4 系统软件设计本系统的软件由集成开发工具RealView MDK专业版开发,它具有强大的编译、链接和调试功能。软件结构如图3所示。本系统的工作过程大致为:STM32通过SPI1从SD卡中读取MP3/WMA文件,将所读取的数据流通过SPI2发送到VS1003解码器中播放;PC机可通过USB总线读写SD卡的内容,传送MP3/WMA等文件;LCD显示屏用于显示MP3的文件名、播放状态。五维摇杆左右摇动控制播放上一首/下一首,上下摇动控制音量,按下则控制播放/暂停。由于SPI1读取SD卡文件的速度远超过VS1003播放数据流的速度,因此VS1003在播放来自SPI2的数据流期间,SPI1能从SD卡中读取下次播放所需的数据,不会产生声音不连续的情况。由于使用了2个SPI接口,相互之间无干扰,且提高了文件系统的效率,因此本系统能得到非常高品质的音乐。限于篇幅,下面仅介绍软件的两个核心模块。4.1 SD模块SD模块主要提供SD卡驱动以及对FAT文件系统操作的函数,FAT文件系统支持长文件名。该模块主要含有2个文件msd.c和fat16.c。下面分别介绍其主要函数的功能。4.1.1 msd.c该文件用于提供SD卡的驱动,主要包括以下函数。SPI_Config:配置与SD卡相连接的SPI1及相关GPIO。MSD_Init:初始化SD卡通信。Get_Medium_Characteristics:获取SD卡的容量和块大小等相关信息。MSD_GoIdleState:令SD卡处于空闲态。MSD_SendCmd:向SD卡发送命令。MSD_GetResponse:从SD卡获取响应。MSD_GetStatus:获取SD卡的状态。MSD_WriteBlock:向SD卡写入1个块的数据。MSD_ReadBlock:从SD卡读取1个块的数据。以下是函数MSD_ReadBlock的实现:u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead){u32 i = 0;u8 rvalue = MSD_RESPONSE_FAILURE;MSD_CS_LOW();//拉低片选信号,选中SD卡MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);//发送读取块命令//检测SD卡是否有返回信息,若是则返回0x00if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)){if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)){//等待数据令牌,标志数据传输开始for (i = 0; i < NumByteToRead; i++){//读取数据*pBuffer = MSD_ReadByte(); //缓存收到的数据pBuffer++;//缓存指针后移}rvalue = MSD_RESPONSE_NO_ERROR;//修改rvalue的值为成功}}MSD_CS_HIGH();//拉高片选信号,禁用SD卡MSD_WriteByte(DUMMY);//写无效字节,传输结束return rvalue;//返回}4.1.2 fat16.c该文件提供对FAT16文件系统的支持,主要包含以下函数。ReadMBR:读取MBR数据结构。ReadBPB:读取BPB数据结构。ReadFAT:读取文件分配表指定项。ReadBlock:读取SD卡的一个扇区。FAT_Init:获取FAT16文件系统的基本信息。DirStartSec:获取根目录的开始扇区号。DataStartSec:获取数据区的开始扇区号。ClusConvLBA:获取一个簇的开始扇区号。LBAConvClus:转换扇区号与簇号之间的关系。GetFileName:获取指定文件的首扇区号。ListDateTime:列出文件或子目录创建的时间日期。SearchFoler:在指定范围内查找文件或子目录。ListDir:列出指定范围内的文件或子目录及相关信息。FAT_FileOpen:打开指定文件。FAT_FileRead:读取文件数据。4.2 VS1003模块VS1003模块主要提供对解码芯片VS1003的驱动,为应用层播放音频数据、控制音量声道等提供基本接口。该模块主要含文件vs1003.c。其主要函数的功能如下。vs1003.c文件主要提供VS1003芯片的驱动,包含以下几个主要函数。VS1003_Config:配置STM32与VS1003连接的相关引脚,包括SPI2、PA0、PA1、PA2、PA3。SPIGetChar:通过SPI从VS1003读取1个字节。SPIPutChar:通过SPI向VS1003写入1个字节。如果是MP3/WMA数据流,则VS1003将开始解码并播放。Mp3ReadRegister:读取VS1003寄存器的值。Mp3WriteRegister:写VS1003寄存器。Mp3Reset:VS1003复位,包括软件复位和硬件复位。Mp3SoftReset:VS1003软件复位,设置时钟、采样率、重音、音量、立体声等参数,一般在2首乐曲之间需要一次软件复位。VsSineTest:播放正弦声波,用于测试VS1003和STM32的连接是否完好。结语本文提出了一种基于STM32的MP3播放器设计方案,并使用ARM开发工具RealView MDK实现了该方案的原型。尽管该方案无法作为一个通用MP3的方案,但是对于某些音频需要的工业控制、汽车电子、医疗电子等方案具有一定的参考性。另外,本系统综合使用了STM32处��器的多个外围接口,也可供读者学习参考。(mbbeetchina)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'基于Cortex-M3的MP3播放器设计资料下载',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);