2016年4月2日 星期六

微處理器實作: AT89S52 音樂盒

        在這個練習中,我設計了一個由四首歌所組成的音樂盒,使用者可以用案件選取所要的音樂,進行播放,這四首歌曲分別是: 0.周杰倫的青花瓷 ,  1. 超級馬力歐 , 2.馬利兄弟-地底世界 ,3.俄羅斯方塊背景音樂。

        程式中會用到兩個timer和一個外部中斷,timer0負責計時,timer1負責發出特定頻率的聲音,外部中斷是由按鍵(用來選擇歌曲)所產生。

執行結果:


完整程式:

#include <regx52.h>
#include "music.h"

#define LED_NUM_0 0xC0
#define LED_NUM_1 0xF9
#define LED_NUM_2 0xA4
#define LED_NUM_3 0xB0
#define LED_NUM_4 0x99
#define LED_NUM_5 0x92
#define LED_NUM_6 0x82
#define LED_NUM_7 0xF8
#define LED_NUM_8 0x80
#define LED_NUM_9 0x98

#define LED_OUT P1

#define MUSIC_MAX_NUM 4

unsigned char count_10ms;
unsigned int  Tone;
unsigned char Beat;
unsigned char playNum=0;


unsigned short count2 = 10;
unsigned short count3 = 0;

unsigned int mynum2 = 0;

unsigned char myarray[4];

unsigned char music_mode=0;
unsigned char music_sel = 0;
unsigned char music_playing = 0;
unsigned  int *ToneTableList[]=
{ToneTable_0, ToneTable_1, ToneTable_2, ToneTable_3};

unsigned char *BeatTableList[]=
{BeatTable_0, BeatTable_1, BeatTable_2, BeatTable_3};

unsigned char SelButtonState=0;
unsigned char ButtonPressTime=0;


unsigned char led_num[10] =
{
LED_NUM_0, LED_NUM_1, LED_NUM_2, LED_NUM_3, LED_NUM_4, 
LED_NUM_5, LED_NUM_6, LED_NUM_7, LED_NUM_8, LED_NUM_9
};

void my_delay_ms(unsigned int n)
{
unsigned int i, j;

for(j=0; j<n; j++)
for(i=0; i<120; i++) ; 

}

void T0_int(void) interrupt 1
{
   TL0 = (65536-10000)%256;
   TH0 = (65536-10000)/256;
    count_10ms++;

   if(count2 ==0 )
  {
count2=10;                
    myarray[3]= ~(1<<mynum2); 
    mynum2++;

        if(mynum2==6) mynum2=0;
 }
else 
count2--;
count3++; // for update 7-seg-display
       
        if(SelButtonState==1)
{
if(ButtonPressTime<40)  
ButtonPressTime++;
else
{
ButtonPressTime=0;
SelButtonState=0;
music_sel++;

          if(music_sel==MUSIC_MAX_NUM) 
           music_sel=0;
}
}
}

void T1_int(void) interrupt 3
{
    TH1=Tone/256;
    TL1=Tone%256;
 
    if(Tone!=0xff && Tone!=0x00 ) //0xff is no_sound, 0x00 is the end
  P2_0=~P2_0;
}

void EX0_int(void) interrupt 0
{
SelButtonState=1; //marking for the button is pressed
}

void timer0_init(void)
{
TMOD = (TMOD&0xf0) | 0x01; 
TL0 = (65536-10000) % 256;  
TH0 = (65536-10000) / 256;
ET0 = 1; 
TR0 = 1;
}

void timer1_init(void)
{
TMOD = (TMOD&0x0f) | 0x10;  
TL1 = (65536-10000) % 256; 
TH1 = (65536-10000) / 256; 
ET1 = 1; 
TR1 = 1;
}

void sys_init(void)
{
P2_0=1;
myarray[3] = 0xff;
playNum=0;
count_10ms = 0;

        Tone = ToneTableList[music_playing][playNum];
Beat = BeatTableList[music_playing][playNum];

EX0=1;
IT0=1;
P3_4 = 0;
EA = 1;
timer0_init(); 
timer1_init();

}

