📄 mega8_player.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 + -