📄 main.c
字号:
#include <avr/io.h> // 器飘, 器飘巧 殿捞 急攫登绢 乐澜,
#include <avr/pgmspace.h>
#include <stdio.h>
#include "global.h" // U8, u16 殿捞 急攫登绢 乐澜, 庆歹 颇老阑 流立 父电 版快 奴 蝶咳钎("")肺 弓绢淋
#include "delay.h"
#include "usart.h" // 流纺烹脚 (MCU <-> PC)
#include "spi.h" // SPI 烹脚 (MCU <-> SD Card, MCU <-> vs1003)
#include "timer.h"
// SD Card
#include "sd/sd.h"
// FAT
#include "fat/fat.h"
#include "fat/filelist.h"
// VS1003
#include "vs1003b/vs1003.h"
// 弊贰侨 LCD
#include "glcd/glcd.h"
#include "glcd/ks0108.h"
#include "glcd/icondef.h"
// 荤侩磊 Key
#include "key/key.h"
// Play Mode Status
#define PM_STOP 0
#define PM_PLAY 1
#define PM_PAUSE 2
void printLogo(void);
void IoInit(void);
void printSlider(U8 pos);
void MP3Play(struct tagFileInfo fileInfo);
// global variables
extern U8 SecPerClus; // 茄 Cluster寸 sector 荐(Sector per Cluster)
extern U32 FirstDataSector; // 霉锅掳 单捞磐 冀磐(焊烹 风飘叼泛配府 浚飘府狼 困摹烙)
extern U32 StartFATSector; // FAT 矫累 冀磐
extern U32 RootCluster; // Root Directory狼 努矾胶磐 锅龋(老馆利栏肺 2)
extern struct tagFATBuffer FATBuffer; // FAT Buffer(1冀磐甫 佬绢坷扁 困茄 滚欺)
extern struct tagDirEntryBuffer DirEntryBuffer; // 叼泛磐府 浚飘府 Buffer
extern U8 bTimerUpdateName;
extern U8 bTimerKeyLock;
extern U8 bTimerClearVol;
// Mp3 Setting
U8 Mp3Volume=200;
int main(void)
{
U8 i=0;
struct tagFileInfo FileInfo;
// 鸥捞赣客 矫府倔 烹脚阑 鞍捞 劝己拳 矫虐搁 AVR捞 府悸 登绰 泅惑捞 惯积凳
// 弊犯霸 锭巩俊 叼滚弊矫父 劝己拳 窍辨 官恩
// 叼滚弊矫父 : 矫府倔 烹脚 劝己拳, 鸥捞赣 厚劝己拳
// Init_USART(); // 流纺烹脚 檬扁拳
SD_Init(); // SD墨靛 檬扁拳
glcdInit(); // 弊贰侨 LCD 檬扁拳
fatInit(); // FAT 檬扁拳
VS1003_Init(); // VS1003 檬扁拳
Timer_Init();
IoInit();
// printLogo();
fatGetDirEntry(RootCluster);
while(1)
{
if (i < DirEntryBuffer.index)
{
FileInfo=fatGetFileInfo(DirEntryBuffer.cluster[i], DirEntryBuffer.entry[i]);
glcdClearScreen();
// glcdSetAddress(0, 3);
// glcdPutString(FileInfo.fileName, NORMAL);
MP3Play(FileInfo);
i++;
}
else
i=0;
}
// fileListBrowse();
// loadConfig();
// fileListBrowse();
return 0;
} // end main
void IoInit(void)
{
// I/O Port Direction Setting
Key_DDR = 0x00; // Input Key
cbi(VS1003_DDR, VS1003_DREQ); // Input Vs1003 DREQ Pin
sbi(LED_DDR, LED_RUN); // LED Output
sbi(LED_PORT, LED_RUN); // LED OFF
}
void printLogo(void)
{
U8 i;
glcdClearScreen();
glcdSetAddress(0, 0);
glcdPutString(" Ggongchi MP3P ", NORMAL);
glcdGotoChar(LINE4, 2);
glcdPutStr(" Firmware v0.1 ");
glcdGotoChar(LINE6, 2);
glcdPutStr("Made by Ggongchi");
glcdRectangle(0, 60, 128, 63);
for(i=0; i < 128; i++)
{
glcdLine(i, 60, i, 63);
delay_ms(25);
}
}
void printSlider(U8 pos) // pos: 0~100
{
U8 i;
U8 offset = pos * 0.6;
if(pos <= 100)
{
glcdSetAddress(61, LINE8);
glcdDataWrite(0x38); // 阜措 哭率
for(i=0; i<offset; i++)
glcdDataWrite(0x38); // 阜措 吝埃(盲框)
glcdDataWrite(0xFE); // 器牢磐 哭率
glcdDataWrite(0x82); // 器牢磐 吝埃
glcdDataWrite(0xFE); // 器牢磐 吝埃
glcdDataWrite(0x82); // 器牢磐 吝埃
glcdDataWrite(0xFE); // 器牢磐 坷弗率
for(i=60-offset; i>0; i--)
glcdDataWrite(0x28); // 阜措 吝埃(厚框)
glcdDataWrite(0x38); // 阜措 坷弗率
}
}
void MP3Play(struct tagFileInfo fileInfo)
{
struct VS1003_Mp3Info mp3_info;
U8 test[30]={0,};
U8 pos;
U8 buffer[SECTOR_SIZE];
U32 index;
U32 sector;
U8 nextSector;
U8 playMode;
U8 icon_flag = 1; // sample rate客 bit rate甫 贸澜 茄锅父 免仿登霸 ...
U32 curCluster, nextCluster;
U32 byteCount;
U16 decode_time=0; // VS1003栏肺何磐 犁积矫埃 钎矫(檬)
struct tagTime time;
float volume;
U8 icon, icon1;
U8 name[MAX_NAME_LEN];
U8* fileName_ptr = fileInfo.fileName;
U8 offset;
// init variables
playMode = PM_PLAY;
index = 512;
byteCount = 0; // 颇老阑 佬篮 官捞飘 荐
nextSector = SecPerClus; // 8 (1GB SD墨靛绰 努矾胶磐寸 8冀磐)
curCluster = fileInfo.startCluster; // MP3颇老狼 矫累 努矾胶磐
sector = fatClusToSec(curCluster); // 矫累 努矾胶飘肺 颇老狼 矫累 冀磐甫 备窃
bTimerUpdateName = 1; // 矫累锭 颇老疙捞 焊咯瘤档废
bTimerKeyLock = 0; // 虐 泪陛阑 秦力
bTimerClearVol = 0; // 杭俘 钎矫甫 瘤快瘤 臼澜
VS1003_Write_SCI_Data(VS1003_DCTIME, 0x0000); // Initialize Decode Time
// init FAT buffer
fatBufferInit(curCluster);
// PLAY 酒捞能 钎矫
glcdSetAddress(0, 0);
glcdWriteIcon16(ICON_PLAY);
/*
if(Config.fadeIn)
volume = MUTE_VOLUME;
else
volume = Config.mp3Volume;
*/
/*
sta013SetVolume(volume, Config.mp3Balance);
sta013SetTone(Config.bassEnh, Config.bassFreq, Config.trebleEnh, Config.trebleFreq);
sta013ResumeDecoder();
timerReset(TIMER_SEC); // 鸥捞赣 reset
timerReset(TIMER_MS);
timerEnable(TIMER_SEC); // 鸥捞赣 enable
timerEnable(TIMER_MS);
*/
while(playMode)
{
// Blink_LED();
while(VS1003_DREQ_PIN)
{
if(index == 512) // 茄冀磐甫 促 佬菌栏搁 促澜 冀磐甫 佬澜
{
SD_Read_Sector(sector++, buffer); // SD墨靛甫 佬瘤 给窍搁
index = 0;
nextSector--;
}
if(nextSector == 0 && index == 256) // 付瘤阜 256官捞飘啊 巢栏搁, 促澜 努矾胶磐甫 霖厚窃
{
if((nextCluster = fatGetNextCluster(curCluster)) == 0xFFFFFFFF) // 颇老狼 场捞搁
{
playMode = PM_STOP; // 犁积 辆丰
break;
}
curCluster = nextCluster;
sector = fatClusToSec(curCluster); // 努矾胶磐 林家甫 角力 冀磐 林家肺 函券
nextSector = SecPerClus;
}
VS1003_XDCS_LOW(); // xDCS = low, vs1003 劝己拳
SPI_Transfer_Byte(buffer[index++]); // vs1003 抹栏肺 MP3 单捞磐 傈价 (1官捞飘)
VS1003_XDCS_HIGH(); // xDCS = high, vs1003 厚劝己拳
byteCount++;
}
/*
// 鸥捞赣甫 捞侩窍档废 荐沥且 巴
// Fade-In effect (杭俘阑 辑辑洒 棵覆)
if(Config.fadeIn && volume <= Config.mp3Volume)
{
volume += 0.4;
sta013SetVolume(volume, Config.mp3Balance);
}
// 杭俘钎矫甫 瘤框 (杭俘虐甫 喘范阑 锭 鸥捞赣俊 狼秦 2檬饶 杭俘钎矫甫 瘤框)
if(bTimerClearVol)
{
glcdSetAddress(80, LINE7);
glcdPutStr(" ");
bTimerClearVol = 0;
}
// 犁积矫埃钎矫
time = timerGetTime();
glcdGotoXY(2, 0);
glcdPutU32Dec16(time.min, 2, NORMAL);
glcdPutEngChar(':', NORMAL);
glcdPutU32Dec16(time.sec, 2, NORMAL);
*/
// 颇老疙 钎矫 (鸥捞赣俊 狼秦 4檬埃拜栏肺 颇老疙 诀单捞飘)
if(bTimerUpdateName)
{
offset = strNcopy(name, fileName_ptr, 16); // 茄临俊 康巩 16磊鳖瘤 钎矫啊瓷
if(offset > 0)
{
glcdSetAddress(0, 2);
glcdPutString(name, NORMAL);
fileName_ptr += offset;
bTimerUpdateName = 0;
}
else
fileName_ptr = fileInfo.fileName;
}
// 犁积 困摹 钎矫
pos = byteCount / (fileInfo.size / 100);
printSlider(pos);
VS1003_Get_Mp3info(&mp3_info);
/*
sprintf(test, "\nID : %d", mp3_info.mp3_ID);
string(test);
sprintf(test, "\nSample Rate : %d", mp3_info.sample_rate);
string(test);
sprintf(test, "\nBit Rate : %d", mp3_info.bit_rate);
string(test);
*/
icon = ICON_STEREO;
glcdSetAddress(0, LINE7);
glcdWriteIcon16(icon);
if (icon_flag == 1)
{
if (mp3_info.mp3_ID == 0 || mp3_info.mp3_ID == 1)
{
switch(mp3_info.sample_rate)
{
default:
case 0: icon = ICON_11KHZ; break;
case 1: icon = ICON_12KHZ; break;
case 2: icon = ICON_08KHZ; break;
}
}
else if (mp3_info.mp3_ID == 2)
{
switch(mp3_info.sample_rate)
{
default:
case 0: icon = ICON_22KHZ; break;
case 1: icon = ICON_24KHZ; break;
case 2: icon = ICON_16KHZ; break;
}
}
else if (mp3_info.mp3_ID == 3)
{
switch(mp3_info.sample_rate)
{
default:
case 0: icon = ICON_44KHZ; break;
case 1: icon = ICON_48KHZ; break;
case 2: icon = ICON_32KHZ; break;
}
switch(mp3_info.bit_rate)
{
default:
case 2: icon1 = ICON_040KBPS; break;
case 3: icon1 = ICON_048KBPS; break;
case 4: icon1 = ICON_056KBPS; break;
case 5: icon1 = ICON_064KBPS; break;
case 6: icon1 = ICON_080KBPS; break;
case 7: icon1 = ICON_096KBPS; break;
case 8: icon1 = ICON_112KBPS; break;
case 9: icon1 = ICON_128KBPS; break;
case 10: icon1 = ICON_160KBPS; break;
case 11: icon1 = ICON_192KBPS; break;
case 12: icon1 = ICON_224KBPS; break;
case 13: icon1 = ICON_256KBPS; break;
case 14: icon1 = ICON_320KBPS; break;
}
}
else if (mp3_info.mp3_ID == 0 || mp3_info.mp3_ID == 1 || mp3_info.mp3_ID == 2)
{
switch(mp3_info.bit_rate)
{
default:
case 1: icon1 = ICON_008KBPS; break;
case 2: icon1 = ICON_016KBPS; break;
case 3: icon1 = ICON_024KBPS; break;
case 5: icon1 = ICON_040KBPS; break;
case 6: icon1 = ICON_048KBPS; break;
case 7: icon1 = ICON_056KBPS; break;
case 8: icon1 = ICON_064KBPS; break;
case 9: icon1 = ICON_080KBPS; break;
case 10: icon1 = ICON_096KBPS; break;
case 11: icon1 = ICON_112KBPS; break;
case 12: icon1 = ICON_128KBPS; break;
case 13: icon1 = ICON_144KBPS; break;
case 14: icon1 = ICON_160KBPS; break;
}
}
icon_flag = 0;
glcdSetAddress(18, LINE7); // sample rate
glcdWriteIcon16(icon);
glcdSetAddress(36, LINE7); // bit rate
glcdWriteIcon24(icon1);
}
decode_time=VS1003_Get_DecodeTime();
glcdSetAddress(70, LINE6);
sprintf(test, "%d : %d ", (decode_time)/60, decode_time%60);
glcdPutString(test, NORMAL);
//glcdPutU32Dec((U32) decode_time, 4);
/*
// 虐 涝仿 贸府
switch(KEY_INPUT())
{
case KEY_PLAY:
if(!bTimerKeyLock) // 虐啊 泪扁瘤 臼疽栏搁
{
if(playMode == PM_PLAY) // 犁积 -> 老矫沥瘤
{
sta013PauseDecoder();
playMode = PM_PAUSE;
glcdGotoXY(0, 0);
glcdWriteIcon16(ICON_PAUSE);
timerDisable(TIMER_SEC); // 鸥捞赣 老矫沥瘤
}
else if(playMode == PM_PAUSE) // 老矫沥瘤 -> 犁积
{
sta013ResumeDecoder();
playMode = PM_PLAY;
glcdGotoXY(0, 0);
glcdWriteIcon16(ICON_PLAY);
timerEnable(TIMER_SEC); // 鸥捞赣 犁俺
}
timerReset(TIMER_MS);
bTimerKeyLock = 1; // debounce 规瘤甫 困秦 虐甫 泪陛
}
break;
case KEY_FF:
if(!bTimerKeyLock) // 虐啊 泪扁瘤 臼疽栏搁
{
// 沤祸 风凭 眠啊且 巴
timerReset(TIMER_MS);
bTimerKeyLock = 1; // debounce 规瘤甫 困秦 虐甫 泪陛
}
break;
case KEY_REW:
if(!bTimerKeyLock) // 虐啊 泪扁瘤 臼疽栏搁
{
// 沤祸 风凭 眠啊且 巴
timerReset(TIMER_MS);
bTimerKeyLock = 1; // debounce 规瘤甫 困秦 虐甫 泪陛
}
break;
case KEY_VOL_UP:
if(!bTimerKeyLock) // 虐啊 泪扁瘤 臼疽栏搁
{
if(Config.mp3Volume < MAX_VOLUME_ATTENUATION)
{
Config.mp3Volume += 2;
sta013SetVolume(Config.mp3Volume, Config.mp3Balance);
}
// 杭俘 沥焊 钎矫
glcdSetAddress(80, LINE7);
glcdPutStr("VOL");
glcdSetAddress(100, LINE7);
glcdPutU32Dec(Config.mp3Volume, 2);
timerReset(TIMER_MS);
bTimerKeyLock = 1; // debounce 规瘤甫 困秦 虐甫 泪陛
}
break;
case KEY_VOL_DN:
if(!bTimerKeyLock) // 虐啊 泪扁瘤 臼疽栏搁
{
if(Config.mp3Volume > MIN_VOLUME_ATTENUATION)
{
Config.mp3Volume -= 2;
sta013SetVolume(Config.mp3Volume, Config.mp3Balance);
}
// 杭俘 沥焊 钎矫
glcdSetAddress(80, LINE7);
glcdPutStr("VOL");
glcdSetAddress(100, LINE7);
glcdPutU32Dec(Config.mp3Volume, 2);
timerReset(TIMER_MS);
bTimerKeyLock = 1; // debounce 规瘤甫 困秦 虐甫 泪陛
}
break;
case KEY_ENTER:
sta013SetVolume(MUTE_VOLUME, Config.mp3Balance);
// pause饶俊 stop窍搁 咯傈洒 棱澜 乐澜, 秦搬且 巴
index = 5 * 1024; // 割锅 角氰栏肺 措面 嘛绢辰 蔼烙
while(index--) // 滚欺甫 厚快扁 困秦 dummy 单捞磐甫 焊晨
MP3sendByte(0xFF);
playMode = PM_STOP;
break;
case KEY_FUNC:
break;
default:
break;
}
*/
}
// Pause 饶俊 辆丰窍搁, 棱澜 积扁绰 巩力 秦搬且 巴
// 犁积捞 辆丰 灯栏搁
/*
sta013PauseDecoder();
printf("End play\n\n");
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -