2023年7月11日发(作者:)
本文将介绍一个利用STM32处理器实现简易MP3 Player的设计实例,这个综合应用实例有助于读者了解STM32、SPI接口、SD卡、TIMER、中断、FAT文件系统、USB等的应用。
这里提供了两种设计方案,第一种方案是简易声波播放器,仅使用STM103V100评估板,令计时器TIM4工作在PWM模式下,将wav格式的声波文件从SD卡中读出,由TIM4产生不同频率的方波通过低通滤波器和放大器送喇叭,如图1所示;第二种方案则是简易MP3播放器,还需要使用额外的解码芯片,将MP3格式的文件从SD卡读出,然后送解码芯片解码播放,如图2所示。本节将先介绍SD卡、FAT16文件格式、VS1003编解码器等关键部分,然后再分别给出两种设计方案的软件设计。
图1 简易声波播放器方案
图2 简易MP3 Player方案
1 SD卡的结构与读写方法
1 / 23
STM103V100评估板有SD连接器,其使用SPI总线与STM32处理器连接,如图3所示。
图3 SD连接器与STM32处理器SPI连接图
SD卡(Secure Digital Memory Card)是一种为满足安全性、容量、性能和使用环境等各方面的需求而设计的一种新型存储器件,SD卡允许在两种模式下工作,即SD模式和SPI模式,本系统采用SPI模式。本小节仅简要介绍在SPI模式下,STM32处理器如何读写SD卡,如果读者如希望详细了解SD卡,可以参考相关资料。SD卡部结构与引脚如图4所示。
2 / 23
图4 SD卡部结构与引脚
SD卡主要引脚和功能为:
CLK:时钟信号,每个时钟周期传输一个命令或数据位,频率可在0~25MHz之间变化,SD卡的总线管理器可以不受任何限制的自由产生0~25MHz的频率;
CMD:双向命令和回复线,命令是一次主机到从卡操作的开始,命令可以是从主机到单卡寻址,也可以是到所有卡;回复是对之前命令的回答,回复可以来自单卡或所有卡;
DAT0~3:数据线,数据可以从卡传向主机也可以从主机传向卡。
SD卡以命令形式来控制SD卡的读写等操作。可根据命令对多块或单块进行读写操作。在SPI模式下其命令由6个字节构成,其中高位在前。SD卡命令的格式如表1所示,其中相关参数可以查阅SD卡规。
--------------
3 / 23
表1 SPI命令格式
Byte 1/ Byte2-5/Byte 6
7,6,5,0/31,0/7,0
0,1/Command/Command Argument/CRC,1
------------------------------------
下面分别给出读写SD卡的两个函数:
读取SD卡函数u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16
NumByteToRead);
/*****************************************************************
* Function Name : MSD_ReadBlock
* Description : Reads a block of data from the MSD.
* Input : - pBuffer : pointer to the buffer that receives the data
read
* from the MSD.
* - ReadAddr : MSD's internal address to read from.
* - NumByteToRead : number of bytes to read from the
MSD.
* Output : None
* Return : The MSD Response:
- MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*****************************************************************/
u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
4 / 23
u32 i = 0;
u8 rvalue = MSD_RESPONSE_FAILURE;
/* MSD chip select low */
MSD_CS_LOW();
/* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);
/* Check if the MSD acknowledged the read block command:
R1 response (0x00: no errors) */
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{
/* Now look for the data token to signify the start of the data */
if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
{
/* Read the MSD block data : read NumByteToRead data */
for (i = 0; i < NumByteToRead; i++)
{
/* Save the received data */
*pBuffer = MSD_ReadByte();
/* Point to the next location where the byte read will be saved */
pBuffer++;
}
/* Get CRC bytes (not really needed by us, but required by MSD) */
5 / 23
MSD_ReadByte();
MSD_ReadByte();
/* Set response value to success */
rvalue = MSD_RESPONSE_NO_ERROR;
}
}
/* MSD chip select high */
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
}
写读取SD卡函数u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr,
u16 NumByteToWrite)
/*****************************************************************
* Function Name : MSD_WriteBlock
* Description : Writes a block on the MSD
* Input : - pBuffer : pointer to the buffer containing the data to
be
* written on the MSD.
* - WriteAddr : address to write on.
* - NumByteToWrite: number of data to write
6 / 23
* Output : None
* Return : The MSD Response:
- MSD_RESPONSE_FAILURE: Sequence failed
* - MSD_RESPONSE_NO_ERROR: Sequence succeed
*****************************************************************/
u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
u32 i = 0;
u8 rvalue = MSD_RESPONSE_FAILURE;
/* MSD chip select low */
MSD_CS_LOW();
/* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);
/* Check if the MSD acknowledged the write block command:
R1 response (0x00: no errors) */
if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
{
/* Send a dummy byte */
MSD_WriteByte(DUMMY);
/* Send the data token to signify the start of the data */
MSD_WriteByte(0xFE);
/* Write the block data to MSD : write count data by block */
7 / 23
for (i = 0; i < NumByteToWrite; i++)
{
/* Send the pointed byte */
MSD_WriteByte(*pBuffer);
/* Point to the next location where the byte read will be saved */
pBuffer++;
}
/* Put CRC bytes (not really needed by us, but required by MSD) */
MSD_ReadByte();
MSD_ReadByte();
/* Read data response */
if (MSD_GetDataResponse() == MSD_DATA_OK)
{
rvalue = MSD_RESPONSE_NO_ERROR;
}
}
/* MSD chip select high */
MSD_CS_HIGH();
/* Send dummy byte: 8 Clock pulses of delay */
MSD_WriteByte(DUMMY);
/* Returns the reponse */
return rvalue;
8 / 23
}
2 FAT16文件系统简介
SD卡如果采用FAT16文件格式,按照其不同的特点和作用大致可分为5 部分:MBR区、DBR区、FAT区、FDT区和DATA区。由于SD卡一般不做引导盘,一般也不分区,因此通常无MBR区,直接从DBR区开始。下面对后面四个区分别作简介:
DBR区
容为系统引导记录,它包括一个引导程序和一个被称为BPB(Bios
Parameter Block)的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区根目录是否有操作系统引导文件,如果有则将其读入存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、根目录大小、FAT个数,分配单元大小等重要参数。本系统采用的DBR结构为:
typedef __packed struct
{/* 由于Cortex-M3核默认以对齐方式访问,因此可能导致结构体元素之间有“空隙”,读出的结构体元素有误,因此需要加上关键字__packed,强制其以压缩方式存储结构体。这样该结构体在存空间上是一片连续的空间,不存在“空隙”情况。其它地方同理 */
u8 BS_jmpBoot[3]; //ofs:0.典型的如:0xEB,0x3E,0x90
u8 BS_OEMName[8]; //ofs:3.典型的如:“MSWIN4.1”
u16 BPB_BytesPerSec; //ofs:11.每扇区字节数
u8 BPB_SecPerClus; //ofs:13.每簇扇区数
u16 BPB_RsvdSecCnt; //ofs:14.保留扇区数,从DBR 到FAT 的扇区数
u8 BPB_NumFATs; //ofs: 的个数,通常为2
u16 BPB_RootEntCnt; //ofs:17.根目录项数
u16 BPB_TotSec16; //ofs:19.分区总扇区数(<32M时用)
9 / 23
u8 BPB_Media; //ofs:21.分区介质标识,SD卡一般用0xF8
u16 BPB_FATSz16; //ofs:22.每个FAT 占的扇区数
u16 BPB_SecPerTrk; //ofs:24.每道扇区数,对于SD卡无意义
u16 BPB_NumHeads; //ofs:26.磁头数,对于SD卡无意义
u32 BPB_HiddSec; //ofs:28.隐藏扇区数,从MBR到DBR的扇区数
u32 BPB_TotSec32; //ofs:32.分区总扇区数(≥32M时用)
u8 BS_DrvNum; //ofs:36.软盘:0x00,硬盘:0x80,SD卡无意义
u8 BS_Reservedl; //ofs:37.保留
u8 BS_BootSig; //ofs:38.扩展引导标记:0x29,通常对于SD卡无意义
u32 BS_VolID; //ofs:39.盘序列号
u8 BS_VolLab[11]; //ofs:43.如“Msdos ”
u8 BS_FilSysType[8]; //ofs:54.“FAT16 ”
u8 ExecutableCode[448]; //ofs:62.引导代码
u8 ExecutableMarker[2]; //ofs:510.结束标识:0xAA55
} FAT_BPB;
FAT区
该区容为文件分配表,FAT16文件系统进行空间分配的最基本单位是簇。文件分配表反映了SD卡所有簇的使用情况,通过查文件分配表可以得知任一簇的使用情况。对于FAT16来说,FAT表每项占用两个字节。FAT表的第一项通常为FFF8H。对于其它项,若其值为0000H表示可用;FFF7H表示为坏簇;FFF8H-FFFFH10 / 23
之间表示该簇为某文件或目录的最后一个簇,FFF0H-FFF6H之间为保留值;其它值则指示下一个簇的簇号。
FDT区
该区的容为文件目录表,FAT文件系统的一个重要思想是把目录(文件夹)当作一个特殊的文件来处理,FAT32甚至将根目录当作文件处理。FAT分区中所有目录文件,实际上可以看作是一个存放其它文件(文件夹)入口参数的数据表。因此,目录占用空间的大小并不等同于其下所有数据的大小,但也不等于0,通常是占很小的空间。其具体的存储原理是:不管目录文件所占空间为多少簇,一簇为多少扇区、多少字节;系统都会以32个字节为单位,进行目录文件所占簇的分配。本系统目录项使用的结构体如下:
typedef __packed struct
{
u8 FileName[8]; //ofs:0.文件名
u8 ExtName[3]; //ofs:8.扩展名
u8 Attribute; //ofs:11.文件属性。典型值:存档(0x20)、卷标(0x08)
u8 Reserved[10]; //ofs:21.保留
u16 Time; //ofs:22.时间
u16 Data; //ofs:24.日期
u16 StartClus; //ofs:26.开始簇号
u32 FileLength; //ofs:28.文件长度
} DIR;
由于篇幅关系,这里不能对上面各字段进行一一介绍。
本系统支持长文件名和汉字显示,如果使用短文件名,则以ASCII编码;当文件名超过8个字节,扩展名超过3字节时,就以长文件名的形式存储,长文件名中的字符采用UNICODE形式编码,每个字符占据2个字节的空间,其目录项中偏移为11的字节即Attribute字段为0FH。在存储时将长文件名以13个字符为单位11 / 23
进行切割,每一组占据一个目录项,所以可能一个文件需要多个目录项,这时长文件名的各个目录项按倒序排列在目录表中,以防与其他文件名混淆。
本系统采用串口作为输入输出接口,通过在PC的超级终端中输入命令来对其进行控制,并在超级终端中显示输出的结果,如路径、目录列表、文件名等相关信息。超级终端输入输出的汉字以GB2312编码、输入输出英文字符以ASCII编码,而长文件名以UNICODE编码。因此需要将UNICODE编码转化为GB2312或ASCII编码来和用户交互。这里使用一排序二维表,里面有7000多个汉字UNICODE编码对应的GB2312编码。这里查找算法采用二分查找算法,大大提高了查找效率,这对于嵌入式应用很关键。
DATA区
该数据区存放文件的容,SD卡所占用的空间绝大部分为此部分。如果文件长度大于一个簇的大小,需要多个簇存放该文件,这些放通过FAT链表串连起来。
3 VS1003-MP3/WMA音频编解码器简介
VS1003是由芬兰VLSI Solution Oy公司所设计的一款单片MP3/WMA/MIDI音频解码器和ADPCM编码器,它包含一个高性能、自主产权的低功耗DSP处理器核VS_DSP4。该芯片部结构如图5所示,其特点如下:
12 / 23
图5 VS1003部结构与引脚
可解码MPEG 1和MPEG 2音频层III(CBR+VBR+ABR)、WMA 4.0/4.1/7/8/9
5-384kbps 所有流文件;WAV(PCM+IMA AD-PCM),可产生MIDI/SP-MIDI 文件;
可对话筒输入或线路输入的音频信号进行IMA ADPCM编码;
支持MP3和WAV流;
高音、低音控制;
单时钟操作(12..13MHz);
部PLL锁相环时钟倍频器;
低功耗
含高性能片上立体声数模转换器,两声道间无相位差;
含能驱动30欧负载的耳机驱动器;
模拟、数字、I/O单独供电;
为用户代码和数据准备了5.5KB片上RAM;
串行的控制、数据接口;
可被用作微处理器的从机;
特殊应用的SPI Flash引导;
供调试用途的UART接口;
新功能可以通过软件和4个GPIO添加。
限于篇幅,这里不对VS1003芯片作详细介绍,读者有兴趣可查阅相关资料与数据手册。
注意,VS1003可以作为一个微控制器的从机,通过串行SPI接口来接收输入的比特流,输入的比特流被解码后,可以通过一个数字音量控制器到达一个18 位过采样多位DAC。这样利用一个VS1003芯片与STM32F103x处理器配合,STM32处理器读取SD卡中的MP3文件,将其通过SPI接口送往VS1003芯片播放,然后再利用STM32F10X处理器的一些GPIO口来控制VS1003即可以实现一个MP3
Player的原形设计。
13 / 23
2 FAT16文件系统简介
SD卡如果采用FAT16文件格式,按照其不同的特点和作用大致可分为5 部分:MBR区、DBR区、FAT区、FDT区和DATA区。由于SD卡一般不做引导盘,一般也不分区,因此通常无MBR区,直接从DBR区开始。下面对后面四个区分别作简介:
DBR区
容为系统引导记录,它包括一个引导程序和一个被称为BPB(Bios
Parameter Block)的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区根目录是否有操作系统引导文件,如果有则将其读入存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、根目录大小、FAT个数,分配单元大小等重要参数。本系统采用的DBR结构为:
typedef __packed struct
{/* 由于Cortex-M3核默认以对齐方式访问,因此可能导致结构体元素之间有“空隙”,读出的结构体元素有误,因此需要加上关键字__packed,强制其以压缩方式存储结构体。这样该结构体在存空间上是一片连续的空间,不存在“空隙”情况。其它地方同理 */
u8 BS_jmpBoot[3]; //ofs:0.典型的如:0xEB,0x3E,0x90
u8 BS_OEMName[8]; //ofs:3.典型的如:“MSWIN4.1”
u16 BPB_BytesPerSec; //ofs:11.每扇区字节数
u8 BPB_SecPerClus; //ofs:13.每簇扇区数
u16 BPB_RsvdSecCnt; //ofs:14.保留扇区数,从DBR 到FAT 的扇区数
u8 BPB_NumFATs; //ofs: 的个数,通常为2
u16 BPB_RootEntCnt; //ofs:17.根目录项数
u16 BPB_TotSec16; //ofs:19.分区总扇区数(<32M时用)
u8 BPB_Media; //ofs:21.分区介质标识,SD卡一般用0xF8
14 / 23
u16 BPB_FATSz16; //ofs:22.每个FAT 占的扇区数
u16 BPB_SecPerTrk; //ofs:24.每道扇区数,对于SD卡无意义
u16 BPB_NumHeads; //ofs:26.磁头数,对于SD卡无意义
u32 BPB_HiddSec; //ofs:28.隐藏扇区数,从MBR到DBR的扇区数
u32 BPB_TotSec32; //ofs:32.分区总扇区数(≥32M时用)
u8 BS_DrvNum; //ofs:36.软盘:0x00,硬盘:0x80,SD卡无意义
u8 BS_Reservedl; //ofs:37.保留
u8 BS_BootSig; //ofs:38.扩展引导标记:0x29,通常对于SD卡无意义
u32 BS_VolID; //ofs:39.盘序列号
u8 BS_VolLab[11]; //ofs:43.如“Msdos ”
u8 BS_FilSysType[8]; //ofs:54.“FAT16 ”
u8 ExecutableCode[448]; //ofs:62.引导代码
u8 ExecutableMarker[2]; //ofs:510.结束标识:0xAA55
} FAT_BPB;
FAT区
该区容为文件分配表,FAT16文件系统进行空间分配的最基本单位是簇。文件分配表反映了SD卡所有簇的使用情况,通过查文件分配表可以得知任一簇的使用情况。对于FAT16来说,FAT表每项占用两个字节。FAT表的第一项通常为FFF8H。对于其它项,若其值为0000H表示可用;FFF7H表示为坏簇;FFF8H-FFFFH之间表示该簇为某文件或目录的最后一个簇,FFF0H-FFF6H之间为保留值;其它值则指示下一个簇的簇号。
FDT区
15 / 23
该区的容为文件目录表,FAT文件系统的一个重要思想是把目录(文件夹)当作一个特殊的文件来处理,FAT32甚至将根目录当作文件处理。FAT分区中所有目录文件,实际上可以看作是一个存放其它文件(文件夹)入口参数的数据表。因此,目录占用空间的大小并不等同于其下所有数据的大小,但也不等于0,通常是占很小的空间。其具体的存储原理是:不管目录文件所占空间为多少簇,一簇为多少扇区、多少字节;系统都会以32个字节为单位,进行目录文件所占簇的分配。本系统目录项使用的结构体如下:
typedef __packed struct
{
u8 FileName[8]; //ofs:0.文件名
u8 ExtName[3]; //ofs:8.扩展名
u8 Attribute; //ofs:11.文件属性。典型值:存档(0x20)、卷标(0x08)
u8 Reserved[10]; //ofs:21.保留
u16 Time; //ofs:22.时间
u16 Data; //ofs:24.日期
u16 StartClus; //ofs:26.开始簇号
u32 FileLength; //ofs:28.文件长度
} DIR;
由于篇幅关系,这里不能对上面各字段进行一一介绍。
本系统支持长文件名和汉字显示,如果使用短文件名,则以ASCII编码;当文件名超过8个字节,扩展名超过3字节时,就以长文件名的形式存储,长文件名中的字符采用UNICODE形式编码,每个字符占据2个字节的空间,其目录项中偏移为11的字节即Attribute字段为0FH。在存储时将长文件名以13个字符为单位进行切割,每一组占据一个目录项,所以可能一个文件需要多个目录项,这时长文件名的各个目录项按倒序排列在目录表中,以防与其他文件名混淆。
本系统采用串口作为输入输出接口,通过在PC的超级终端中输入命令来对其进行控制,并在超级终端中显示输出的结果,如路径、目录列表、文件名等相关信16 / 23
息。超级终端输入输出的汉字以GB2312编码、输入输出英文字符以ASCII编码,而长文件名以UNICODE编码。因此需要将UNICODE编码转化为GB2312或ASCII编码来和用户交互。这里使用一排序二维表,里面有7000多个汉字UNICODE编码对应的GB2312编码。这里查找算法采用二分查找算法,大大提高了查找效率,这对于嵌入式应用很关键。
DATA区
该数据区存放文件的容,SD卡所占用的空间绝大部分为此部分。如果文件长度大于一个簇的大小,需要多个簇存放该文件,这些放通过FAT链表串连起来。
3 VS1003-MP3/WMA音频编解码器简介
VS1003是由芬兰VLSI Solution Oy公司所设计的一款单片MP3/WMA/MIDI音频解码器和ADPCM编码器,它包含一个高性能、自主产权的低功耗DSP处理器核VS_DSP4。该芯片部结构如图5所示,其特点如下:
图5 VS1003部结构与引脚
可解码MPEG 1和MPEG 2音频层III(CBR+VBR+ABR)、WMA 4.0/4.1/7/8/9
5-384kbps 所有流文件;WAV(PCM+IMA AD-PCM),可产生MIDI/SP-MIDI 文件;
17 / 23
可对话筒输入或线路输入的音频信号进行IMA ADPCM编码;
支持MP3和WAV流;
高音、低音控制;
单时钟操作(12..13MHz);
部PLL锁相环时钟倍频器;
低功耗
含高性能片上立体声数模转换器,两声道间无相位差;
含能驱动30欧负载的耳机驱动器;
模拟、数字、I/O单独供电;
为用户代码和数据准备了5.5KB片上RAM;
串行的控制、数据接口;
可被用作微处理器的从机;
特殊应用的SPI Flash引导;
供调试用途的UART接口;
新功能可以通过软件和4个GPIO添加。
限于篇幅,这里不对VS1003芯片作详细介绍,读者有兴趣可查阅相关资料与数据手册。
注意,VS1003可以作为一个微控制器的从机,通过串行SPI接口来接收输入的比特流,输入的比特流被解码后,可以通过一个数字音量控制器到达一个18 位过采样多位DAC。这样利用一个VS1003芯片与STM32F103x处理器配合,STM32处理器读取SD卡中的MP3文件,将其通过SPI接口送往VS1003芯片播放,然后再利用STM32F10X处理器的一些GPIO口来控制VS1003即可以实现一个MP3
Player的原形设计。
5 简易MP3 Player的设计与实现
18 / 23
第4小节所介绍的声音播放器,是通过定时器TIM4产生不同频率方波来产生声音的,因此只适合播放wav声波文件,其音质也非常粗糙。如果希望播放MP3文件,并产生高品质的声音,则需要使用专用声音解码芯片,这将得到一个简易MP3 Player原型设计。
5.1 硬件设计
如图8所示,STM32F103x使用SPI2端口与VS1003芯片的SI、SO、SCLK连接;VS1003芯片的控制引脚xCS、xRESET、xDCS分别与STM32F103的PA1、PA0和PA2连接,低电平有效;VS1003的状态引脚DREQ与STM32F103处理器的PA3连接,低电平表示需要送数据,高电平表示正在处理数据。
读者如果没有条件制作硬件,可以使用一块VS1003的评估板和STM103V100评估板配置,只需要使用电缆实现上述连接与供电即可,实验成本也非常低。
图8 简易MP3 Player硬件原理图
19 / 23
5.2 软件程序设计
由上面所述容与图2、图8可以得到简易MP3 Player的软件工作过程:通过SPI1从SD卡中读取MP3文件,将所读取的容通过SPI2发送到VS1003解码器中播放;PC机可通过USB总线读写SD卡的容,传送MP3文件;PC机的超级终端用于发送MP3播放命令、显示MP3 播放状态。
由于SPI1读取SD卡的速度远超过VS1003播放声音的速度,因此在VS1003播放SPI2送给其的声音数据期间,SPI1能从SD卡中读取下次播放所须的数据,不会产生声音不连续的情况。
读者也可以尝试采用更有效的中断方式,在存中设置一个环形的缓冲区,SPI1从SD卡读取的MP3文件数据存放在其中,当VS1003需要数据时其DREQ引脚将产生低电平,利用其产生中断,在中断服务程序中从缓冲区读取数据送VS1003,直至DREQ引脚恢复为高电平时退出中断。
该系统软件程序主要包含以下源文件,下面分别介绍其中主要的一些函数。限于篇幅这里不能给出工程的源代码,读者可在附件里下载所有源代码。
main.c
该源文件包含以下几个主要函数:
USART_Scanf_Name和USART_Scanf_Cmd:用于从超级终端获取输入字符串;
PrintPass:用于在超级终端上输出提示符“X:>”;
main: 主函数,首先初始化系统时钟、串口、USB接口、SPI1、SPI2,通过命令启动VS1003芯片,检测并在超级终端上打印SD卡的信息;然后根据用户在超级中输入的命令进行操作,这里有“dir”、“cd”、“read”、“free”、“usb”、“vstest”、“play”七个简单的命令,分别是目录项列表、目录更换、以文本方式读取文件、查询SD空余空间、启动读卡器功能、VS1003正弦测试、和播放MP3声音文件;如果输入“Play ***.mp3”,则处理器开始从SD卡中读取相应的MP3文件,并将其送VS1003芯片播放;
VS1003.c
该文件主要提供VS1003芯片的驱动,包含以下几个主要函数:
VS1003_Config:配置STM32处理器与VS1003芯片连接的相关引脚,包括SPI2、PA1、PA0、PA2、PA3;
20 / 23
SPIGetChar:通过SPI从VS1003读取一个数据;
SPIPutChar:通过SPI向VS1003写一个数据,如果是MP3声音数据,则VS1003将解码并播放;
Mp3ReadRegister:读取VS1003寄存器的值;
Mp3WriteRegister:写VS1003寄存器
Mp3Reset:VS1003硬件复位;
Mp3SoftReset:VS1003软件复位,设置时钟、采样率、重音、音量、立体声等参数;
VsSineTest:播放正弦声波,用于测试;
msd.c
该文件用于提供SD卡的驱动,与小节4.1中的msd.c文件一样。
fat16.c
该文件提供FAT16文件系统的支持,与小节4.1中的fat16.c文件一样。
UnicodeToGB2312.c
该文件处理从UniCode编码到GB2312字符的转换,与小节4.1中的UnicodeToGB2312.c文件一样。
memory.c
该源文件提供通过USB接口进行SD存储管理的功能。其主要函数有:
Address_Management_Test:测试接收到的存储地址;
Read_Memory:通过USB读取SD卡;
Write_Memory:通过USB写SD卡;
hw_config.c
该文件包含系统初始化设置函数和中断配置函数。
21 / 23
Set_System:用于提供系统时钟与电源设置;
Set_USBClock:配置USB端口所使用引脚与时钟。
5.3 运行过程
(1)
使用MDK通过ULINK 2仿真器连接STM103V100开发板,或使用两根USB电缆分别将CN1和CN5 与PC机USB端口相连(使用板上自带的UlinkMe);
(2)
使用USB电缆连接CN1与PC机USB端口;将VS1003评估板与STM103V100评估板相关引脚连接,具体连接参考5.1小节;
(3)
使用串口线将开发板的串口COM0与PC机连接,在PC机上运行windows自带的超级终端串口通信程序(波特率115200、1位停止位、无校验位、无硬件流控制);或者使用其它串口通信程序;
(4)
打开所下源代码目录PlayerSimple MP3 Player下的Simple MP3
2工程,将其编译后烧写到开发板中;
(5)
将MP3文件拷贝到SD卡中,并将SD插入评估板的SD连接器中;
(6)
重启动开发板,在超级终端上将看到SD卡的信息以与提示符“X:>”,如图9-2-7所示;
(7)
可在超级终端中输入“dir”、“cd”、“free”、“usb”、“vstest”、“read”等命令(注:read 命令后跟文件名;读出并输出文件的文本容,可以正确显示文本文件如以txt,c,h,s为后缀的文件),观察运行结果;注意,由于程序中没有进行大小写转换,因此命令只能使用小写;
(8)
在超级终端中输入“play ***.mp3”,如果程序运行正常,通过VS1003评估版的耳机将能听到高品质音乐声,如图9所示。
22 / 23
图9 播放MP3音乐
本系统只是实现了简易MP3 Player的基本原型设计,读者可以进一步利用STM103V100评估板资源来完善和丰富该MP3 Player的功能,例如利用Joystick来选择歌曲、利用LCD来显示歌曲名、利用ADC来调节音量、利用几个LED灯来表示音量。如果能完成以上所有相关设计,则可以基本熟悉STM32处理器的各种应用开发。
STM103V100评估板与VS1003解码模块的引脚连接:
PA3 DREQ
PB13 SCLK
PB14 SO
PB15 SI
PA1 /xCS
PA2 /xDCS
PA0 /xRESET
23 / 23
发布者:admin,转转请注明出处:http://www.yc00.com/news/1689065063a202151.html
评论列表(0条)