⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mega8_player.c

📁 mega8的mp3代码
💻 C
字号:
/*******************************************************************/
/*                   MP3/Wma/Midi播放器                            */
/*  功能:播放文件系统为FAT16/32的SD卡根目录下的MP3/Wma/Mid文件    */
/*        有五个按键分别为 暂停/播放 模式 上一首 下一首 音量+ 音量-*/
/*  环境WinAVR 20060421                                            */
/*  作者:Bozai(章其波)                                          */
/*  E-mail:sudazqb@163.com                                        */
/*  2006年12月03日                                                 */
/*******************************************************************/



#include<avr/io.h>
#include"MMC_SD/MMC_SD.h"
#include"FAT/FAT.h"
#include"VS1003B/VS1003B.h"
#include<avr/pgmspace.h>

#define uint unsigned int

#define ENTER_KEY 0x0d
#define BACK_KEY  0x08
#define ESC_KEY   0x1b
#define MAX       64

#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)

#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 STOP _BV(PD5)
#define NEXT _BV(PD3)
#define UP   _BV(PD6)
#define DOWN _BV(PD2)
#define PREV _BV(PD4)
*/
#define MP3 1
#define WMA 2
#define MID 3

extern WORD SectorsPerClust;//每簇扇区数
extern WORD FirstDataSector;//第一个数据扇区数

struct FileInfoStruct FileInfo;//文件信息

struct direntry MusicInfo;//要播放的mp3文件信息
uint16 totalsongs;//总的音乐文件数目
uint8 type;//文件类型



void Delay(uint16 n)//延时
{
	while(n--);
}

void PlayMusicwithKey()//播放音乐函数,一旦执行不会退出
{
	uint16 keylen;//用于建处理
	uint16 count;//数据计数
	uint8 i;//循环变量
	uint16 j;//循环变量
	DWORD p;//簇指示值
	DWORD totalsect;//文件拥有的扇区数
	uint16 leftbytes;//剩余字节
	uint8 *buffer;//缓冲
	DWORD sector;//扇区
	uint8 flag=1;//播放/暂停标志
	uint16 vol=0x2020;//初始音量,应与vs1003函数里的初始音量相同
	uint8 songs=1;//默认放第一首歌
	uint8 mode=0;//单曲重复
	if(totalsongs==0)return;//如果没有歌曲则异常退出

next://下一首歌的起始地方
	count=0;//清基数
	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
				count++;
			}
			if(count == 2047)break;
		}
	}
	VS1003B_SoftReset();//soft reset //in case of playing wma files//软件复位
	Search("\\",&MusicInfo,&songs,&type);//找到相应的文件
	p     = MusicInfo.deStartCluster+(((unsigned long)MusicInfo.deHighClust)<<16);//读文件首簇
		
	totalsect = MusicInfo.deFileSize/512; //计算扇区数
	leftbytes = MusicInfo.deFileSize%512; //计算剩余的字节数
	i=0;
	sector=0;
	
	while(1)
	{
		keylen=0;
    	for(;i<SectorsPerClust;i++)//一个簇
		{
			buffer=malloc(512);
			SPI_High();//调到适合sd卡操作的速度
			FAT_LoadPartCluster(p,i,buffer);//读一个扇区
		 	VS1003B_SPI_High();//调到适合vs1003的速度
			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)//根据需要送数据
				{
					for(j=0;j<32;j++)//每次送32个数据
					{
						VS1003B_WriteDAT(buffer[count]);
						count++;
					}
					if(keylen)keylen--;//用于键处理
					if(sector == totalsect && count >= leftbytes)//如果文件已结束
					{
						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;
					}//文件结束
					if(count == 511){break;}//512字节送完跳出
				}
				if((PIND&STOP)==0 && keylen==0)//播放暂停键
			    {
	 			    Delay(100);
					if(!(PIND&STOP))
					{
						keylen=10000;
						 if(flag)flag=0;
						 else flag=1;
					 }
				 }
				else if(!(PIND&DOWN) && keylen==0)  //音量-
	 			{
				    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) //音量+
	  			 {
					 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)) //下一首
	 			 {
					Delay(50000);		
					if(!(PIND&NEXT))
					{
						while(!(PIND&NEXT));
						songs++;
						if(songs > totalsongs)songs=1;
						{free(buffer);goto next;}
					}
	  			 }
				 else if(!(PIND&PREV)) //上一首
	 			 {
					Delay(5000);		
					if(!(PIND&PREV))
					{
						while(!(PIND&PREV));
						if(songs == 1)songs=totalsongs;
						else songs--;
						{free(buffer);goto next;}
					}
	  			 }
				 else if((!(PIND&MODE)) && keylen==0) //模式
	 			 {
					Delay(100);		
					if(!(PIND&MODE))
					{
						keylen=50000;
						if(mode){mode=0;LED2_OFF();}
						else {mode=1;LED2_ON();}
					}
	  			 }
			}
			sector++;
			free(buffer);
		}
		i=0;
		p=FAT_NextCluster(p);//读下一簇数据
		if(p == 0x0fffffff || p == 0xffff)
		{if(mode==0)songs++;if(songs>totalsongs)songs=1;goto next;}//如果无后续簇则结束,//正常情况不会执行到
	}
}

int main()
{
	DDRD &= 0x03;//初始化端口
	PORTD |= 0xfc;
	
	LED1_CON();
	LED1_OFF();
	LED2_CON();
	LED2_OFF();

	OSCCAL = 0xff;//最大RC振荡频率
	OSCCAL = 0xff;
	Delay(0xffff);

	MMC_SD_Init();//初始化spi口

	Delay(0xffff);

	if(VS1003B_Init())LED1_ON();//配置VS1003

	Delay(0xffff);//提供足够的延时
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);

	MMC_SD_Reset();//初始化SD卡

	if(FAT_Init())LED2_ON();//初始化文件系统 支持FAT16和FAT32

	Search("\\",&MusicInfo,&totalsongs,&type);//搜索根目下的歌曲 不包含子目录
	//也可以指定文件夹 如Search("\\new\mp3",&MusicInfo,&totalsongs,&type);
	//代表在根目录下的new文件夹下的mp3文件下的音乐文件

	PlayMusicwithKey();//播放歌曲
	return 0;
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -