|
本帖最后由 hongniu 于 2015-6-23 16:50 編輯
MP3在之前對(duì)我來說是一個(gè)很深?yuàn)W,很高級(jí)的東西!感性的認(rèn)識(shí)就是前年買的那個(gè)MP3。說起MP3不得不說LCD12864,他起得頭,自從做完12864顯示后,我目標(biāo)瞄向了彩屏!黑白屏有啥意思!彩色的才好來!于是又做TFT9325彩屏!在做彩屏之前做了一件非常非常重要的事!因?yàn)椴势敛煌?2864,12864顯示一整屏才要1024個(gè)字節(jié),而彩屏2.4寸則要他的150倍!這么大的數(shù)據(jù)量你放哪?是個(gè)問題吧!這個(gè)東西必須要常見,必須要小,必須要容量大!他是什么呢?--沒錯(cuò),就是日常生活中的手機(jī)里的那張所謂的內(nèi)存卡(人家叫TF卡)!第一他常見,第二他小,第三容量大,基本上是1個(gè)G的!那個(gè)卡只有指甲蓋大!很方便,所有條件滿足!就是他了!開始看關(guān)于TF卡的資料,首先是文件系統(tǒng)!實(shí)話當(dāng)時(shí)我頭都大了!啥叫文件系統(tǒng)?什么原理?存儲(chǔ)機(jī)制是什么?有哪些操作?答案沒有現(xiàn)成的!但是資料告訴我們只要堅(jiān)持一定會(huì)找到!慢慢的磨啊磨。¢_始知道我要學(xué)的文件系統(tǒng)沒名字叫FAT32文件系統(tǒng)!開始了解內(nèi)部邏輯扇區(qū)和MBR,BPB,根目錄,F(xiàn)AT表,數(shù)據(jù)鏈,簇,扇區(qū),通信機(jī)制,數(shù)據(jù)讀寫,命令/指令,可是光有這些還是不行,要試驗(yàn),要調(diào)試,失敗,失敗,失敗,連著一個(gè)星期的失敗換來了成功,知道有一天,我記得特別清楚我從TF卡中讀到了55AA,那代表了扇區(qū)的結(jié)束標(biāo)志,可是期待的EB(邏輯0扇區(qū)標(biāo)志)沒有出現(xiàn),又一次失落了,懷疑,我讀錯(cuò)了?還是......。不懂了,第二天我做了個(gè)通信,把數(shù)據(jù)一次性的送往計(jì)算機(jī),到數(shù)據(jù)送出的那一刻,我激動(dòng)了,我明白了,原來我讀出的并不是邏輯0扇區(qū),而是物理0扇區(qū),以前的思想多磨可笑。≡俅位A(chǔ)上我成功的讀出邏輯0扇區(qū)!跟實(shí)際的一摸一樣,這意味這我可以對(duì)TF卡的在地址范圍內(nèi)的任意一個(gè)地址扇區(qū)進(jìn)行讀!TF卡的底層已經(jīng)對(duì)我打開了!這時(shí)我放下TF卡,專攻彩屏液晶顯示器!又是失敗,失敗,失敗,失敗,兩個(gè)星期后我終于可以在彩屏的任意點(diǎn)顯示任意顏色!接下來是把TF卡和液晶連起來!把JPG的320240的圖像轉(zhuǎn)換成BMP的16位圖像,轉(zhuǎn)成BIN,存到TF卡中,找到數(shù)據(jù)地址,吧數(shù)據(jù)地址送到液晶,液晶取出數(shù)據(jù)以掃描方式顯示在屏幕上!讀完正好掃描完成!正好是一幅完整的圖像!當(dāng)然速度是很慢的!因?yàn)镃PU實(shí)在是不敢恭維啊!但是他做到了!接下來搞啥呢?-----MP3!數(shù)據(jù)的存儲(chǔ)還用TF卡,就憑我的程序水平肯定編不出MP3解碼算法的,所以我決定使用專用的DSP解碼器,那我要做的是把數(shù)據(jù)給他!然后讓他解碼!DA后在耳機(jī)里聽到音樂!思路是有了!寫程序,修改,實(shí)驗(yàn),失敗,我目標(biāo)很明確,任何器件都一樣,首先保證硬件是正確的,下一步是底層的驅(qū)動(dòng)是成功的!因?yàn)榻獯a器用的通信使SPI,很容易實(shí)現(xiàn),一下午的功夫,搞定了!然后把數(shù)據(jù)送往MP3解碼器,此時(shí)在耳機(jī)里聽到悅耳的音樂!我真的很高興!因?yàn)檫@是有史以從未搞過的!接下來的幾天我開始遇到麻煩了!播放老是得我去計(jì)算歌曲的地址,然后告訴他,太麻煩,離顯示的MP3還太遙遠(yuǎn),于是開始著手改進(jìn),當(dāng)我開始的時(shí)候問題來了,MP3的碼率不夠,導(dǎo)致有的比特流高的歌曲不能播放!又改程序,簡化代碼,提高速度,這里說一點(diǎn),指針我頭一次用,效率果然不同一般!賊快!碼率解決了,怎樣讓他自己自動(dòng)的找歌!而不用我人為地計(jì)算呢?-----呵呵-----文件系統(tǒng)!---我把我找個(gè)歌曲文件的方法換成代碼,就是了!程序一運(yùn)行,感覺一切正常,自動(dòng)找到歌曲并播放,問題又來了,放著放著亂了,本來是1的卻播到2去了!又開始找了一天的原因,第二天才知道原來少了一個(gè)變量,哎!曲折啊!又來問題了,我明明在電腦上已經(jīng)刪除的文件他還在播!后來WNHEX才知道原來電腦刪除文件時(shí)在根目錄里吧文件名的第一個(gè)字節(jié)改成E5,哎呀,有是一頓修改,調(diào)試,終于昨天上午全部搞定!現(xiàn)在是一個(gè)通過手機(jī)TF卡或SD卡存儲(chǔ)4G文件為文件內(nèi)存的,具FAT32文件系統(tǒng)、自動(dòng)識(shí)別MP3文件、自動(dòng)掃描歌曲目錄、自動(dòng)順序播放、自動(dòng)添加MP3文件的準(zhǔn)MP3音樂播放器了。!當(dāng)然離市面的MP3還差點(diǎn),但是剩下的工作就是對(duì)系統(tǒng)的擴(kuò)展了!什么音量調(diào)整了,進(jìn)度條了,頻譜了,人機(jī)界面了!都可以在此基礎(chǔ)上做了!!
于天津開發(fā)區(qū)第四項(xiàng)目部。
源程序:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar some;
- unsigned long k=4323840;//定義根目錄地址,當(dāng)然我知道;
- uchar xdata tab[512];
- //******************
- sbit p1_7=P1^7;
- sbit CS=P2^0; //片選信號(hào)(低電平有效)
- sbit DATEIN =P2^1;//主-從數(shù)據(jù)輸入
- sbit SCLK=P2^2;//時(shí)鐘信號(hào)
- sbit DATEOUT=P2^3;//從-主數(shù)據(jù)輸出
- unsigned char bdata dat;
- sbit dat_0=dat^0;
- sbit dat_1=dat^1;
- sbit dat_2=dat^2;
- sbit dat_3=dat^3;
- sbit dat_4=dat^4;
- sbit dat_5=dat^5;
- sbit dat_6=dat^6;
- sbit dat_7=dat^7;
- bit is_init;//決定是否延時(shí);
- uchar lpp;
- unsigned char fhz;//返回值
- uchar fhz_buff; //讀返回值中間量
- //unsigned char xdata tab[512];
- ///*******************以上是SD卡
- /*
- VS1003mp3模塊的接口定義
- */
- sbit XRST=P1^0;//復(fù)位
- sbit DREQ=P1^1; //數(shù)據(jù)請(qǐng)求
- sbit XDCS=P1^2; //數(shù)據(jù)片選
- sbit XCS=P1^3; //命令片選
- /*
- /* VS1003mp3SPI通信接口定義
- */
- sbit SCK=P1^4; //時(shí)鐘
- sbit SI=P1^5; //串行輸入
- sbit SO=P1^6; //串行輸出
- //*******************************
- void delay(uint time)
- { while(time)
- time--;
- }
- //***************************
- unsigned char bdata datmp3;
- sbit datmp3_0=datmp3^0;
- sbit datmp3_1=datmp3^1;
- sbit datmp3_2=datmp3^2;
- sbit datmp3_3=datmp3^3;
- sbit datmp3_4=datmp3^4;
- sbit datmp3_5=datmp3^5;
- sbit datmp3_6=datmp3^6;
- sbit datmp3_7=datmp3^7;
-
- ///*************************************以下是MP3模塊的程序
- void delay1ms(uint j)//延時(shí)100us
- {unsigned char i;
- for(i=j;i;i--)
- {
- }
- }
- void spi_write_mp3_1(uchar h)//SPI寫入一個(gè)字節(jié),這里是最底層的數(shù)據(jù)發(fā)送!
- {
- datmp3=h;
-
- SI=datmp3_7;
- //為了進(jìn)一步提高速度我這里采用了順序結(jié)構(gòu)!全是斷橋殘雪惹的禍!第一次愛的人播放正常!而斷橋殘雪不行了!一定盡全力
- SCK=0; //從SD讀取和MP3寫數(shù)據(jù)流下手
- SCK=1;
-
- SI=datmp3_6;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_5;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_4;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_3;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_2;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_1;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_0;
-
- SCK=0;
- SCK=1;
-
-
-
-
-
-
-
- }
-
- /*uchar spi_read_mp3()// SPI讀取一個(gè)字節(jié)
- {
- uchar i,read;
- for(i=8;i;i--)
- {
- SCLK=1;
- delay();
- SCLK=0;
- delay();
- read=SO&0x80;
- read=(read<<1);
- }
- SCLK=1;
- return (read);
- }
- */
- void write_comd_mp3(uchar add,uint date)//寫入控制命令add地址date是數(shù)據(jù)注意這里是16位的數(shù)據(jù),內(nèi)部做分開了處理
- {
- uchar h,l;
- l=date;
- h=(date>>8);
- DREQ=1;
- while(!DREQ); //檢測(cè)MP3模塊的忙狀態(tài)
- XCS=0;
- spi_write_mp3_1(2); //表示寫操作
- spi_write_mp3_1(add);
- spi_write_mp3_1(h); //先寫高8位
- spi_write_mp3_1(l);
- XCS=1;
-
- }
- void write_date_mp3(uchar dat)//寫入音頻數(shù)據(jù)信息這里還有一點(diǎn)是XDCS在此函數(shù)外拉低
- {
- DREQ=1;
- while(!DREQ);
- datmp3=dat;
- SI=datmp3_7;
- //為了進(jìn)一步提高速度我這里采用了順序結(jié)構(gòu)!全是斷橋殘雪惹的禍!第一次愛的人播放正常!而斷橋殘雪不行了!一定盡全力
- SCK=0; //從SD讀取和MP3寫數(shù)據(jù)流下手
- SCK=1;
-
- SI=datmp3_6;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_5;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_4;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_3;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_2;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_1;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_0;
-
- SCK=0;
- SCK=1;
-
-
-
-
-
-
-
- }
- void init_mp3() //初始化vs1003
- {
- XRST=1;
- delay1ms(100);
- XRST=0;
- delay1ms(100);
- XRST=1;
- delay1ms(100);
- write_comd_mp3(0x00,0x0804);//模式設(shè)置
- write_comd_mp3(0x03,0x9800);//時(shí)鐘控制
- write_comd_mp3(0x0b,15000);//聲音音量控制 00是最大的。。。!這里也是十六位的!
- XDCS=0;//數(shù)據(jù)片選
- spi_write_mp3_1(0);
- spi_write_mp3_1(0);
- spi_write_mp3_1(0);
- spi_write_mp3_1(0);
- XDCS=1;
- }
- void sing(uchar fhz)//正選測(cè)試
- {
-
-
- write_comd_mp3(0x00,0x0820);
- DREQ=1;
- while(!DREQ);
- XDCS=0;
- write_date_mp3(0x53);
- write_date_mp3(0xef);
- write_date_mp3(0x6e);//正選測(cè)試開啟
- write_date_mp3(fhz); //頻率選擇
- write_date_mp3(0);
- write_date_mp3(0);
- write_date_mp3(0);
- write_date_mp3(0);
- delay1ms(60000);
- write_date_mp3(0x45); //正選關(guān)段
- write_date_mp3(0x78);
- write_date_mp3(0x69);
- write_date_mp3(0x74);
- write_date_mp3(0);
- write_date_mp3(0);
- write_date_mp3(0);
- write_date_mp3(0);
- XDCS=1;
-
-
-
-
-
- }
- //以上是MP3程序
- //*//**********************************************
-
- /*讀sd卡子程序,無返回值,有參函數(shù),參數(shù)為要寫入DATEIN數(shù)據(jù)線的字節(jié)*/
- void write(unsigned char wr_)// 寫入一個(gè)字節(jié)SD卡
- {
- dat=wr_;
- DATEIN=dat_7;
-
- SCLK=0;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
-
- DATEIN=dat_6;
-
- SCLK=0;
- //if(!is_init)delay(1);
- if(is_init)delay(200);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
- DATEIN=dat_5;
-
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- //if(!is_init)delay(1);
- DATEIN=dat_4;
-
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
- DATEIN=dat_3;
-
- SCLK=0;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
- DATEIN=dat_2;
-
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
- DATEIN=dat_1;
-
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- // if(!is_init)delay(1);
- DATEIN=dat_0;
-
- SCLK=0;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- SCLK=1;
- if(is_init) delay(200);
- //if(!is_init)delay(1);
- }
- unsigned char read()// 讀取一個(gè)字節(jié)SD卡
- {
- DATEOUT=1;
- SCLK=1;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- dat_7=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- //if(!is_init)delay(1);
- dat_6=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_5=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_4=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_3=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_2=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_1=DATEOUT;
- SCLK=1;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- SCLK=0;
- if(is_init)delay(200);
- // if(!is_init)delay(1);
- dat_0=DATEOUT;
- return (dat);
- }
- //****************************
- void write1(unsigned char wr_)// 寫入一個(gè)字節(jié)SD卡
- {
- dat=wr_;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1;
-
-
- }
- unsigned char read1()// 讀取一個(gè)字節(jié)SD卡
- {
- DATEOUT=1;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
- //if(!is_init)delay(1);
- dat_7=DATEOUT;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
-
- //if(!is_init)delay(1);
- dat_6=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_5=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_4=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_3=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_2=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_1=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_0=DATEOUT;
- return (dat);
- }
- //******************************8
- void restsd()//復(fù)位SD卡
- { uchar i;
- uchar pcmd[6]={0x40,0x00,0x00,0x00,0x00,0x95};
- is_init=1;
-
- CS=1;
- for(i=0;i<15;i++)
- {
- //120時(shí)鐘
- write(0xff);
- }
-
-
- CS=1;
- write(0xff);//據(jù)說是提高兼容性
- CS=0;//片選開
- write( pcmd[0]);
- write( pcmd[1]);
- write( pcmd[2]);
- write( pcmd[3]);
- write( pcmd[4]);
- write( pcmd[5]);
- fhz=read();
- for(;;)
- {
- fhz=read();
- if(fhz==0x01)break;
-
-
- }
-
- CS=1;
- write(0xff);
- }
-
- void initsd()//初始化SD
- {
- //
- uchar pcmd[6]={0x41,0x00,0x00,0x00,0x00,0xff};//
- //
-
- CS=1;
- write(0xff);//據(jù)說是提高兼容性
- CS=0;//片選開
- write( pcmd[0]);
- write( pcmd[1]);
- write( pcmd[2]);
- write( pcmd[3]);
- write( pcmd[4]);
- write( pcmd[5]);
-
-
- fhz=read();
- for(;;)
- {
- fhz=read();
- if(fhz==0x00)break;
-
-
- }
-
- CS=1;
- write(0xff);
-
-
-
- }
- void readsd(unsigned long addstart)//讀SD卡物理一扇區(qū)的值送TAB表中
-
- {
- uint k,n;
- uchar zh1,zh2,zh3,zh4;
- uchar *p;
-
-
- p=&addstart; //取出存放Numb的地址的最高位!詳細(xì)請(qǐng)看匯編!
- zh1=*p; //這里必須要寫!要不然就會(huì)出現(xiàn)播放開始正常,播到一定程度就亂了!因?yàn)樗灰欢ㄎ?0!就是。≌垓v我一天了。!201012月31日搞定!
- p++; //由于最高位不用所以這里舍去小于2G
- zh2=*p;//從高到底的地第二字節(jié) 、、
- p++;
- zh3=*p; //從高到底的地第三字節(jié)
- p++;
- zh4=*p; //從高到底的地第四字節(jié)
- //readsd(numb);//讀物理扇區(qū)
- //**************
- CS=0;//片選開
- write1( 0x51);
- write1( zh1);//這里是2G以下可以為00
- write1( zh2);
- write1( zh3);
- write1( zh4);
- write1( 0xff);
- DATEOUT=1;
-
- for(;;)
- {
- fhz=read1();
- if(fhz==0x00)break;
-
-
- }
- DATEOUT=1;
- for(;;)
- {
- fhz=read1();
- if(fhz==0xfe)break;
-
-
- }
- DATEOUT=1;
- n=0;
- for(k=512;k;k--)
- {
- tab[n]=read1();
- n++;
- }
- fhz=read1();
- fhz=read1();
- CS=1;
- write1(0xff);
-
-
-
- }
- void readsd_mp3(unsigned long numbs) //讀一扇區(qū)的數(shù)據(jù)送MP3解碼。!
- {
- uchar *p;
- uchar zh2,zh3,zh4,zh1;
- uint j;
- p=&numbs; //取出存放Numb的地址的最高位!詳細(xì)請(qǐng)看匯編。
- zh1=*p;
- p++; //由于最高位不用所以這里舍去小于2G
- zh2=*p;//從高到底的地第二字節(jié) 、、
- p++;
- zh3=*p; //從高到底的地第三字節(jié)
- p++;
- zh4=*p; //從高到底的地第四字節(jié)
- //readsd(numb);//讀物理扇區(qū)
- //**************
-
- XDCS=0;
- CS=0;//片選開
- dat=0x51;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1; //fhz=read1(); 以上是寫SD卡
- //write1( 0x00);//這里是2G以下可以為00 //fhz=read1(); 以下是寫SD卡
- dat=zh1;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1; //fhz=read1(); 以上是寫SD卡
- //write1( zh2); //fhz=read1(); 以下是寫SD卡
- dat=zh2;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1; //fhz=read1(); 以上是寫SD卡
- // write1( zh3); //fhz=read1(); 以下是寫SD卡
- dat=zh3;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1; //fhz=read1(); 以上是寫SD卡
- //write1( zh4); //fhz=read1(); 以下是寫SD卡
- dat=zh4;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1; //fhz=read1(); 以上是寫SD卡
- // write1( 0xff); //fhz=read1(); 以下是寫SD卡
- dat=0xff;
- DATEIN=dat_7;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
-
- DATEIN=dat_6;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_5;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_4;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_3;
-
- SCLK=0;
-
- SCLK=1;
-
-
- DATEIN=dat_2;
-
- SCLK=0;
-
-
- SCLK=1;
-
-
- DATEIN=dat_1;
-
- SCLK=0;
-
- SCLK=1;
-
- DATEIN=dat_0;
-
- SCLK=0;
-
- SCLK=1;
- DATEOUT=1; // 以上是寫SD卡
-
- for(;;)
- {
- //fhz=read1(); 以下是讀SD卡
- DATEOUT=1;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
- //if(!is_init)delay(1);
- dat_7=DATEOUT;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
-
- //if(!is_init)delay(1);
- dat_6=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_5=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_4=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_3=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_2=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_1=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_0=DATEOUT;
- fhz=dat; // 以上是讀SD卡
- if(fhz==0x00)break;
-
-
- }
- DATEOUT=1;
- for(;;)
- {
- // fhz=read1(); 以下是讀SD卡
- DATEOUT=1;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
- //if(!is_init)delay(1);
- dat_7=DATEOUT;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
-
- //if(!is_init)delay(1);
- dat_6=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_5=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_4=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_3=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_2=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_1=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_0=DATEOUT;
- fhz=dat; //fhz=read1(); 以上是讀SD卡
- if(fhz==0xfe)break;
-
-
- }
- DATEOUT=1;
- // n=0;
- for(j=512;j;j--)
- {
- DATEOUT=1; //fhz=read1(); 以下是讀SD卡
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
- //if(!is_init)delay(1);
- dat_7=DATEOUT;
- SCLK=1;
- //if(!is_init)delay(1);
- SCLK=0;
-
- //if(!is_init)delay(1);
- dat_6=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_5=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_4=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_3=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_2=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_1=DATEOUT;
- SCLK=1;
-
- // if(!is_init)delay(1);
- SCLK=0;
-
- // if(!is_init)delay(1);
- dat_0=DATEOUT; //fhz=read1(); 以上是讀SD卡
- datmp3=dat; //fhz=read1(); 以下是寫mp3bit流
- DREQ=1;
- while(!DREQ);
-
- SI=datmp3_7;
- //為了進(jìn)一步提高速度我這里采用了順序結(jié)構(gòu)!全是斷橋殘雪惹的禍!第一次愛的人播放正常!而斷橋殘雪不行了!一定盡全力
- SCK=0; //從SD讀取和MP3寫數(shù)據(jù)流下手
- SCK=1;
-
- SI=datmp3_6;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_5;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_4;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_3;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_2;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_1;
-
- SCK=0;
- SCK=1;
-
- SI=datmp3_0;
-
- SCK=0;
- SCK=1;
-
-
-
-
-
-
-
- //以上是寫mp3bit流
- }
- //**********************以下是讀CRC*****
- DATEOUT=1;
- SCLK=1;
- SCLK=0;
- dat_7=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_6=DATEOUT;
- SCLK=1;
-
- SCLK=0;
-
- dat_5=DATEOUT;
- SCLK=1;
-
- SCLK=0;
-
- dat_4=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_3=DATEOUT;
- SCLK=1;
-
- SCLK=0;
- dat_2=DATEOUT;
- SCLK=1;
-
- SCLK=0;
-
- dat_1=DATEOUT;
- SCLK=1;
- SCLK=0;
- dat_0=DATEOUT;
- DATEOUT=1;
- SCLK=1;
- SCLK=0;
- dat_7=DATEOUT;
- SCLK=1;
- SCLK=0;
- dat_6=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_5=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_4=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_3=DATEOUT;
- SCLK=1;
- SCLK=0;
-
- dat_2=DATEOUT;
- SCLK=1;
- SCLK=0;
- dat_1=DATEOUT;
- SCLK=1;
- SCLK=0;
- dat_0=DATEOUT;
- CS=1;
- dat=0xff;
- DATEIN=dat_7;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_6;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_5;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_4;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_3;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_2;
- SCLK=0;
- SCLK=1;
- DATEIN=dat_1;
- SCLK=0;
- SCLK=1;
-
- DATEIN=dat_0;
- SCLK=0;
- SCLK=1;
-
- XDCS=1;
- //**********************以上是讀CRC***** //**************
- }
-
- ////***************************************以上是SD主程序
- /*
- FAT32文件系統(tǒng)是用來尋找歌曲文件的手段!必須的 ////////////////////////////////////////////////////////////////////////////////////////////////////
- 下面是了
- 名稱:FAT32 文件系統(tǒng)
- 說明:不要認(rèn)為FAT32多神秘,其實(shí)他就是"查字典" 只是每一個(gè)環(huán)節(jié)都不能錯(cuò)。。∫画h(huán)扣一環(huán)
- 編制:王均偉
- 地點(diǎn):天津市開發(fā)區(qū)泰達(dá)地下交通空間第四項(xiàng)目部宿舍
- 時(shí)間:2010年12月29日19:00完成!調(diào)試完畢!!所有歌曲完整無缺的再現(xiàn)!
- 記:本文件系統(tǒng)是以簇為單位,也就是說要讀就是一簇!不存在精確到扇區(qū)的算法!因此在切換
- 歌曲時(shí)容易出現(xiàn)幾毫秒的等待或噪音!只讀 了根目錄的第一個(gè)扇區(qū),所以不能播放超過第一扇區(qū)
- 存放的P3文件!也是經(jīng)一步改進(jìn)的地方!但是相對(duì)此系統(tǒng)而言,就簡單了!我總結(jié)了!只要你有思路
- 你有想法!那么不管是否可行根據(jù)這個(gè)想法畫出流程圖,一步一步改進(jìn)細(xì)化流程圖,然后把流程分成幾個(gè)
- 功能塊!分別編寫子函數(shù),最后連起來!調(diào)試!關(guān)鍵是調(diào)試,一編編,一個(gè)問題要問:為什么會(huì)這樣?是什么原因
- 導(dǎo)致的?一步步排查!實(shí)驗(yàn),排查!一定能找到阻礙你的那塊石頭!!
- */
-
- /*****************************************************************
- /* 函數(shù)名:unsigned long find_sd_type(); *
- /* 作用:FAT32系統(tǒng)中用來尋找根目錄中的MP3文件 *
- /* 輸入:無 *
- /* 輸出:返回一個(gè)長整形作為找到的MP3文件的簇號(hào) *
- /* *
- /* *
- /* *
- /* *
- /*****************************************************************
- */
- unsigned long find_sd_type()
- {
-
- uchar i,n,a,m,clr;
- unsigned long h1,h2,h3,h4,startadd;
-
- lpp: readsd(k);//這里的K一定要是全局變量!因?yàn)樵诤瘮?shù)調(diào)用時(shí),他要不能變化 當(dāng)然靜態(tài)也是可以的!我覺得不保險(xiǎn),算了,加點(diǎn)內(nèi)存加點(diǎn)吧
- switch (some)//some是用來掃描mp3文件。!
- { case 0: {some=1; i=0;break; }//檢測(cè)第0行,提供指針
- case 1: {some=2; i=2;break; }//檢測(cè)第2行,提供指針
- case 2: {some=3; i=4;break; }//檢測(cè)第4行,提供指針
- case 3: {some=4; i=6;break; }//檢測(cè)第6行,提供指針
- case 4: {some=5; i=8;break; }//檢測(cè)第8行,提供指針
- case 5: {some=6; i=10;break;}//檢測(cè)第10行,提供指針
- case 6: {some=7; i=12;break;}//檢測(cè)第12行,提供指針
- case 7: {some=8; i=14;break;}//檢測(cè)第14行,提供指針
- case 8: {some=9; i=16;break;}//檢測(cè)第16行,提供指針
- case 9: {some=10; i=18;break;}//檢測(cè)第18行,提供指針
- case 10:{some=11; i=20;break;}//檢測(cè)第20行,提供指針
- case 11:{some=12; i=22;break;}//檢測(cè)第22行,提供指針
- case 12:{some=13; i=24;break;}//檢測(cè)第24行,提供指針
- case 13:{some=14; i=26;break;}//檢測(cè)第26行,提供指針
- case 14:{some=15; i=28;break;}//檢測(cè)第28行,提供指針
- case 15:{some=0; i=30;break;}//檢測(cè)第30行,提供指針
- }
-
- //把根目錄中的第一扇區(qū)數(shù)據(jù)讀入tab中。。
- for(;;)
- {
- n=tab[8+(16*i)];//
- a=tab[9+(16*i)];//
- m=tab[10+(16*i)];//
- clr=tab[(16*i)];
-
- if((n==0x4d)&(a==0x50)&(m==0x33)&(clr!=0xe5)){break;}//如果有mp3文件擴(kuò)展名且m之前第8個(gè)字節(jié)不能是e5,因?yàn)閑5表示已經(jīng)刪除的文件,的話退出,沒有就一直找!
- if((n==0)&(m==0)&(a==0)&(clr==0)){k=4323840;goto lpp;} //如果讀到0000000,表示下面沒有MP3文件了
- if(i==30){k=(k+512);goto lpp;}//如果讀到30表示一個(gè)扇區(qū)讀完了只是30里面沒東西話
-
- goto lpp;
-
- }
- if(i==30){k=(k+512);}//如果讀到了30行表示一個(gè)扇區(qū)讀完了只是30行里有歌曲文件 這里的30表示一個(gè)扇區(qū)有0-31行:::
-
-
-
-
-
- //注意這里的i--;是必要的!應(yīng)為我在比較后
- h1=tab[20+(16*i)]; //i多加了一次,所以要減去,因?yàn)橄旅嫖乙玫模!就是這個(gè)原因!
- h2=tab[21+(16*i)];//查文件開始簇的地址
- h3=tab[26+(16*i)];
- h4=tab[27+(16*i)];//這里得到h1-h4表示
-
-
-
-
- h2=(h2<<24);//注意這里!h2是在32為中的32-24位 開始我在這里搞錯(cuò)了
- h1=(h1<<16);//注意這里!h1是在32為中的17-24位 ///格式轉(zhuǎn)換!把它有逆序排列的十六進(jìn)制轉(zhuǎn)換成正常的高位在前的十六進(jìn)制。。
- h4=(h4<<8);//注意這里!h2是在32為中的8-16位 / /上面不用轉(zhuǎn)換,文件名的排列是正確的!
- startadd=h1+h2+h3+h4;
-
- return(startadd);//返回文件的開始簇開始
- }
-
- /*****************************************************************
- /* 函數(shù)名:unsigned long find_sd_fat(unsigned long startadd1); *
- /* 作用:FAT32系統(tǒng)中用來查找FAT是否有下一簇的開始地址 *
- /* 如有則返回,沒有則退出 *
- /* 輸入:已經(jīng)執(zhí)行完的的或前一個(gè)簇號(hào) *
- /* 輸出:返回一個(gè)長整形作為找到的MP3文件的下一簇開始地址*
- /* *
- /* *
- /* *
- /* *
- /*****************************************************************
- */
- unsigned long find_sd_fat(unsigned long startadd1)
- {
- unsigned long a,b,c,d,startadd; //snumb存儲(chǔ)扇區(qū)數(shù)
- static unsigned long snumb;
- snumb=((startadd1*4)/512);//占得扇區(qū)數(shù)
- readsd(2363904+(snumb*512));//讀fat表放入tab中
- a=tab[(startadd1*4)-(snumb*512)];//最低字節(jié)
- b=tab[(startadd1*4)-(snumb*512)+1];
- c=tab[(startadd1*4)-(snumb*512)+2];
- d=tab[(startadd1*4)-(snumb*512)+3];//最高字節(jié)
- d=(d<<24);
- c=(c<<16);
- b=(b<<8);
- startadd=a+b+c+d;
- return (startadd);
- }
- ///////////////////////////////////////////////////////////////
- void main() //主程序
- {
- uint ct;
- unsigned long numb,f,st;//numb是簇號(hào),f是物理地址,st 中間變量
-
- init_mp3();//初始化MP3
- ////////////////
- is_init=1;
- restsd(); //復(fù)位SD卡
- initsd(); //初始化SD卡
- is_init=0;//提高始終頻率
- ///////////////
- sing(100);//正選測(cè)試
- while(1)//主循環(huán)
- {
-
- // numb=//從4327936物理地址開始讀歌曲!
- loop: p1_7=0;
- numb=find_sd_type();//計(jì)算mp3文件的開始簇,返回計(jì)算出的文件開始簇號(hào)!
- p1_7=1;
- while(1)
- {
-
-
- f=(4323840+((numb-2)*4096));// 將計(jì)算歌曲的開始簇地址轉(zhuǎn)化成SD卡的物理地址
- st=f;//中間量ST保證一個(gè)個(gè)基準(zhǔn)量,F(xiàn)則不行!因?yàn)镕要加0X200時(shí)刻變化的!而ST則是不變的!!
- for(;;) //讀出一簇?cái)?shù)據(jù)送往MP3;
- {
-
- readsd_mp3(f);//給他地址他就播放。!當(dāng)然是物理SD地址
-
- f=(f+0x200);//因?yàn)槭且淮厮砸x扇區(qū)后腰加一扇區(qū)的地址更新
-
- if(f==(st+4096))break; //如果是一簇播放完畢!那么要退出!尋找下一簇!怎么找?FAT表
- }
-
- numb=find_sd_fat(numb); //查FAT表!找到下一簇!
- if(numb==0x0fffffff)//文件播放完畢?完畢就轉(zhuǎn)到下一首,沒完繼續(xù)查fat表
- {
- XDCS=0;
- for(ct=2048;ct;ct--)
- {
-
- write_date_mp3(0);
-
-
- }
- XDCS=1;
-
- goto loop;
-
-
- }// 是否播放完畢?檢測(cè)到0X0FFFFFFF表示播放完畢!如果完畢則轉(zhuǎn)到loop執(zhí)行
-
- }
-
- }
-
-
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|