單片機課程設計>八音盒


 

 


 

 

 


2017—2018學年度第一學期

 

《單片機原理及應用》作品考試

 

八音盒


 

 

 

                 

 

2017-2018-1《單片機原理及應用》作品設計提交文檔

一、作品設計目的

1、利用51單片機的各個部件結合實現八音盒。

2. 通過按鍵控制蜂鳴器播放設定的歌曲,按鍵1~8控制8首歌曲的播放,按鍵0 停止播放歌曲。

3. 熟練掌握C 語言與單片機的結合,單片機的原理和PCB制圖原理。

二、作品設計內容

1、總電路圖顯示       

 

 

2、總程序

#include <reg52.h>

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

uchar th0_f;

uchar tl0_f;

unsigned char i=100;

unsigned char j,k,temp,key;

uchar code jie8[8]={12,14,16,17,19,21,23,24};

 

sbit datacs=P2^6;   //位選

sbit chipcs=P2^7;         //段選

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f};                                               ///共陰數碼管顯示段碼0~8

 

sbit row1=P2^5;                //行端口定義

sbit row2=P2^4;

sbit row3=P2^3;

sbit row4=P2^2;

 

sbit col1=P1^7;                 //列端口定義

sbit col2=P1^6;

sbit col3=P2^0;

sbit col4=P2^1;

sbit SPEAK = P3^0;//接蜂鳴器管腳

 

/*按鍵掃描函數*/

void keyScan(void)

{

                                     col1=0;col2=1;col3=1;col4=1;

                                     temp=P2&0x3f;

                                                    

                                     if(col1==0)                      //假設第一列有按鍵

                                     {

                                          if(temp!=0x3f)              //沒有按鍵退出這次對第一列鍵盤掃描

                                          {

                                                 temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=12; break;     //0’鍵被按下時導通,則對應端口變為低電平

                            case 0x34:key=8;break;

                                                     case 0x2C:key=4;break;

                            case 0x1C:key=0;break;

                                                 }

                                          }

                                     }

                                     col1=1;col2=0;col3=1;col4=1;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(col2==0)

                                     {

                                          if(temp!=0x3f)

                                          {

                                                 temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=13; break;     //0’鍵被按下時導通,則對應端口變為低電平

                            case 0x34:key=9;break;

                                                     case 0x2C:key=5;break;

                            case 0x1C:key=1;break;

                                                 }

                                          }

                                     }

                                     col1=1;col2=1;col3=0;col4=1;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(temp!=0x3f)

                                     {

                                          temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=14; break;     //0’鍵被按下時導通,則對應端口變為低電平

                            case 0x34:key=10;break;

                                                     case 0x2C:key=6;break;

                            case 0x1C:key=2;break;

                                                 }

                                     }

                                     col1=1;col2=1;col3=1;col4=0;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(temp!=0x3f)

                                     {

                                     temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=15; break;     //0’鍵被按下時導通,則對應端口變為低電平

                            case 0x34:key=11;break;

                                                     case 0x2C:key=7;break;

                            case 0x1C:key=3;break;

                                                 }

                                     }

 

 

 /**************************中斷函數*******************************************/

timer0() interrupt 1

{

                                     TL0=tl0_f;TH0=th0_f;

                                     SPEAK =~SPEAK; //取反音樂輸出IO

}

 

 /********************T0的值,及輸出頻率對照表***********************************/

