|
请教一下,我用的阿莫公司的片子,片子没有问题,我弄下来焊在阿莫开发板上没有问题,我制作的程序能完整的播放整段音乐,但中间老有杂音,就好像有划伤的CD片播放声音,用的是STM32的片子,嵌的uC系统,代码如下:请帮看下,谢谢。其中播放单字符没有问题,很正常
u16 MP3_Play(u16 item,u8 *buf ) // item=0 搜索根目录下的 mp3文件并返回数量,不播放
{ // item≠0 从item开始播放
u8 Cnt; // 普通变量
u8 DirSecCout; // 根目录扇区变量
u16 coun; // 扇区内偏移变量
u16 Entry=0; // mp3文件数量
u32 FileClus; // mp3文件簇号
u32 FileSect; // mp3文件长度/扇区变量
u32 totalsect; // 文件拥有的扇区数
u16 leftbytes; // 文件剩余字节
u8 n; // 簇扇区变量
u8 j; // 播放字节变量
u16 count; // 播放缓冲区指针变量
u32 LBA32; // 32bit绝对扇区变量
// u32 Rootcluster; // FAT32根目录簇号暂存变量
u8 Playbuf[512];
GPIO_SetBits(GPIOC, GPIO_Pin_9);
GPIO_ResetBits(GPIOC, GPIO_Pin_12);
// Rootcluster = FirstDircluster;
// FAT32根目录首簇号赋给暂存变量
if(DirSecitemCunt==FAT16) DirSecCout=32;
// FAT16根目录为32扇区
else DirSecCout=BPBSecPerClust;
// FAT32单个根目录为一簇的扇区数,分多个簇段
LBA32 = (u32)FirstDirSector;
for(Cnt=0;Cnt<DirSecCout;Cnt++)
// 在DirSecCout个根目录扇区内搜索
{
if(0 == item) MSD_ReadBlock(buffer, (LBA32+Cnt), 512); // 搜索歌曲
for(coun=0;coun<512;coun+=32) // 目录项基数为32字节
{
if(0 != item) MSD_ReadBlock(buffer, (LBA32+Cnt), 512); // 播放歌曲
if(('.' != buffer[coun])&&(0x00 != buffer[coun])&&(0xE5 != buffer[coun])&&(0x0F != buffer[coun+11]))// 确保是正确可访问文?
{ //文件名32个字节整数倍的开头
if(( buffer[coun+0] == buf[0])&&( buffer[coun+1] == buf[1])&&( buffer[coun+2] == buf[2])&&
( buffer[coun+3] == buf[3])&&( buffer[coun+4] == buf[4])&&( buffer[coun+5] == buf[5])&&
( buffer[coun+6] == buf[6])&&( buffer[coun+7] == buf[7])&&('M' == buffer[coun+8])&&
('P' == buffer[coun+9])&&('3' == buffer[coun+10]))
Entry++;
if((item == Entry)&&(0 != Entry)) // 如果相等开始播放
{
/*printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);
printf1( buffer[coun+0]);printf1( buffer[coun+1]);printf1( buffer[coun+2]);printf1( buffer[coun+3]);
printf1( buffer[coun+4]);printf1( buffer[coun+5]);printf1( buffer[coun+6]);printf1( buffer[coun+7]);
printf1( buffer[coun+8]);printf1( buffer[coun+9]); printf1( buffer[coun+10]); */
Mp3Reset(); // 播放前软复位VS1003b
if(DirSecitemCunt==FAT16)
{
FileClus = 0;
FileClus = ((u16)buffer[coun+26])|((u16)buffer[coun+27]<<8); // 获取FAT16文件首簇号
}
else
{
FileClus = ((u32)buffer[coun+26])|((u32)buffer[coun+27]<<8)|
((u32)buffer[coun+20]<<16)|((u32)buffer[coun+21]<<24); // 获取FAT32文件首簇号
}
FileSect = ((u32)buffer[coun+28])|((u32)buffer[coun+29]<<8)|
((u32)buffer[coun+30]<<16)|((u32)buffer[coun+31]<<24); // 获取文件长度
totalsect = FileSect / 512; // 计算文件拥有的扇区数
if(totalsect<4) goto Exit; // 如果文件小于2K
leftbytes = FileSect % 512; // 计算剩余的字节数
FatClusSec = 0; // 簇号所在的FAT扇区,每首歌播放前清0
while(1) // 音乐播放函数,一曲播放完退出
{
FileSect=(FileClus-2)*BPBSecPerClust+FirstDataSector-8; // 数据扇区=(簇号-2)×每簇扇区数+数据区起始扇区
Mp3SelectData();
Delay_us(1);
Mp3DeselectControl();
Delay_us(1);
for(n=0;n<BPBSecPerClust;n++)// 播放一个簇的全部扇区
{
MSD_ReadBlock(Playbuf, (FileSect+n), 512);// 读一扇区数据到播放缓冲区
count=0;
//Mp3DeselectControl();
//Mp3SelectData();
while(count<512)
{
Delay_us(1);
while (GPIO_ReadInputData(GPIOE) & MP3_DREQ == 0); //等待DREQ为高向VS1003b发送32字节数据
if(GPIO_ReadInputData(GPIOE) & MP3_DREQ)
{
for(j=0;j<32;j++)
{
SPIPutChar(Playbuf[count]);
count++;
// Delay_us(100);
// while (GPIO_ReadInputData(GPIOE) & MP3_DREQ != 0);
}
if((0 ==totalsect)&&(count>=leftbytes)) goto Exit; // 文件结束?
if((n+1 ==BPBSecPerClust)&&(count==32)) FileClus=GetNextCluster(FileClus);
// 播放一簇文件的最后一个扇区时加载下一簇号
if((DirSecitemCunt==FAT16 && FileClus==0x0000FFFF)||(FileClus==0x0FFFFFFF)) goto Exit;
// 防止读取簇号意外出错
}
}
//Mp3DeselectData();
totalsect--; // 文件拥有扇区数减1
}
Mp3DeselectData();
}
Exit:
count=2048; // 放完一首歌,向VS1003b填充2048个0
Mp3SelectData();
while(count)
{
Delay_us(100);
while (GPIO_ReadInputData(GPIOE) & MP3_DREQ == 0); //等待DREQ为高
{
for(j=0;j<32;j++)
{
SPIPutChar(0);
count--;
}
}
}
Mp3DeselectData();
item++; // 放完一首歌加1,否则不能继续播放
}
}
}
}
return Entry; // 返回根目录下mp3文件数量
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|