Funpack第十一期—利用LPC55S69开发板播放SD卡中音乐文件
本项目是基于LPC55S69开发板所设计的SD卡内音频文件的读取播放系统,可读取SD卡内指定歌曲文件的音频信息,并将其发送到音频输出端口,控制音频播放设备进行相应的播放。
标签
嵌入式系统
tobi2021
更新2021-11-02
1385

此次活动我选择使用LPC55S69开发板实现SD卡内音频文件的播放,主要用到的设备有有线音箱、LPC55S69开发板、SD卡、个人电脑、安卓线。

一 硬件介绍

LPC55S69是一款ARM Cortex M33内核的单片机,运行频率可高达100MHz,内部包括TrustZone安全空间,保证代码的安全性。该芯片内部由主核心与辅助核心双核心结构构成,大大提高了处理器的性能与灵活性。320KB的SRAM以及高达640KB的闪存。高速与全速USB接口、五个通用定时器、高速SPI以及八个灵活串行通信外设等等工具,可大大方便开发者的设计难度。

LPC55S69开发板是作为LPC55S69微处理器的开发学习用板,该开发板为了方便用户快速了解使用LPC55S69芯片,配置了大量的外围电路,并将相关例程发布在NXP官网上,以供初学者与相关开发人员下载。下图为LPC55S69开发板的外部展示图与功能说明。

开发板框图

LPC55S69开发板外部展示与功能框图

由图中可以看出,LPC55S69开发板外部电路装配有1个USB供电口,两个USB通信接口,以及一个板载调试器,用于程序下载以及在线调试。四个USB接口均可与安卓线相连,方便学习人员的调试。除此之外,开发板还包括SD卡槽,音频输入输出接口,以及RGB灯珠,并提供相应的例程,使开发者可以轻松实现SD卡的读取,音频信号的输入与输出,RGB三色光的调整,进而学习LPC55S69的相关功能。LPC扩展口可轻松连接外部硬件系统,与其他系统进行互动,mikroBUS接口可轻松连接上位机等信息通讯系统,实现互联,PMOD接头可以连接相应的外设。

二 设计思路

针对这次Funpack十一期的任务要求,我选择了利用SD卡播放音乐的任务。由于开发板上自带SD卡槽以及音频输出接口,以及丰富的例程包,使得任务完成的难度降低很多。

实现该功能的设计思路如下图所示。首先完成该芯片相关功能的初始化,其中包括时钟配置,串口初始化,I2C通信初始化,I2S通信初始化,用于与板载WM8904解码芯片通信,FATFS系统初始化,用于读取SD内存卡中的相关信息。在初始化任务结束后,我们首先检测SD卡是否插入到卡槽之中,检测到卡插入之后,向上位机反馈相应的信息,对SD卡进行挂载,随后寻找卡内指定的音频文件,打开文件,并读取相应的文件信息。这里我设置了双缓存区,用于加载音频内容,每个缓存区大小为20KB,首先将一部分内容加载到缓存区1,同时启动音频播放,在音频播放的同时,将下一部分的音频内容加载到缓存区2中,等待音频播放完毕,继续播放缓存区2中的音频信息,再将下一部分信息加载到缓存区1中,依此类推,直到整首歌播放完毕,关闭播放。

流程图

程序运行流程图

本次代码编译环境选择KEIL5软件,指定音乐格式为wav格式,该格式音频文件内部信息为未经加密处理的音频信号,播放较为简单,其他几种格式需要进行解密处理,操作复杂,在这里没有进行相关研究。以下为程序片段。

    /* set BOD VBAT level to 1.65V */
    POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
    CLOCK_EnableClock(kCLOCK_InputMux);

    CLOCK_EnableClock(kCLOCK_Iocon);
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio1);

    /* USART0 clock */
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    /* I2C clock */
    CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);

    PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_XTAL32M_MASK;   /*!< Ensure XTAL16M is on  */
    PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_LDOXO32M_MASK;  /*!< Ensure XTAL16M is on  */
    SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /*!< Ensure CLK_IN is on  */
    ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK;

    CLOCK_AttachClk(kEXT_CLK_to_PLL0);