main()
{
sys_init();
while(1)
{
   if(music_playing == music_sel)
  {
     if(Tone!=0)
    {
if(count_10ms>Beat)
{
      TR1=0;
   playNum++;
   count_10ms=0;
   Tone=ToneTableList[music_playing][playNum];
   Beat=BeatTableList[music_playing][playNum];
   TH1=Tone/256;
  TL1=Tone%256;
                  TR1=1;
}
        }
   else
          {
       music_mode = 0xff;
    TR1=0;
   }
     } // music number changed
     else
     {
EA=0;
        music_playing = music_sel;
sys_init();
     }
  P3_1 = 0; //enable control bit: active LOW
 LED_OUT = led_num[music_playing];
 my_delay_ms(3);
 LED_OUT = 0xFF;
  P3_1 = 1;

  P3_0 = 0; //enable control bit: active LOW
 LED_OUT = myarray[3];
 my_delay_ms(3);
 LED_OUT = 0xFF;
  P3_0 = 1;
}
}

music.h 的內容(歌曲部分):

/*-------------------- 青花瓷-----------------------------*/
unsigned int code ToneTable_0[]=
{
  255, 63836, 63628, 63264, 63628, 63628, 63264, 63628, 63628, 63264, 
63628, 63264, 62985,   255,   255, 63836, 63628, 63264, 63628, 63628, 
63264, 63628, 63628, 64021, 63836, 63628, 63628,   255,   255, 62985, 
63264, 64021, 64021, 64021, 63836, 64021, 64021, 63836, 64021, 64261, 
64021, 64021,   255,   255, 64021, 64021, 64021, 63836, 63836, 63836, 
63836, 63836, 63628, 64021, 64021, 63836,   255,   255, 63836, 63628, 
63264, 63628, 63628, 63264, 63628, 63628, 63264, 63628, 63264, 62985, 
  255,   255, 62985, 63264, 64021, 64261, 64261, 64021, 64261, 64261, 
64021, 63836, 63628, 63628,   255,   255, 63836, 63628, 63836, 64021, 
63836, 63836, 63628, 63836, 63628, 63264, 63836, 63628, 63628, 63264, 
63628, 63628, 63628,   255,   255, 64261, 64261, 64021, 63836, 64021, 
63264, 63836, 64021, 64261, 64021, 63836,   255,   255, 64261, 64261, 
64021, 63836, 64021, 62985, 63836, 64021, 64261, 63836, 63628,   255, 
  255, 63628, 63836, 64021, 64261, 64400, 64261, 64104, 64261, 64021, 
64021, 63836, 63836,   255,   255, 63628, 63836, 63628, 63628, 63836, 
63628, 63836, 63836, 64021, 64261, 64021, 64021,   255,   255, 64261, 
64261, 64021, 63836, 64021, 63264, 63836, 64021, 64261, 64021, 63836, 
  255,   255, 64261, 64261, 64021, 63836, 64021, 62985, 63836, 64021, 
64261, 63836, 63628,   255,   255, 63628, 63836, 64021, 64261, 64400, 
64261, 64104, 64261, 64021, 64021, 63836, 63836, 62985, 64021, 63836, 
63836, 63836, 63628,   255, 0
};

unsigned char code BeatTable_0[]=
{
25, 25, 25, 25, 50, 25, 25, 50, 25, 25, 
25, 25, 50, 50, 25, 25, 25, 25, 50, 25, 
25, 50, 25, 25, 25, 25, 50, 50, 25, 25, 
25, 25, 50, 25, 25, 50, 25, 25, 25, 25, 
25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 
25, 50, 25, 25, 25, 50, 50, 25, 25, 25, 
25, 50, 25, 25, 50, 25, 25, 25, 25, 50, 
50, 25, 25, 25, 25, 50, 25, 25, 50, 25, 
25, 25, 25, 50, 50, 25, 25, 25, 25, 25, 
25, 25, 25, 50, 25, 25, 25, 25, 25, 25, 
50, 25, 100, 50, 25, 25, 25, 25, 25, 25, 
50, 25, 25, 25, 25, 100, 50, 25, 25, 25, 
25, 25, 25, 50, 25, 25, 25, 25, 100, 50, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 100, 50, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 50, 25, 25, 50, 50, 25, 25, 
25, 25, 25, 25, 50, 25, 25, 25, 25, 100, 
50, 25, 25, 25, 25, 25, 25, 50, 25, 25, 
25, 25, 100, 50, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 100, 25, 50, 25, 
25, 25, 100, 50, 
};

/* --------------------- 超級馬力歐-----------------------------*/
unsigned int code ToneTable_1[]=
{
65347, 65347,   255, 65347,   255, 65298, 65347,   255, 65377,   255, 
  255,   255, 65218,   255,   255,   255, 65298,   255,   255, 65218, 
  255,   255, 65157,   255,   255, 65252,   255, 65283,   255, 65268, 
65252,   255, 65218, 65347, 65377, 65394,   255, 65358, 65377,   255, 
65347,   255, 65298, 65324, 65283,   255,   255, 65298,   255,   255, 
65218,   255,   255, 65157,   255,   255, 65252,   255, 65283,   255, 
65268, 65252,   255, 65218, 65347, 65377, 65394,   255, 65358, 65377, 
  255, 65347,   255, 65298, 65324, 65283,   255,   255, 0
};


unsigned char code BeatTable_1[]=
{
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
16, 16, 22, 22, 22, 16, 16, 16, 16, 16, 
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
16, 16, 16, 22, 22, 22, 16, 16, 16, 16, 
16, 16, 16, 16, 16, 16, 16, 16, 
};

/* ---------------- 馬利兄弟: underworld ------------ */
unsigned int code ToneTable_2[]=
{
63628, 64580, 63264, 64400, 63391, 64464,   255,   255, 63628, 64580, 
63264, 64400, 63391, 64464,   255,   255, 62679, 64104, 62135, 63836, 
62331, 63929,   255,   255, 62679, 64104, 62135, 63836, 62331, 63929, 
  255,   255, 63929, 63731, 63836, 63731, 63929, 63929, 63133, 62985, 
63731, 63628, 64185, 64104, 62506, 64464, 64400, 64332, 63929, 63512, 
63391, 63264, 63133,   255,   255,   255, 0
};

unsigned char code BeatTable_2[]=
{
16, 16, 16, 16, 16, 16, 33, 66, 16, 16, 
16, 16, 16, 16, 33, 66, 16, 16, 16, 16, 
16, 16, 33, 66, 16, 16, 16, 16, 16, 16, 
33, 33, 11, 11, 11, 33, 33, 33, 33, 33, 
33, 11, 11, 11, 11, 11, 11, 20, 20, 20, 
20, 20, 20, 66, 66, 66, 
};

/* -------------------俄羅斯方塊背景音樂  -------------------------*/
unsigned int code ToneTable_3[]=
{
64778, 62506, 64524, 64580, 64685, 64778, 64685, 64580, 64524, 64400, 
63264, 64400, 64580, 64778, 63264, 64685, 64580, 64524, 64021, 64261, 
64580, 64685, 62506, 64778, 62506, 64580, 63264, 64400, 63264, 64400, 
63264, 61471, 61720, 62135, 64685, 64820, 64968, 64580, 64580, 64899, 
64820, 64778, 61720,   255, 64580, 64778, 64400, 64261, 64685, 64580, 
64524, 64021, 64524, 64580, 64685, 64261, 64778, 64261, 64580, 64021, 
64400, 62506, 64400,   255, 64778, 62506, 64524, 64580, 64685, 64778, 
64685, 64580, 64524, 64400, 63264, 64400, 64580, 64778, 63264, 64685, 
64580, 64524, 64021, 64261, 64580, 64685, 62506, 64778, 62506, 64580, 
63264, 64400, 63264, 64400, 63264, 61471, 61720, 62135, 64685, 64820, 
64968, 64580, 64580, 64899, 64820, 64778, 61720,   255, 64580, 64778, 
64400, 64261, 64685, 64580, 64524, 64021, 64524, 64580, 64685, 64261, 
64778, 64261, 64580, 64021, 64400, 62506, 64400,   255, 64021, 62506, 
60991, 62506, 63628, 62506, 60991, 62506, 63836, 62506, 60729, 62506, 
63512, 62506, 60729, 62506, 63628, 62506, 60991, 62506, 63264, 62506, 
60991, 62506, 63133, 62506, 60729, 62506, 63512, 62506, 60729, 62506, 
64021, 62506, 60991, 62506, 63628, 62506, 60991, 62506, 63836, 62506, 
60729, 62506, 63512, 62506, 60729, 62506, 63628, 62506, 64021, 62506, 
64400, 62506, 60991, 62506, 64332, 62506, 60729, 62506, 60729, 62506, 
60729, 62506, 64778, 62506, 64524, 64580, 64685, 64778, 64685, 64580, 
64524, 64400, 63264, 64400, 64580, 64778, 63264, 64685, 64580, 64524, 
64021, 64261, 64580, 64685, 62506, 64778, 62506, 64580, 63264, 64400, 
63264, 64400, 63264, 61471, 61720, 62135, 64685, 64820, 64968, 64580, 
64580, 64899, 64820, 64778, 61720,   255, 64580, 64778, 64400, 64261, 
64685, 64580, 64524, 64021, 64524, 64580, 64685, 64261, 64778, 64261, 
64580, 64021, 64400, 62506, 64400,   255, 64778, 62506, 64524, 64580, 
64685, 64778, 64685, 64580, 64524, 64400, 63264, 64400, 64580, 64778, 
63264, 64685, 64580, 64524, 64021, 64261, 64580, 64685, 62506, 64778, 
62506, 64580, 63264, 64400, 63264, 64400, 63264, 61471, 61720, 62135, 
64685, 64820, 64968, 64580, 64580, 64899, 64820, 64778, 61720,   255, 
64580, 64778, 64400, 64261, 64685, 64580, 64524, 64021, 64524, 64580, 
64685, 64261, 64778, 64261, 64580, 64021, 64400, 62506, 64400,   255, 
64021, 62506, 60991, 62506, 63628, 62506, 60991, 62506, 63836, 62506, 
60729, 62506, 63512, 62506, 60729, 62506, 63628, 62506, 60991, 62506, 
63264, 62506, 60991, 62506, 63133, 62506, 60729, 62506, 63512, 62506, 
60729, 62506, 64021, 62506, 60991, 62506, 63628, 62506, 60991, 62506, 
63836, 62506, 60729, 62506, 63512, 62506, 60729, 62506, 63628, 62506, 
64021, 62506, 64400, 62506, 60991, 62506, 64332, 62506, 60729, 62506, 
60729, 62506, 60729, 62506, 0
};

unsigned char code BeatTable_3[]=
{
25, 25, 25, 25, 25, 12, 12, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 50, 25, 25, 12, 12, 25, 
25, 25, 25, 25, 25, 25, 12, 12, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 50, 50, 25, 25, 25, 25, 25, 12, 
12, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 50, 25, 
25, 12, 12, 25, 25, 25, 25, 25, 25, 25, 
12, 12, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 50, 50, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 12, 12, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 50, 25, 25, 12, 
12, 25, 25, 25, 25, 25, 25, 25, 12, 12, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 50, 50, 25, 25, 25, 25, 
25, 12, 12, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
50, 25, 25, 12, 12, 25, 25, 25, 25, 25, 
25, 25, 12, 12, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 50, 50, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 
25, 25, 25, 25, 
};


沒有留言:

張貼留言