欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標題: 基于單片機的音樂播放 [打印本頁]

作者: QQQQQQQY    時間: 2019-5-23 13:26
標題: 基于單片機的音樂播放
#include "MusicPlay.h"
unsigned char *PP[]={song1,song2,song3};//指向歌曲的指針數組
unsigned char *p;//只想歌曲的指針
unsigned int Point = 0;//歌曲播放位置
bit flag_pause=1;//暫停標志位
bit flag_up=0;//上一曲標志位
bit flag_down=0;//下一曲標志位
int flag_order=0;//歌曲順序
void Delay1ms(unsigned int count);//簡單延時
void InitialSound(void);//初始化
void Play(unsigned char *sound,unsigned char Signature,unsigned Octachord,unsigned int Speed);//音樂播放函數
//******************主程序***************************************************
void main()
{
    InitialSound();
    while(1)
    {
        if(k_state==0)//有按鍵按下
        {
            if(k_pause==0)//開始/暫停鍵
            {
                while(k_pause==0);
                flag_pause=~flag_pause;
            }
        }
        while(!flag_pause)
        {
            Play(p+Point,0,3,360);
            Delay1ms(300);
            if(flag_down | flag_up)
            {
                if(flag_down) flag_down=0;
                if(flag_up)   flag_up  =0;
                Point = 0;
            }
            else flag_order++;
            if(flag_pause==1) flag_order--;
        
            if(flag_order == 3)
                flag_order = 0;
            p=PP[flag_order];   
        }
    }
}
//***********************中斷服務程序*************************************//
void BeepTimer0(void) interrupt 1   //音符中斷程序
{
    BeepIO = !BeepIO;
    TH0    = Sound_Temp_TH0;
    TL0    = Sound_Temp_TL0;
}
//***********************簡單延時*******************************************//
void Delay1ms(unsigned int count)
{
    unsigned int i,j;
    for(i=0;i<count;i++)
    for(j=0;j<120;j++);
}
//***********************系統初始化********************************************//
void InitialSound(void)
{
    BeepIO = 0;
    Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;   // 計算TL1應裝入的初值  (10ms的初裝值)
    Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;   // 計算TH1應裝入的初值
    TH1 = Sound_Temp_TH1;
    TL1 = Sound_Temp_TL1;
    TMOD  |= 0x11;
    ET0    = 1;
    ET1    = 0;
    TR0    = 0;
    TR1    = 0;
    EA     = 1;
    p=PP[0];
}
/****************************音樂播放函數***************************************/
/*  input:歌曲名sound
                    調號signature
          音階octachord
                    速度speed
*/
void Play(unsigned char *sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
    unsigned int NewFreTab[12];//新的頻率表
    unsigned char i,j;
    unsigned int LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
    unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
    if(p==song1) flag_order=0;
    else if (p==song2) flag_order=1;
    else if (p==song3)  flag_order=2;
    for(i=0;i<12;i++)// 根據調號及升降八度來生成新的頻率表
    {
        j = i + Signature;
        if(j > 11)
        {
            j = j-12;
            NewFreTab[i] = FreTab[j]*2;
        }
        else
            NewFreTab[i] = FreTab[j];
        if(Octachord == 1)
            NewFreTab[i]>>=2;
        else if(Octachord == 3)
            NewFreTab[i]<<=2;
    }                                   
    SoundLength = 0;
    while(sound[SoundLength] != 0x00)   //計算歌曲長度
    {
        SoundLength+=2;
    }
//  Point = 0;
    Tone   = sound[Point];
    Length = sound[Point+1];            // 讀出第一個音符和它時時值
   
    LDiv0 = 12000/Speed;                // 算出1分音符的長度(幾個10ms)
    LDiv4 = LDiv0/4;                    // 算出4分音符的長度
    LDiv4 = LDiv4-LDiv4*SOUND_SPACE;    // 普通音最長間隔標準
    TR0   = 0;
    TR1   = 1;
    while(Point < SoundLength)
    {
        SL=Tone%10;                                 //計算出音符
        SM=Tone/10%10;                              //計算出高低音
        SH=Tone/100;                                //計算出是否升半
        CurrentFre = NewFreTab[SignTab[SL-1]+SH];   //查出對應音符的頻率     
        if(SL!=0)
        {
            if (SM==1) CurrentFre >>= 2;        //低音
            if (SM==3) CurrentFre <<= 2;        //高音
            Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//計算計數器初值
            Sound_Temp_TH0 = Temp_T/256;
            Sound_Temp_TL0 = Temp_T%256;
            TH0 = Sound_Temp_TH0;  
            TL0 = Sound_Temp_TL0 + 12; //加12是對中斷延時的補償
        }
        SLen=LengthTab[Length%10];  //算出是幾分音符
        XG=Length/10%10;            //算出音符類型(0普通1連音2頓音)
        FD=Length/100;
        LDiv=LDiv0/SLen;            //算出連音音符演奏的長度(多少個10ms)
        if (FD==1)
            LDiv=LDiv+LDiv/2;
        if(XG!=1)
            if(XG==0)               //算出普通音符的演奏長度
                if (SLen<=4)   
                    LDiv1=LDiv-LDiv4;
                else
                    LDiv1=LDiv*SOUND_SPACE;
            else
                LDiv1=LDiv/2;       //算出頓音的演奏長度
        else
            LDiv1=LDiv;
        if(SL==0) LDiv1=0;
            LDiv2=LDiv-LDiv1;       //算出不發音的長度
      if (SL!=0)
        {
            TR0=1;
            for(i=LDiv1;i>0;i--)    //發規定長度的音
            {
                while(TF1==0);
                TH1 = Sound_Temp_TH1;
                TL1 = Sound_Temp_TL1;
                TF1=0;
            }
        }
        if(LDiv2!=0)
        {
            TR0=0; BeepIO=0;
            for(i=LDiv2;i>0;i--)    //音符間的間隔
            {
                while(TF1==0);
                TH1 = Sound_Temp_TH1;
                TL1 = Sound_Temp_TL1;
                TF1=0;
            }
        }
        Point+=2;
        Tone=p[Point];
        Length=p[Point+1];
//按鍵掃描
        if(k_state==0)
        {//掃描開始
            if(k_pause==0)
            {
                while(k_pause==0);
                flag_pause=~flag_pause;
                TR1   = flag_pause;
                return;
            }
            if(k_up==0)
            {
                while(k_up==0);
                flag_up=~flag_up;
                flag_order--;
                if(flag_order < 0)
                    flag_order = 2;//第三首
                 p=PP[flag_order];
                break;
            }
            if(k_down==0)
            {
                while(k_down==0);
                flag_down=~flag_down;
                flag_order++;
                if(flag_order > 2)
                    flag_order=0;//第一首
                 p=PP[flag_order];
                break;
            }
        }//按鍵掃描結束
    }
    BeepIO = 0;//播放結束,關閉
}#include "MusicPlay.h"
unsigned char *PP[]={song1,song2,song3};//指向歌曲的指針數組
unsigned char *p;//只想歌曲的指針
unsigned int Point = 0;//歌曲播放位置
bit flag_pause=1;//暫停標志位
bit flag_up=0;//上一曲標志位
bit flag_down=0;//下一曲標志位
int flag_order=0;//歌曲順序
void Delay1ms(unsigned int count);//簡單延時
void InitialSound(void);//初始化
void Play(unsigned char *sound,unsigned char Signature,unsigned Octachord,unsigned int Speed);//音樂播放函數
//******************主程序***************************************************
void main()
{
    InitialSound();
    while(1)
    {
        if(k_state==0)//有按鍵按下
        {
            if(k_pause==0)//開始/暫停鍵
            {
                while(k_pause==0);
                flag_pause=~flag_pause;
            }
        }
        while(!flag_pause)
        {
            Play(p+Point,0,3,360);
            Delay1ms(300);
            if(flag_down | flag_up)
            {
                if(flag_down) flag_down=0;
                if(flag_up)   flag_up  =0;
                Point = 0;
            }
            else flag_order++;
            if(flag_pause==1) flag_order--;
        
            if(flag_order == 3)
                flag_order = 0;
            p=PP[flag_order];   
        }
    }
}
//***********************中斷服務程序*************************************//
void BeepTimer0(void) interrupt 1   //音符中斷程序
{
    BeepIO = !BeepIO;
    TH0    = Sound_Temp_TH0;
    TL0    = Sound_Temp_TL0;
}
//***********************簡單延時*******************************************//
void Delay1ms(unsigned int count)
{
    unsigned int i,j;
    for(i=0;i<count;i++)
    for(j=0;j<120;j++);
}
//***********************系統初始化********************************************//
void InitialSound(void)
{
    BeepIO = 0;
    Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;   // 計算TL1應裝入的初值  (10ms的初裝值)
    Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;   // 計算TH1應裝入的初值
    TH1 = Sound_Temp_TH1;
    TL1 = Sound_Temp_TL1;
    TMOD  |= 0x11;
    ET0    = 1;
    ET1    = 0;
    TR0    = 0;
    TR1    = 0;
    EA     = 1;
    p=PP[0];
}
/****************************音樂播放函數***************************************/
/*  input:歌曲名sound
                    調號signature
          音階octachord
                    速度speed
*/
void Play(unsigned char *sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
    unsigned int NewFreTab[12];//新的頻率表
    unsigned char i,j;
    unsigned int LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
    unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
    if(p==song1) flag_order=0;
    else if (p==song2) flag_order=1;
    else if (p==song3)  flag_order=2;
    for(i=0;i<12;i++)// 根據調號及升降八度來生成新的頻率表
    {
        j = i + Signature;
        if(j > 11)
        {
            j = j-12;
            NewFreTab[i] = FreTab[j]*2;
        }
        else
            NewFreTab[i] = FreTab[j];
        if(Octachord == 1)
            NewFreTab[i]>>=2;
        else if(Octachord == 3)
            NewFreTab[i]<<=2;
    }                                   
    SoundLength = 0;
    while(sound[SoundLength] != 0x00)   //計算歌曲長度
    {
        SoundLength+=2;
    }
//  Point = 0;
    Tone   = sound[Point];
    Length = sound[Point+1];            // 讀出第一個音符和它時時值
   
    LDiv0 = 12000/Speed;                // 算出1分音符的長度(幾個10ms)
    LDiv4 = LDiv0/4;                    // 算出4分音符的長度
    LDiv4 = LDiv4-LDiv4*SOUND_SPACE;    // 普通音最長間隔標準
    TR0   = 0;
    TR1   = 1;
    while(Point < SoundLength)
    {
        SL=Tone%10;                                 //計算出音符
        SM=Tone/10%10;                              //計算出高低音
        SH=Tone/100;                                //計算出是否升半
        CurrentFre = NewFreTab[SignTab[SL-1]+SH];   //查出對應音符的頻率     
        if(SL!=0)
        {
            if (SM==1) CurrentFre >>= 2;        //低音
            if (SM==3) CurrentFre <<= 2;        //高音
            Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//計算計數器初值
            Sound_Temp_TH0 = Temp_T/256;
            Sound_Temp_TL0 = Temp_T%256;
            TH0 = Sound_Temp_TH0;  
            TL0 = Sound_Temp_TL0 + 12; //加12是對中斷延時的補償
        }
        SLen=LengthTab[Length%10];  //算出是幾分音符
        XG=Length/10%10;            //算出音符類型(0普通1連音2頓音)
        FD=Length/100;
        LDiv=LDiv0/SLen;            //算出連音音符演奏的長度(多少個10ms)
        if (FD==1)
            LDiv=LDiv+LDiv/2;
        if(XG!=1)
            if(XG==0)               //算出普通音符的演奏長度
                if (SLen<=4)   
                    LDiv1=LDiv-LDiv4;
                else
                    LDiv1=LDiv*SOUND_SPACE;
            else
                LDiv1=LDiv/2;       //算出頓音的演奏長度
        else
            LDiv1=LDiv;
        if(SL==0) LDiv1=0;
            LDiv2=LDiv-LDiv1;       //算出不發音的長度
      if (SL!=0)
        {
            TR0=1;
            for(i=LDiv1;i>0;i--)    //發規定長度的音
            {
                while(TF1==0);
                TH1 = Sound_Temp_TH1;
                TL1 = Sound_Temp_TL1;
                TF1=0;
            }
        }
        if(LDiv2!=0)
        {
            TR0=0; BeepIO=0;
            for(i=LDiv2;i>0;i--)    //音符間的間隔
            {
                while(TF1==0);
                TH1 = Sound_Temp_TH1;
                TL1 = Sound_Temp_TL1;
                TF1=0;
            }
        }
        Point+=2;
        Tone=p[Point];
        Length=p[Point+1];
//按鍵掃描
        if(k_state==0)
        {//掃描開始
            if(k_pause==0)
            {
                while(k_pause==0);
                flag_pause=~flag_pause;
                TR1   = flag_pause;
                return;
            }
            if(k_up==0)
            {
                while(k_up==0);
                flag_up=~flag_up;
                flag_order--;
                if(flag_order < 0)
                    flag_order = 2;//第三首
                 p=PP[flag_order];
                break;
            }
            if(k_down==0)
            {
                while(k_down==0);
                flag_down=~flag_down;
                flag_order++;
                if(flag_order > 2)
                    flag_order=0;//第一首
                 p=PP[flag_order];
                break;
            }
        }//按鍵掃描結束
    }
    BeepIO = 0;//播放結束,關閉
}


untitled.png (278.08 KB, 下載次數: 53)

untitled.png

音樂r.zip

18.57 KB, 下載次數: 10, 下載積分: 黑幣 -5






歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1