系统初始化

    PRINTF("\r\nFATFS example to demonstrate how to use FATFS with SD card.\r\n");

    PRINTF("\r\nPlease insert a card into board.\r\n");

		if (sdcardWaitCardInsert() != kStatus_Success)
				{
						return -1;
				}

				if (f_mount(&g_fileSystem, driverNumberBuffer, 0U))
				{
						PRINTF("Mount volume failed.\r\n");
						return -1;
				}

		#if (FF_FS_RPATH >= 2U)
				error = f_chdrive((char const *)&driverNumberBuffer[0U]);
				if (error)
				{
						PRINTF("Change drive failed.\r\n");
						return -1;
				}
		#endif

SD卡配置程序

    error = f_open(&g_fileObject, _T("/song.wav"), (FA_READ | FA_OPEN_EXISTING));
    if (error)
    {
        if (error == FR_EXIST)
        {
            PRINTF("File exists.\r\n");
        }
        else
        {
            PRINTF("Open file failed.\r\n");
            return -1;
        }
    }
    error = f_read(&g_fileObject, music1, sizeof(music1), &bytesRead);
    if ((error) || (bytesRead != sizeof(music1)))
		{
				PRINTF("Read file failed. \r\n");
				failedFlag = true;
		}
	musicflag=1;
	s_TxTransfer.data     = &music1[0];
	s_TxTransfer.dataSize = sizeof(music1);
	I2S_TxTransferCreateHandle(DEMO_I2S_TX, &s_TxHandle, TxCallback, (void*)&s_TxTransfer);
	I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);

文件读取与音乐播放

for(;;)
{
 if(musicflag2!=musicflag)
 {
 if(musicflag==0)
 {
   error = f_read(&g_fileObject, music1, sizeof(music1), &bytesRead);
   if ((error) || (bytesRead != sizeof(music1)))
   {
	PRINTF("Read file failed. \r\n");
        failedFlag = true;
	break;
   }
  }
  else
  {
        error = f_read(&g_fileObject, music2, sizeof(music2), &bytesRead);
	if ((error) || (bytesRead != sizeof(music2)))
	{
	        PRINTF("Read file failed. \r\n");
		failedFlag = true;
		break;
	}
   }
		musicflag2=musicflag;
}
			
}

双缓存填充

static void TxCallback(I2S_Type *base, i2s_handle_t *handle, status_t completionStatus, void *userData)
{
	if((musicflag==0)&&(music_close==0))
	{
		musicflag=1;
		s_TxTransfer.data     = &music1[0];
		s_TxTransfer.dataSize = sizeof(music1);
		I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
	}
	else if((musicflag==1)&&(music_close==0))
	{
		musicflag=0;
		s_TxTransfer.data     = &music2[0];
		s_TxTransfer.dataSize = sizeof(music2);
		I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
	}
	if(bytesRead<0x5000)//
	{
		music_close=1;
	}
}

音乐播放

三、功能展示

将相关程序下载到开发板芯片中,随后将存好音频文件的SD卡插入到开发板中,将音频线分别连接桌面音箱和开发板音频输出接口,随后给音箱和开发板上电,观察开发板的运行效果。能够听到,在上电结束后,音箱可以正常播放SD卡内预设置的音乐文件,并在开发板复位之后也可以从头运行。具体演示可看视频。注意,串口上位机波特率设置为115200,SD卡中请放入wav文件,文件名设置为“song”。

硬件连接图

串口接收信息

四、心得体会

感谢电子森林,硬禾学堂,提供这些非常难得的体验机会!该活动促使我学习了LPC55S69芯片的开发流程,并对音频开发的I2S,SD卡读取所借用的FATFS系统软件进行了相应的学习,是一次很好了解软件的机会,也体会到程序语言对嵌入式开发的重要性。在这里非常感谢硬禾学堂提供的这次机会。

软硬件
元器件
LPC55S69
基于 Arm® Cortex®-M33 的高效微控制器。
附件下载
sdcard_music.rar
程序代码,使用Keil5打开
团队介绍
刚毕业的电气工程大学生,现在为一名电控开发工程师。
团队成员
tobi2021
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号