📄 mp3.c
字号:
/*-------------------------------------------------------------
MP3 Player
XieLiangHui
AVR Studio 4.12 sp4+ WinAvr 2005-11-5
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <avr/eeprom.h>
#include <stdio.h>
#include "comm.h"
#include "vs1003.h"
#include "mp3.h"
#include "sd.h"
#include "fat.h"
#include "lcd.h"
#include "bmp.h"
#include "delay.h"
MENU_CONECT m_c[4]; //保存目录显示的四行文件名
/*每一秒中断一次
ISR(SIG_OVERFLOW0) //Real Time Count every 1s interrupt
{
TimeFlag|=bT1S;
}
// 每32.768MS中断一次
ISR(SIG_OVERFLOW2)
{
TimeFlag|=(bT32MS|bTkey);
Rtime++;
} */
uchar MenuCnt;
uchar MenuMode;
uchar SelIndex;
ulong CurDir;
uchar fileindex=1;
uint TotalFile;
#define VIEW_MODE 1
#define PLAY_MODE 2
#define STBY_MODE 3
#define SET_MODE 4
#define RADIO_MODE 5
#define REC_MODE 6
unsigned long filelength;
unsigned int voltbl[] PROGMEM ={
0x9191,0x8c8c,0x8787,0x8282,0x7d7d,0x7878,0x7373,0x6e6e,0x6969,0x6464,
0x5f5f,0x5a5a,0x5555,0x5050,0x4b4b,0x4646,0x4141,0x3c3c,0x3737,0x3232,
0x2d2d,0x2828,0x2323,0x1e1e,0x1919,0x1414,0x0f0f,0x0a0a,0x0505,0x0000
};
TIME rtc;
//extern unsigned long FileSize;
extern PARTRECORD PartInfo;
/*
void Delay2s(void)
{
unsigned char i;
i=Rtime;
while((Rtime-i)<60);
}
*/
void ReadConfig(void)
{
unsigned char flag;
flag=eeprom_read_byte((uchar*) kEepFlag);
if(flag!=0xab){
vol=5; fileindex=1; SelIndex=0;CurDir=fatGetRootClust();
TotalFile=0; flag=0xab;
eeprom_write_byte((uchar*)kEepFlag,flag);
eeprom_busy_wait();
eeprom_write_byte((uchar*) kEepVol,vol);
eeprom_busy_wait();
}else{
vol=eeprom_read_byte((uchar*)kEepVol);
// eeprom_read_byte(&MenuMode,(void *) kEepMenuMode);
// eeprom_read_word(&fileindex,(void *)kEepfileindex);
}
MenuCnt=0; TotalFile=0; PlayMode=0;
MenuMode=STBY_MODE; MenuCnt=0;
vs1003_cmd_write(0x0b,pgm_read_word(voltbl+vol));
}
int main()
{
InitSystem();
FindSysFile(); //查找系统文件(汉字库,及编码转换文件)
ReadConfig(); //读取配置数据
MenuMode=STBY_MODE;
StopPlay();
while(TRUE) {
GetKey();
RtcCount();
MenuOpter();
LcdWrite();
MusicPlay();
LyricDisplayCtrl();
}
return 0;
}
void GetKey(void)
{
//按键处理程序
static unsigned char sakey=kNull;
static unsigned char KeyCnt=0;
unsigned char tempKey;
if(!(TimeFlag&bTkey)) return;
TimeFlag&=~bTkey;
tempKey = kNull;
if(!(PINE&PLAY)){
tempKey =kPlay;
}else if(!(PINE&VOLDOWN)){
tempKey = kVolDown;
}else if(!(PINE&VOLUP)) {
tempKey = kVolUp;
}else if(!(PINE&NEXTSONG)){
tempKey = kNext;
}else if(!(PINE&PREVSONG)){
tempKey = kPrev;
}
if(tempKey==sakey){
if(tempKey!=kNull){
if(++KeyCnt>30) KeyVal=sakey+0x10;
}
return;
}
KeyCnt=0;
sakey=tempKey;
if(sakey!=kNull) KeyVal=sakey;
}
void MusicPlay(void)
{
unsigned char n;
while(TRUE){
if(!(WorkFlag&bReadOvr)){
if(!ReadFileData()) WorkFlag|=bReadOvr;
}
//---------数据写入VS1003-----------------------------//
if(WorkFlag&bPause) break;
if(WorkFlag&bDatRdy){
do{
if(PINB&MP3_DATA_REQ) {
for(n=0;n<32;n++) { //
vs1003_data_write(BUFFER[data_pointer++]);
}
if(filelength<32) {
WorkFlag|=(bPlayOvr|bReadOvr);
break;
}
filelength-=32;
}else
break;
}while(data_pointer<511);
if(data_pointer>=511) {
data_pointer=0;
WorkFlag&=(~bDatRdy);
continue;
}
}
break;
}
}
//
BOOL ReadFileData(void)
{
unsigned long LBA;
if(!(WorkFlag&bDatRdy)){
if(SectorIndex>=SectorsPerCluster){
NextCluster = fatNextCluster(NextCluster);
if(NextCluster==CLUST_EOFE) return FALSE;
SectorIndex=0;
}
LBA =fatClustToSect(NextCluster);
ReadBlock(LBA+SectorIndex);
SectorIndex++;
WorkFlag|=bDatRdy;
}
return TRUE;
}
void StopPlay()
{
vs1003_Reset();
WorkFlag|=(bPause|bPlayOvr); //停止放音
WorkFlag&=~(bLrc|bDatRdy);
data_pointer=SectorIndex=0;
}
void StartPlay(unsigned long FirstClust)
{
NextCluster=FirstClust;
WorkFlag&=~(bReadOvr|bDatRdy|bPlayOvr|bPause);
data_pointer=SectorIndex=0;
}
void RtcCount()
{
if(TimeFlag&bT1S){
TimeFlag&=~bT1S;
TimeFlag|=bRtcUpdate;
if(++rtc.sec>=60){
rtc.sec=0;
if(++rtc.min>=60){
rtc.min=0;
if(++rtc.hour>=24){
rtc.hour=0;
if(++rtc.day>GetDay(rtc.month)){
rtc.day=1;
if(++rtc.month>12){
rtc.month=1;
rtc.year++;
}
}
}
}
}
}
}
const unsigned char DayTable[] PROGMEM ={31,28,31,30,31,30,31,31,30,31,30,31};
unsigned char GetDay(unsigned char mo)
{
return pgm_read_byte(&DayTable[mo]);
}
void InitSystem()
{
key_port();
/* ASSR=0X08 ;
TCCR0=0X05; //128分频 计数模式
TCCR2=0X05; //1/1024
TIFR|=(_BV(TOV0))|(_BV(TOV2));
TIMSK|=_BV(TOIE0)|_BV(TOIE2);
SFIOR&=~_BV(TSM);
sei();*/
spi_init();
LCD_Init();
LCD_clear();
mp3_port_init();
sd_port_init();
vs1003_init();
SD_Init();
SPCR = 0x50;
SPSR = 0x01; //setup SPI
LCD_draw_map(0,2,AVR_bmp,40,24); // 显示“AVR”位图
LCD_draw_map(44,2,china_bmp,36,15); // 显示”实验室“位图
fatInit(); //初始化FAT文件系统
rtc.year=2006;
rtc.month=rtc.day=1;
rtc.hour=rtc.min=rtc.sec=0;
StopPlay();
}
//查询SD卡文件系统信息
/*
void DispSdInfo(void)
{
unsigned int data;
unsigned char t1,t2;
switch (FatType)
{
case FAT12:
LCD_write_String(0,0,"FAT 12");
break;
case FAT32:
LCD_write_String(0,0,"FAT 32");
break;
case FAT16:
LCD_write_String(0,0,"FAT 16");
break;
default:
LCD_write_String(0,0,"No Partition!");
break;
}
//显示磁盘容量
data=PartInfo.prSize>>11;
LCD_set_XY(56,0);
t1=data/100;
LCD_write_char(t1+48);
data=data%100;
t1=data/10;
LCD_write_char(t1+48);
t2=data%10;
LCD_write_char(t2+48);
LCD_write_String(0,76,"M");
LCD_write_String(1,0,"RATE");
}
*/
void SaveHzk12Sector(unsigned long StartCluser)
{ //0x000-0x17c
void *eep=0;
unsigned long temp,temp1;
do{
eeprom_busy_wait();
eeprom_read_block(&temp,(void *)eep,4);
temp1=fatClustToSect(StartCluser);
if(temp!=temp1){
eeprom_write_block(&temp1,(void*)eep,4);
}
eep+=4;
}while((StartCluser=fatNextCluster(StartCluser))!=CLUST_EOFE);
eeprom_busy_wait();
}
void SaveUniCodeSector(unsigned long StartCluser)
{
void *eep=(void*)0x200;
unsigned long temp,temp1;
do{
eeprom_busy_wait();
eeprom_read_block(&temp,(void *)eep,4);
temp1=fatClustToSect(StartCluser);
if(temp!=temp1){
eeprom_write_block(&temp1,(void*)eep,4);
}
eep+=4;
}while((StartCluser=fatNextCluster(StartCluser))!=CLUST_EOFE);
eeprom_busy_wait();
}
unsigned char GetChar(unsigned char *buf)
{
unsigned long address;
if(lyric.filelen>0) lyric.filelen--;
if(lyric.so!=64){
return buf[lyric.so++];
}else{
if(++lyric.wl>=8){
lyric.wl=0;
if(++lyric.sl>=SectorsPerCluster){
lyric.sl=0;
lyric.Clust=fatNextCluster(lyric.Clust);
if(lyric.Clust==CLUST_EOFE) return 0xff; //文件结束
}
}
address=(unsigned long )(fatClustToSect(lyric.Clust)+lyric.sl)*512+(unsigned long) lyric.wl*64;;
ReadSD64Byte(address,buf); //读取64个字节
lyric.so=0;
return buf[lyric.so++];
}
}
//取第二行内容的首指针
unsigned char *GetSecondLine(unsigned char *pb)
{
unsigned char i;
unsigned char bHz=0;
unsigned char line=0;
for(i=0;i<29;i++){
if(pb[i]=='\0') return (pb+i);
if(!bHz){
if(pb[i]>0x80){
bHz=1;
if(line>(84-12)) //无法显示完一个完整的字符
return pb+i;
line+=12;
}else{
if(line>(84-6)) return (pb+i);
line+=6;
}
}else{
bHz=0;
}
}
return (pb+i);
}
//-------------------------------------------
//读取一句有效的歌词记录
void ReadLrcFileData(void)
{
unsigned char lbuf[64];
unsigned char c;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -