標題: 單片機電子琴課程設計論文 [打印本頁]

作者: 51黑電子迷    時間: 2017-6-5 01:10
標題: 單片機電子琴課程設計論文
《單片機原理及應用》課程設計
一、        電子琴電路功能介紹及組成框圖
1、設計要求
由16個按鍵組成4×4鍵盤矩陣,設置成16個音,可隨意彈奏想要表現(xiàn)的音樂。按下鍵的同時,顯示鍵號;另外在沒有鍵按下時能播放一首熟悉的音樂。



二、硬件電路設計
1、總電路
2、各部分工作原理1 音頻電路原理
音頻電路原理為整個電子琴設計的核心原理,電路設計方法和編程方法都圍繞著電子琴的音頻產(chǎn)生、變化的原理來進行。
音頻電路中包含一個發(fā)音裝置。利用電子琴的音頻脈沖和節(jié)拍的產(chǎn)生原理,通過P3.3口來控制發(fā)音裝置,產(chǎn)生音符和音樂信號。
1.1)音頻脈沖
音樂的產(chǎn)生主要是通過單片機的I/O口輸出高低不同的脈沖信號來控制蜂鳴器發(fā)音,要想產(chǎn)生音頻脈沖信號,需要算出某一音頻的周期(1/頻率),然后將此周期除以2,即為半周期的時間。利用單片機定時器計時這個半個周期時間,每當計時到后就將輸出脈沖的I/O口反相,然后重復計時此半周期時間再對I/O口反相,這樣就能在此I/O口上得到此頻率的脈沖。通常,利用單片機的內部定時器0,工作在方式1下,改變計數(shù)初始值THO和TLO來實現(xiàn)。
例如,若單片機采用12MHz晶振,要產(chǎn)生頻率為587Hz的音頻脈沖時,其音頻信號的脈沖周期 T=1/587=1703.5775μs,半周期的時間為852μs,因此只要令計數(shù)器計數(shù)=852μs/1μs=852,在每計數(shù)852時將I/O口反相,就可得到C調中音Re。
計數(shù)脈沖值與頻率的關系如下:

頻率Hz

周期us

簡譜碼(定時初值)

音符

頻率Hz

周期

us

簡譜碼(定時初值)

低1Do

262

3816

63628

高1Do

1047

955

65058

低2Re

294

3401

63835

高2Re

1175

851

65110

低3Mi

330

3030

64021

高3Mi

1319

758

65157

低4Fa

349

2865

64103

高4Fa

1397

751

65160

低5So

392

2551

64260

高5So

1568

637

65217

低6La

440

2272

64400

高6La

1760

568

65252

低7Si

494

2024

64524

高7Si

1967

508

65282

中1Do

523

1912

64580

中2Re

587

1703

64684

中3Mi

659

1517

64777

中4Fa

698

1432

64820

中5So

784

1275

64898

中6La

880

1136

64968

中7Si

988

1012

65030

1.2 節(jié)拍
每個音符使用一個字節(jié),字節(jié)的高四位代表音符的高低,低四位代表音符的節(jié)拍,表5-2為節(jié)拍與節(jié)拍碼的對照表。如果1拍為0.4s,1/4拍是0.1s只要設定延遲時間就可求得節(jié)拍的時間。假設1/4拍為1個延遲單位時間,那么1拍對應的就是4個延遲單位時間,以此類推。所以只要求得1/4拍的延遲單位時間,其余的節(jié)拍就是它的倍數(shù),表5-3為1/4拍和1/8拍的時間設定。
不管采用哪種方法,當歌曲結束時,在發(fā)音計數(shù)值表(TABLE)中均需加上音樂結束符00H。
2)音符顯示
采用的共陰極7段數(shù)碼管作為音符顯示器。當AT89C51執(zhí)行完按鍵掃描程序后,所得到的鍵號送至P0口,通過P0口進而控制數(shù)碼管的音符字模的顯示。另外,P0口作為通用I/O口時,需要外界上拉電阻。
3)矩陣式音符鍵盤
          采用矩陣式鍵盤,節(jié)省I/O口資源。矩陣式鍵盤的行線與列線的交叉處不相通,設置為按鍵,n條行線與m條列線,可構成n*m個按鍵的鍵盤。
4)彈奏按鍵
音符按鍵采用外部中斷1的方式來實現(xiàn)。當按鍵按下時,調用中斷函數(shù)切斷音樂播放模式,進入音符按鍵彈奏模式。
三、軟件設計
1、程序組成
(1.1)歌曲播放程序
首先,建立音樂代碼庫:找出樂曲最低音和最高音范圍,然后確定音符表T的順序,把T值建立在數(shù)組 T[ ] 中,構成發(fā)音符的計數(shù)值放在數(shù)組tab[ ]中,以音符節(jié)拍碼00H為音樂結束標記。通過調用音樂代碼庫來實現(xiàn)演奏歌曲。
[音樂代碼庫]
[音樂播放程序]
(1.2)鍵盤音符獲取程序
鍵盤是人與單片機通信的重要接口。合適的鍵盤掃描程序能使單片機準確的運行。另外,按鍵按下時,由于彈簧抖動的原因,會對按鍵有無按下的判斷產(chǎn)生干擾,故需要采用適當?shù)南斗椒。本案例采用軟件延時的方法去抖動。
[延時去抖動]
[按鍵掃描]
(1.3)音符顯示程序
采用的共陰極7段數(shù)碼管作為音符顯示器,當執(zhí)行完按鍵掃描程序后,所得到的鍵號送至P0口,通過P0口進而控制數(shù)碼管的音符字模的顯示。
[音符獲取]
(1.4)彈奏模式程序
通過彈奏按鍵的按下來產(chǎn)生外部中斷,利用中斷來實現(xiàn)由歌曲播放模式轉到彈奏模式。
[外部中斷0函數(shù)]
[音符彈奏]
2、流程圖
四、設計總結(包括調試軟、硬件過程和體會、收獲)
附錄:
1. 仿真狀態(tài)圖
2. 程序清單

  1. #include <reg51.h>
  2. #include <absacc.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. uchar S=0,T=0;        
  8. uchar SH;      
  9. uchar SL;
  10. uchar k, key;
  11. bit flag=1;   
  12. sbit SPK=P3^0;
  13. uchar code DSY_CODE[]= {0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
  14. uchar code music[]= {8,9,10,8,8,9,10,8,10,11,12,10,11,12,-1};
  15. uchar code Len[]= {1,1,1,1,1,1,1,1,1,1,2,1,1,2,-1};
  16. uint code tab[]= { 64580,64684,64777,64820,64898,64968,65030,
  17.                      65058,65110,65157,65178,65217,65252,65283};  
  18. //延時
  19. void delay1(uint ms)
  20. { uchar t;
  21.         while(ms--)
  22.         for (t=0;t<120;t++); }

  23. /* 鍵消抖延時*/
  24.         void delay(void)
  25.         {  uchar i;
  26.                 for (i=300;i>0;i--); }

  27. /* 鍵掃描函數(shù) */
  28. uchar getkey()
  29.         {
  30.         uchar scode,tcode;
  31.                 if ((P2&0xf0)==0xf0)
  32.                 return(0);
  33.                         scode = 0xfe;
  34.                                  while((scode&0x10)!=0)  
  35.                                 {                     P2 = scode;
  36.                                         if ((P2&0xf0)!=0xf0)  
  37.                                                 {         
  38.                                                  tcode = (P2&0xf0)|0x0f;                                                                                                                   return((~scode)+(~tcode)); }
  39.                                         else scode = (scode<<=1)|0x01;         }
  40.           }
  41. void EX0_INT() interrupt 0
  42. {   flag=0;   }
  43. void time0_int(void) interrupt 1 using 0
  44. {  
  45.         TH0 = SH;
  46.         TL0 = SL;
  47.         SPK=!SPK;
  48.         P0=DSY_CODE[k] ;   }
  49. void main(void) {
  50.         P0=0x3f;
  51.         IE=0x87;
  52.         TMOD=0x01;
  53.         IT0=1;
  54.         IT1=1;
  55.                 while(1)
  56.                 {
  57.                          P2 = 0xf0;                                
  58.                                 if ((P2&0xf0)!=0xf0)  
  59.                                            delay();                       
  60.                                 if ((P2&0xf0)!=0xf0)   
  61.                                  {     key = getkey();  
  62.                                         switch(key)              
  63.                                         {
  64.                                                 case 0x11:k = 0;break;  // 按鍵1
  65.                                                 case 0x21:k = 1;break;  //         按鍵2                                       
  66.                                                 case 0x41:k = 2;break;  // 按鍵3                                                
  67.                                                 case 0x81:k = 3;break;  // 按鍵4                                                
  68.                                                 case 0x12:k = 4; break;     // 按鍵5                                                
  69.                                                 case 0x22:k = 5;break;      // 按鍵6                                                
  70.                                                 case 0x42:k = 6;break;      // 按鍵7                                                
  71.                                                 case 0x82:k = 7;break;      // 按鍵8                                                
  72.                                                 case 0x14:k = 8;break;      // 按鍵9                                                
  73.                                                 case 0x24:k = 9;break;      // 按鍵10                                       
  74.                                                 case 0x44:k = 10;break;      // 按鍵11                                       
  75.                                                 case 0x84:k = 11;break;      // 按鍵12                                       
  76.                                                 case 0x18:k = 12;break;      // 按鍵13                                       
  77.                                                 case 0x28:k = 13;break;      // 按鍵14                                       
  78.                                                 case 0x48:k = 14;break;      // 按鍵15                                       
  79.                                                 case 0x88:k = 15;break;      // 按鍵16                                       
  80.                                                 default:break;
  81.                                                 }
  82.                                                  if(flag==0) {                                                                                                                SH = tab[k]/256;
  83.                                                      SL = tab[k]%256;
  84.                                                          TR0 = 1;           
  85.                                                          while ((P2&0xf0)!=0xf0);  
  86.                                                          SPK=1;
  87.                                                          TR0 = 0;                                                                                      }
  88.                                                 else
  89.                                                   { while(flag==1)
  90.                                                         {               
  91.                                                                         if (music[T]==-1)T=0;
  92.                                                                         SH=(tab[music[T]])/256;


  93. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

完整課設論文下載(word格式 可編輯)http://www.torrancerestoration.com/bbs/dpj-86870-1.html





作者: ssp7812    時間: 2017-6-5 07:37
學習一下,頂一個,




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