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

📄 mega8_player_v11.c

📁 Atmel ATMEGA32 Serial controlled SD card MP3 Player.
💻 C
字号:


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


#define F_CPU 8000000 
#define BAUD 1200
#define UBRR_VAL F_CPU/16/BAUD-1

unsigned char seri_buffer6;
unsigned char seri_buffer5;
unsigned char seri_buffer4;
unsigned char seri_buffer3;
unsigned char seri_buffer2;
unsigned char seri_buffer1;
unsigned char seri_buffer;

unsigned char play_no=0;
unsigned char play=0;



#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() DDRB|=_BV(PB0)
#define LED1_ON()  PORTB|=_BV(PB0)
#define LED1_OFF() PORTB&=~_BV(PB0)

#define LED2_CON() DDRB|=_BV(PB1)
#define LED2_ON()  PORTB|=_BV(PB1)
#define LED2_OFF() PORTB&=~_BV(PB1)

//keys
#define STOP _BV(PC0)
#define MODE _BV(PC1)
#define NEXT _BV(PC2)
#define UP   _BV(PC3)
#define DOWN _BV(PC4)
#define PREV _BV(PC5)

#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


BYTE		songno[8];

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 PlayMusic()//播放音乐函数,一旦执行不会退出
{
	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=1;			//单曲重复			//repet all by default
	if(totalsongs==0)return;//如果没有歌曲则异常退出	//if no music file return
	unsigned long rand_val;

	Timer1_Initial();//启动定时器,用于产生随机函数的种子	//initialize the timer


 
	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//软件复位
	
	//songno[8]="\\1";


	Search(songno[8],&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 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
						{
													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;}  //break if a sector was sent
				}
			}

			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
		{
		
		return;

		}
	}
}





void init_uart(unsigned int ubrr) 

	{
        UBRRH = (unsigned char)(ubrr>>8);
        UBRRL = (unsigned char)(ubrr);

    	UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN);	

		sei(); // Eneable Interrupt

// 8 Databits, receive and transmit enabled, receive and transmit complete interrupt enabled
		
	}


/* Receive interrupt */

SIGNAL(SIG_UART_RECV) 
	
{
	
unsigned char chksum;

		seri_buffer=UDR;

			seri_buffer5=seri_buffer4;
			seri_buffer4=seri_buffer3;
			seri_buffer3=seri_buffer2;
			seri_buffer2=seri_buffer1;
			seri_buffer1=seri_buffer;

		//	UDR=seri_buffer;

//FF 55 99 MN CKS

		if ((seri_buffer5==0xff) & (seri_buffer4==0x55) &(seri_buffer3==0x99))

		{
			chksum=seri_buffer5+seri_buffer4+seri_buffer3+seri_buffer2;
			

			if (seri_buffer1==chksum)
				
				{
					play_no=seri_buffer2;
					play=1;

					UDR=seri_buffer1;

				}
		}


}


SIGNAL(SIG_UART_DATA) 

	{

		UCSRB &= ~(1<<UDRIE);

	}



//main function
int main()
{

start:
	Delay(0xffff);				//supply enough delay
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);

	DDRC &= 0x00;
	PORTD |= 0xfF;
	
	LED1_CON();
	LED1_OFF();
	LED2_CON();
	LED2_OFF();

	Delay(0xffff);

	MMC_SD_Init();					//SPI initialize

	Delay(0xffff);

	if(VS1003B_Init())LED1_ON();	//config vs1003
		
		if(VS1003B_Init()==1) goto start;

	Delay(0xffff);				//supply enough delay
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);
	Delay(0xffff);

	MMC_SD_Reset();			//sd card initialize

	Delay(0xffff);								//wait for stable

	if(FAT_Init())LED2_ON();//initialize file system  FAT16 and FAT32 are supported

if(FAT_Init()==1) goto start;
			

//if (LED1_ON()==1) goto start;
//if (LED2_ON()==1) goto start;


init_uart(UBRR_VAL);



dondur:

	Delay(0xffff);	


	if (play==0x01)

	{

		switch (play_no)

		{

		case 1: 
				songno[8]="\\1";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 2:
				songno[8]="\\2";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 3:
				songno[8]="\\3";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 4: 
				songno[8]="\\4";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 5:
				songno[8]="\\5";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 6:
				songno[8]="\\6";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 7:
				songno[8]="\\7";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 8: 
				songno[8]="\\8";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 9:
				songno[8]="\\9";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 10:
				songno[8]="\\10";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 11: 
				songno[8]="\\11";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 12:
				songno[8]="\\12";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 13:
				songno[8]="\\13";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 14: 
				songno[8]="\\14";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 15:
				songno[8]="\\15";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 16:
				songno[8]="\\16";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 17:
				songno[8]="\\17";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 18: 
				songno[8]="\\18";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 19:
				songno[8]="\\19";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 20:
				songno[8]="\\20";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 21: 
				songno[8]="\\21";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 22:
				songno[8]="\\22";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 23:
				songno[8]="\\23";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 24: 
				songno[8]="\\24";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 25:
				songno[8]="\\25";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 26:
				songno[8]="\\26";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 27:
				songno[8]="\\27";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;
		case 28: 
				songno[8]="\\28";
				Search(songno[8],&MusicInfo,&totalsongs,&type);
				PlayMusic();
				break;

		}

		play=0;
    }

goto dondur;



}




⌨️ 快捷键说明

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