uchar code freq[36*2]={

                                                                      0xA9,0xEF,//00220HZ ,1 //0

                                                                      0x93,0xF0,//00233HZ ,1#

                                                                      0x73,0xF1,//00247HZ ,2

                                                                      0x49,0xF2,//00262HZ ,2#

                                                                      0x07,0xF3,//00277HZ ,3

                                                                      0xC8,0xF3,//00294HZ ,4

                                                                      0x73,0xF4,//00311HZ ,4#

                                                                      0x1E,0xF5,//00330HZ ,5

                                                                      0xB6,0xF5,//00349HZ ,5#

                                                                      0x4C,0xF6,//00370HZ ,6

                                                                      0xD7,0xF6,//00392HZ ,6#

                                                                      0x5A,0xF7,//00415HZ ,7

                                                                      0xD8,0xF7,//00440HZ 1 //12

                                                                      0x4D,0xF8,//00466HZ 1# //13

                                                                      0xBD,0xF8,//00494HZ 2 //14

                                                                      0x24,0xF9,//00523HZ 2# //15

                                                                      0x87,0xF9,//00554HZ 3 //16

                                                                      0xE4,0xF9,//00587HZ 4 //17

                                                                      0x3D,0xFA,//00622HZ 4# //18

                                                                      0x90,0xFA,//00659HZ 5 //19

                                                                      0xDE,0xFA,//00698HZ 5# //20

                                                                      0x29,0xFB,//00740HZ 6 //21

                                                                      0x6F,0xFB,//00784HZ 6# //22

                                                                      0xB1,0xFB,//00831HZ 7 //23

                                                                      0xEF,0xFB,//00880HZ `1

                                                                      0x2A,0xFC,//00932HZ `1#

                                                                      0x62,0xFC,//00988HZ `2

                                                                      0x95,0xFC,//01046HZ `2#

                                                                      0xC7,0xFC,//01109HZ `3

                                                                      0xF6,0xFC,//01175HZ `4

                                                                      0x22,0xFD,//01244HZ `4#

                                                                      0x4B,0xFD,//01318HZ `5

                                                                      0x73,0xFD,//01397HZ `5#

                                                                      0x98,0xFD,//01480HZ `6

                                                                      0xBB,0xFD,//01568HZ `6#

                                                                      0xDC,0xFD,//01661HZ `7 //35

                                                                };

/***************************音樂符號串解釋函數****************************/

//入口:要解釋的音樂符號串,輸出的音調串,輸出的時長串

changedata(uchar *song,uchar *diao,uchar *jie)

{

                                     uchar i,i1,j;

                                     char gaodi; //高低+/-12音階

                                     uchar banyin;//有沒有半個升音階

                                     uchar yinchang;//音長

                                     uchar code jie7[8]={0,12,14,16,17,19,21,23}; //C調的7個值

                                     *diao=*song;

                                     for(i=0,i1=0;;)

                                     {

                                          gaodi=0; //高低=0

                                          banyin=0;//半音=0

                                          yinchang=4;//音長1

                                          if((*(song+i)=='|') || (*(song+i)==' ')) i++; //拍子間隔和一個空格過濾

                                          switch(*(song+i))

                                          {     

                                                 case ',': gaodi=-12;i++;//低音

                                                 break;

                                                 case '`': gaodi=12;i++; //高音

                                                 break;

                                          }

                                          if(*(song+i)==0) //遇到0結束

                                          {

                                                 *(diao+i1)=0; //加入結束標志0

                                                 *(jie+i1)=0;

                                                 return;

                                          }

                                          j=*(song+i)-0x30; i++; //取出基准音

                                          j=jie7[j]+gaodi; //加上高低音

                                          yinc: switch(*(song+i))

                                                 {

                                                        case '#': //有半音j加一個音階

                                                               i++;j++;

                                                               goto yinc;

                                                        case '-': //有一個音節加長

                                                               yinchang+=4;

                                                               i++;

                                                               goto yinc;

                                                        case '_': //有一個音節縮短

                                                               yinchang/=2;

                                                               i++;

                                                               goto yinc;

                                                        case '.': //有一個加半拍

                                                               yinchang=yinchang+yinchang/2;

                                                               i++;

                                                               goto yinc;

                                                 }

                                          *(diao+i1)=j; //記錄音符

                                          *(jie+i1)=yinchang; //記錄音長

                                          i1++;

                                     }

}

 

/******************************奏樂函數***************************************/

//入口:要演奏的音樂符號串

void play(uchar *songdata)

{

                                     uchar i,c,j=0;

                                     uint n;

                                     uchar  diaodata[48]; //音調緩沖

                                     uchar jiedata[48]; //音長緩沖

                                     changedata(songdata,diaodata,jiedata); //解釋音樂符號串

                                     TR0=1;

                                      keyScan();

                                     while(key==1||key==2||key==3||key==4||key==5||key==6||key==7||key==8)

{                                   for(i=0;diaodata[i]!=0;i++) //逐個符號演奏

                                     {

                                          tl0_f=freq[diaodata[i]*2]; //取出對應的定時值送給T0

                                          th0_f=freq[diaodata[i]*2+1];

                                          for(c=0;c<jiedata[i];c++) //按照音長延時

                                          {     

                                              keyScan();

                                                 for(n=0;n<29500;n++); //29500

                                                 if(key==0) //發現按鍵0,立即退出播放

                                                 {

                                                        TR0=0;

                                                        return;

                                                 }

                                          }

                                          TR0=0;

                                          for(n=0;n<460;n++); //音符間延時

                                          TR0=1;

                                     }TR0=0;

                                     }

}                                  

 

//茉莉花

uchar code molihua[]={"33_5_6_`1_`1_6_|55_6_5-|33_5_6_`1_`1_6_|55_6_5-|"

                       "5553_5_|665-|32_3_53_2_|11_2_1|"

                       //"3_2_1_3_2.3_|56_`1_5-|23_5_2_3_1_,6_|,5-,61|"

                       //"2.3_1_2-1_,6_|,5--"

                                                                   };

//世上只有媽媽好

uchar code mamahao[]={

"6.5_35|`16_5_6-|35_6_53_2_|1_,6_5_3_2-|"

"2.3_55_6_|321-|5.3_2_1_,6_1_|,5--"

};

//小毛驢

uchar code xiaomaolv[]={"1_1_1_3_|5_5_5_5_|6_6_6_`1|5-|"

                         "4_4_4_6_|3_3_3_3_|2_2_2_2_|5-"};

//我是一只菠蘿

uchar code boluo[]={

                                                 "1-|2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_`1_7_6_|5_4_2_3_11|"

                                                 "2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_5_2_3_|1---|"

};

//小星星

uchar code xiaoxingxing[]={

"1155|665-|4433|221-|"

"5544|332-|5544|332-|"

"1155|665-|4433|221-|"

};

//春天在哪里

uchar code chuntian[]={"3_3_3_1_|,5,5_|3_3_3_1_|3-|5_5_3_1_|,5_,5_,5|,6_,7_1_3_|2-|"

 "3_3_3_1_|,5,5_|3_3_3_1_|3-|5_6_5_6_|5_4_3_1_|,5_3_|2_1_"};

//找朋友

uchar code zhaopeng[]={"5_6_5_6_|5_6_5|5_`1_7_6_|5_6_5"};

//一分錢

uchar code yifen[]={"5`1|6_`1_5|3_5_2_3_|5|3_5_6_`1_|5_6_5_3_|5_13_2"};

//樂譜方式輸入的音樂播放

/******************************數碼管函數***************************************/

 //數碼管顯示

 void display(unsigned char num)

{

        P0=table[num];

                                            

        datacs=1;

        datacs=0;

        P0=0xfe;

        chipcs=1;

        chipcs=0;

}

 

/*******************************主函數****************************************/

void main(void)

{

                                     TMOD = 0x01; //使用定時器016位工作模式

                                     TR0 = 0;

                                     ET0 = 1;

                                     EA = 1;

                                     EX0=1;

 

 

                                     while(1)

                                     { 

                                     P3=0xff;

                                   keyScan();

                                     display(key);

                                        switch(key)

                                           {

                                                   case 1:play(molihua);      break;

                                                  case 2:play(mamahao);     break;                        

                                                   case 3:play(xiaomaolv);   break;                               

                                                   case 4:play(boluo);   break;

                                                 case 5:play(xiaoxingxing);   break;                        

                                                 case 6:play(chuntian); break;                 

                                                 case 7:play(yifen); break;

                                                 case 8:play(zhaopeng); break;

   }   }   }

 

3、PCB設計過程

(1)畫原理圖

 

 

(2)原理圖庫

 

 

 

 

 

(3)畫封裝圖

 

 

 

生成PCB圖、

布線

敷銅

 

 

 

 

 

 

 

三、調試過程

1、  詳細連線

用跳線連接單片機P3^0口連接開發板蜂鳴器p6口;用排線連接單片機P0口和開發板的P7口

2、調試過程簡介

在單片機中下載好代碼之后,按1鍵播放第一首音樂,按0停止之后,可以按其他按鍵播放其他音樂

 

四、作品設計心得和經驗

      

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM