📄 m8单片机做得mp3程序.c
字号:
M8_VS1003_SD卡做的MP3播放器
对Bozai(章其波)表示感谢。
复制内容到剪贴板代码:
/*******************************************************************/
/* MP3/Wma/Midi播放器 */
/* 功能:播放文件系统为FAT16/32的SD卡根目录下的MP3/Wma/Mid文件 */
/* 有五个按键分别为 暂停/播放 模式 上一首 下一首 音量+ 音量-*/
/* 环境WinAVR 20060421 */
/* 作者:Bozai(章其波) */
/* E-mail:[email]sudazqb@163.com[/email] */
/* 2006年12月13日 */
/*******************************************************************/
/* MiniMP3 Player (mega8 + VS1003 + SD) V1.1 */
/* */
/* Discription: Can play mp3/wma/wav/mid SF0 files in the root */
/* directery on the SD card which file system is FAT16*/
/* or FAT32. */
/* It has six keys to control this player */
/* MODE: switch between repet all (default),repet one */
/* and shuffle */
/* PLAY/PAUSE: */
/* PREV: previous songs */
/* NEXT: next songs */
/* UP : volume up */
/* DOWN: volume down */
/* Platform : AVRStudio4.13 524 + WinAVR20070122 */
/* optimize -0s */
/* Author : bozai(Zhang Qibo) */
/* E-mail : [email]sudazqb@163.com[/email] */
/* MSN : [email]zhangqibo_1985@hotmail.com[/email] */
/* Date : 2007-02-25 */
/*******************************************************************/
/* Last modify: 2007-02-25 */
/* Change the directory to C:\music\ */
/* A bug fixed */
/* Modify some code to adjust new GCC compiler*/
#include<avr/io.h>
#include"MMC_SD/MMC_SD.h" //head files
#include"FAT/FAT.h"
#include"VS1003B/VS1003B.h"
#include<avr/pgmspace.h>
#define uint unsigned int
//diagnose and state indicate leds
//at start up this two led indicate error
//at normal they indicate the state of the MODE
#define LED1_CON() DDRC|=_BV(PC5)
#define LED1_ON() PORTC|=_BV(PC5)
#define LED1_OFF() PORTC&=~_BV(PC5)
#define LED2_CON() DDRB|=_BV(PB1)
#define LED2_ON() PORTB|=_BV(PB1)
#define LED2_OFF() PORTB&=~_BV(PB1)
//keys
#define STOP _BV(PD2)
#define MODE _BV(PD3)
#define NEXT _BV(PD7)
#define UP _BV(PD4)
#define DOWN _BV(PD6)
#define PREV _BV(PD5)
#define MP3 1
#define WMA 2
#define MID 3
//mode
#define REPET_ALL 0
#define REPET_ONE 1
#define RANDOM 2
extern WORD SectorsPerClust;//每簇扇区数
extern WORD FirstDataSector;//第一个数据扇区数 //struct of file information
extern BYTE FAT32_Enable;
struct FileInfoStruct FileInfo;//文件信息
struct direntry MusicInfo; //要播放的mp3文件信息 //the mp3 file item whichi will be played
uint16 totalsongs; //总的音乐文件数目 //total songs in the root directery on the SD card
uint8 type; //文件类型 //file type
void Delay(uint16 n)//延时
{
while(n--)asm("nop");
}
//Timer initialization offer seed of the srandom()
void Timer1_Initial()
{
TCNT1H=0x00;
TCNT1L=0x00;
TCCR1A=0x03;//ctc mode use icr1
TCCR1B=0x01;//system clock;
ICR1H=0xff;
ICR1L=0xff;
}
void PlayMusicwithKey()//播放音乐函数,一旦执行不会退出
{
uint16 keylen; //用于键处理 //for key processing
uint16 count; //数据计数 //data counting
uint8 i; //循环变量 //loop variable
uint16 j; //循环变量 //loop variable
DWORD p; //簇指示值 //cluster
DWORD totalsect; //文件拥有的扇区数 //cotain the total sector number of a file
uint16 leftbytes; //剩余字节 //cotain the left bytes number of a file //the last cluster usually not fully occupied by the file
uint8 *buffer; //缓冲 //buffer
DWORD sector; //扇区 //recor the current sector to judge the end sector
uint8 flag; //播放/暂停标志 //flag of pause
uint16 vol=DefaultVolume;//初始音量,应与vs1003函数里的初始音量相同 //default volume
uint16 songs=1; //默认放第一首歌 //play the fist songs by default
uint8 mode=0; //单曲重复 //repet all by default
if(totalsongs==0)return;//如果没有歌曲则异常退出 //if no music file return
unsigned long rand_val;
Timer1_Initial();//启动定时器,用于产生随机函数的种子 //initialize the timer
next://下一首歌的起始地方 //label for "goto"
if(mode==RANDOM)//随机播放歌曲 //if the mode is shuffle the songs
{
rand_val = TCNT1;
Delay((random() && 0x00ff));
rand_val <<= 16;
rand_val += TCNT1;
srandom(rand_val);
songs = (unsigned int)(((random()/214749)*(unsigned long)totalsongs)/10000)+1;//随机产生歌曲序号 //create random song number
}
count=0;//清基数 //clear count
flag=1;
while(count<2048 && (type != MID))//recommand 2048 zeros honoring DREQ befor soft reset
{ //用于从wma跳出到下一首歌,和一首歌结束填充数据//midi格式不需要
if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0)
{
for(j=0;j<32;j++)
{
VS1003B_WriteDAT(0x00);//填充0 //fill 0
count++;
}
if(count == 2047)break;
}
}
VS1003B_SoftReset();//soft reset //in case of playing wma files//软件复位
Search("\\music",&MusicInfo,&songs,&type); //找到相应的文件 //find the file
p = MusicInfo.deStartCluster+(((unsigned long)MusicInfo.deHighClust)<<16);//读文件首簇 //the first cluster of the file
totalsect = MusicInfo.deFileSize/512; //计算扇区数 //calculate the total sectors
leftbytes = MusicInfo.deFileSize%512; //计算剩余的字节数 //calculate the left bytes
i=0;
sector=0;
while(1)
{
keylen=0;
for(;i<SectorsPerClust;i++) //一个簇 //a cluster
{
buffer=malloc(512);
FAT_LoadPartCluster(p,i,buffer);//读一个扇区 //read a sector
count=0;
while(count<512)
{
if(flag==0){if(keylen){Delay(100);keylen--;}}
else if(type == MID){if(keylen){Delay(100);keylen--;}}
if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 && flag) //根据需要送数据 //send data honoring DREQ
{
for(j=0;j<32;j++) //每次送32个数据 //32 Bytes each time
{
VS1003B_WriteDAT(buffer[count]);
count++;
}
if(keylen)keylen--; //用于键处理 //for key processing
if(sector == totalsect && count >= leftbytes) //如果文件已结束 //if this is the end of the file
{
if(type == MID)//waiting the midi file was decoded
{//对于mid音乐要接着送2048个零
count=0;
while(count<2048)//recommand 2048 zeros honoring DREQ goto next songs
{
if((VS1003B_PIN & _BV(VS1003B_DREQ))!=0 )
{
for(j=0;j<32;j++)
{
VS1003B_WriteDAT(0x00);
count++;
}
if(count == 2047)break;
}
}
}
i=SectorsPerClust;
break;
}//文件结束 //file ended
if(count == 511){break;}//512字节送完跳出 //break if a sector was sent
}
if((PIND&STOP)==0 /*&& keylen==0*/)//播放暂停键 //key PLAY/PAUSE
{
Delay(100);
if(!(PIND&STOP))
{
while(!(PIND&STOP));
if(flag)flag=0;
else flag=1;
Delay(1000);
}
}
else if(!(PIND&DOWN) && keylen==0) //音量- //Volume down
{
Delay(100);
if(!(PIND&DOWN))
{
keylen=200;
vol=vol+((uint)(1<<8)+1);
if(vol>=0xFEFE) vol=0xFEFE;
else VS1003B_WriteCMD(0x0b,vol);
}
}
else if(!(PIND&UP) && keylen==0) //音量+ //Volume up
{
Delay(100);
if(!(PIND&UP))
{
keylen=200;
vol=vol-((uint)(1<<8)+1);
if(vol<=0x0101) vol=0x0101;
else VS1003B_WriteCMD(0x0b,vol);
}
}
else if(!(PIND&NEXT)) //下一首 next songs
{
Delay(0x7fff);
if(!(PIND&NEXT))
{
Delay(0x7fff);
if(!(PIND&NEXT))
{
while(!(PIND&NEXT));
songs++;
if(songs > totalsongs)songs=1;
{
free(buffer);
// Delay(0xffff);
goto next;
}
}
}
}
else if(!(PIND&PREV)) //上一首 previous songs
{
Delay(0x7fff);
if(!(PIND&PREV))
{
Delay(0x7fff);
if(!(PIND&PREV))
{
while(!(PIND&PREV));
if(songs == 1)songs=totalsongs;
else songs--;
{
free(buffer);
// Delay(0xffff);
goto next;
}
}
}
}
else if((!(PIND&MODE)) && keylen==0) //模式 //mode key
{
Delay(100);
if(!(PIND&MODE))
{
keylen=0xffff;
if(mode==REPET_ALL)
{
mode=REPET_ONE;
LED1_ON();
LED2_OFF();
}
else if(mode==REPET_ONE)//next mode is shuffle
{
mode=RANDOM;
LED1_OFF();
LED2_ON();
srandom(((unsigned long)TCNT1)<<16);//产生随机数的种子
}
else
{
mode=REPET_ALL;
LED1_OFF();
LED2_OFF();
}
}
}
}
sector++;
free(buffer);
}
i=0;
p=FAT_NextCluster(p);//读下一簇数据 //read next cluster
if(p == 0x0fffffff || p == 0x0ffffff8 || (FAT32_Enable == 0 && p == 0xffff))//如果无后续簇则结束, //no more cluster
{
if(mode==REPET_ALL)songs++;
if(songs>totalsongs)songs=1;
goto next;
}
}
}
//main function
int main()
{
DDRD &= 0x03;//初始化端口
PORTD |= 0xfc;
LED1_CON();
LED1_OFF();
LED2_CON();
LED2_OFF();
OSCCAL = 0x00;//最小RC振荡频率 //in order to operate some low speed card the initialization should run at lowest speed
Delay(0xffff);
MMC_SD_Init();//初始化spi口 //SPI initialize
Delay(0xffff);
if(VS1003B_Init())LED1_ON();//配置VS1003 //config vs1003
Delay(0xffff);//提供足够的延时 //supply enough delay
Delay(0xffff);
Delay(0xffff);
Delay(0xffff);
Delay(0xffff);
MMC_SD_Reset();//初始化SD卡 //sd card initialize
OSCCAL = 0xff;//最大RC振荡频率 //normal operation maximum the frequency
Delay(0xffff); //wait for stable
if(FAT_Init())LED2_ON();//初始化文件系统 支持FAT16和FAT32 //initialize file system FAT16 and FAT32 are supported
Search("\\music",&MusicInfo,&totalsongs,&type);//搜索根目下的歌曲 不包含子目录
//也可以指定文件夹 如Search("\\new\\mp3",&MusicInfo,&totalsongs,&type);
//代表在根目录下的new文件夹下的mp3文件下的音乐文件
//search the songs in the root directery on the SD card
//You can also specify the directery where the songs are placed
//eg: Search("\\new\\mp3",&MusicInfo,&totalsongs,&type);
// means search the file in the foler C:\new
PlayMusicwithKey();//播放歌曲 //play songs
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -