找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1982|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

基于51單片機音樂播放器Proteus仿真源程序設(shè)計

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1106310 發(fā)表于 2023-12-25 20:02 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
原創(chuàng)作品,禁止轉(zhuǎn)載售賣,僅供學(xué)習(xí)參考。。
仿真目的和要求:
(1)  進一步熟悉定時/計數(shù)器的應(yīng)用
(2)  讓單片機放個音樂聽聽
項目內(nèi)容:
(1)  選定一首歌,下載歌譜,按照音調(diào)和節(jié)拍生成數(shù)據(jù)格式,用蜂鳴器播放。
(2)  按鍵定義鋼琴的鍵盤,按下按鍵可以發(fā)出不同的聲音,可以彈奏簡單的曲調(diào)。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)



單片機源程序如下:
  1. #include <REGX52.H>
  2. sbit beep = 0xA6;
  3. unsigned int num = 0;
  4. unsigned char number = 1;//歌曲序號
  5. unsigned char time = 0;//節(jié)拍時間,第三個數(shù)
  6. unsigned char fre_num ;
  7. unsigned char sign = 0;

  8. unsigned char flag = 1;

  9. //簡單愛
  10. unsigned char code music[]={
  11.     5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1,
  12.     4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1,
  13.     5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1,
  14.     3,2,1, 3,2,1, 1,2,1, 5,2,1, 1,2,1, 5,2,1, 1,2,1, 7,1,1, 1,2,1, 1,2,1, 6,1,1,
  15.     2,2,1, 2,2,1, 3,2,1, 3,2,1, 5,2,1, 5,2,1,
  16.     5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2,  
  17.     5,1,1, 1,2,1, 2,1,2, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1,
  18.     4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1,
  19.     5,2,1, 5,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1,
  20.     3,2,1, 3,2,1, 1,2,2, 5,2,1, 1,2,1, 5,2,1, 5,2,1, 7,1,1, 1,2,1, 0,0,0 };



  21. // 頻率-半周期數(shù)據(jù)表 高八位  共保存了四個八度的28個頻率數(shù)據(jù)
  22. unsigned char code NOTEH[]={
  23.     0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,    //低音1234567
  24.     0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
  25.     0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,            //高音 234567
  26.     0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};   //超高音 1234567

  27. // 頻率-半周期數(shù)據(jù)表 低八位
  28. unsigned char code NOTEL[]={
  29.     0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,    //低音1234567
  30.     0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
  31.     0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,             //高音 234567
  32.     0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};   //超高音 1234567

  33. void Delay(unsigned char t) //延時子函數(shù),控制發(fā)音的時間長度,每個節(jié)拍0.4S
  34. {
  35.     unsigned char t1;
  36.     unsigned long t2;
  37.     for (t1 = 0; t1 < t; t1++) //嵌套循環(huán), 共延時t個半拍
  38.     {
  39.         for (t2 = 0; t2 < 8000; t2++) //延時期間, 可進入T0中斷去發(fā)音
  40.         {
  41.             ;
  42.         }
  43.     }
  44.     TR0 = 0; //關(guān)閉T0, 停止發(fā)音
  45. }
  46. void Delay20ms()                //@11.0592MHz
  47. {
  48.         unsigned char i, j, k;

  49.         
  50.         i = 1;
  51.         j = 216;
  52.         k = 35;
  53.         do
  54.         {
  55.                 do
  56.                 {
  57.                         while (--k);
  58.                 } while (--j);
  59.         } while (--i);
  60. }

  61.         
  62. void ONE() //演奏一個音符
  63. {
  64.                 beep = !beep;
  65.     TH0 = NOTEH[fre_num];      
  66.     TL0 = NOTEL[fre_num];
  67.     TR0 = 1;     
  68.     Delay(time);
  69. }

  70. void PlayMusic() //播放相應(yīng)歌曲的某個音符
  71.         {
  72.                 if(sign == 1)
  73.                 {
  74.                 if ((number == 1) && (flag == 1))
  75.     {
  76.         fre_num = music[num] + 7 * music[num + 1] - 1; //第i個是音符,第i+1個是第幾個八度
  77.         time = music[num + 2]; //讀出時間長度數(shù)值
  78.         num += 3;
  79.         if (fre_num < 0)
  80.         {
  81.             num = 0;
  82.             number = 1;
  83.         }
  84.         ONE(); //發(fā)出一個音符
  85.         
  86.     }
  87.    
  88.    
  89.                 }
  90.                 sign = 0;
  91.                 beep = 1;
  92.    
  93.    
  94.         }        
  95.         unsigned char key_scan()
  96. {
  97.         unsigned char KeyNumber = 0;
  98.         
  99.         P1 = 0xff;
  100.         P1_0 = 0;
  101.         if(P1_4 == 0){Delay20ms();while(P1_4 == 0);KeyNumber = 1;}
  102.         if(P1_5 == 0){Delay20ms();while(P1_5 == 0);KeyNumber = 2;}
  103.         if(P1_6 == 0){Delay20ms();while(P1_6 == 0);KeyNumber = 3;}
  104.         if(P1_7 == 0){Delay20ms();while(P1_7 == 0);KeyNumber = 4;}
  105.         
  106.         P1 = 0xff;
  107.         P1_1 = 0;
  108.         if(P1_4 == 0){Delay20ms();while(P1_4 == 0);KeyNumber = 5;}
  109.         if(P1_5 == 0){Delay20ms();while(P1_5 == 0);KeyNumber = 6;}
  110.         if(P1_6 == 0){Delay20ms();while(P1_6 == 0);KeyNumber = 7;}
  111.         if(P1_7 == 0){Delay20ms();while(P1_7 == 0);KeyNumber = 8;}
  112.         
  113.         P1 = 0xff;
  114.         
  115.         return KeyNumber;
  116. }
  117. unsigned char ss ;
  118. void Key()
  119. {
  120.         
  121.         ss = key_scan();
  122.         if(ss == 1)
  123.                 {
  124.                                 beep = !beep;        
  125.                                 TH1 = NOTEH[8];
  126.                                 TL1 = NOTEL[8];
  127.                                 TR1 = 1;
  128.                                 Delay(1);
  129.                                 beep = 0;
  130.                         }        
  131.         if(ss == 2)
  132.                 {
  133.                                 beep = !beep;        
  134.                                 TH1 = NOTEH[9];
  135.                                 TL1 = NOTEL[9];
  136.                                 TR1 = 1;
  137.                                 Delay(1);
  138.                                 beep = 0;
  139.                         }               
  140.         if(ss == 3)
  141.         {
  142.                                 beep = !beep;        
  143.                                 TH1 = NOTEH[10];
  144.                                 TL1 = NOTEL[10];
  145.                                 TR1 = 1;
  146.                                 Delay(1);
  147.                                 beep = 0;
  148.                                 
  149.         }
  150.         if(ss == 4)
  151.         {
  152.                                 beep = !beep;        
  153.                                 TH1 = NOTEH[11];
  154.                                 TL1 = NOTEL[11];
  155.                                 TR1 = 1;
  156.                                 Delay(1);
  157.                                 beep = 0;
  158.                         }        
  159.         if(ss == 5)
  160.         {
  161.                 beep = !beep;        
  162.                                 TH1 = NOTEH[12];
  163.                                 TL1 = NOTEL[12];
  164.                                 TR1 = 1;
  165.                                 Delay(1);
  166.                                 beep = 0;
  167.         }
  168.         if(ss == 6)
  169.         {
  170.                         beep = !beep;        
  171.                                 TH1 = NOTEH[13];
  172.                                 TL1 = NOTEL[13];
  173.                                 TR1 = 1;
  174.                                 Delay(1);
  175.                                 beep = 0;
  176.         }
  177.         if(ss == 7)
  178.         {
  179.                 beep = !beep;        
  180.                                 TH1 = NOTEH[14];
  181.                                 TL1 = NOTEL[14];
  182.                                 TR1 = 1;
  183.                                 Delay(1);
  184.                                 beep = 0;
  185.                                 
  186.         }
  187.         
  188.         
  189. }

  190. void time0() interrupt 1
  191. {
  192.         if(sign == 1)
  193.                 {               
  194.                                 beep = !beep;         
  195.                                 TH0 = NOTEH[fre_num];  
  196.                                 TL0 = NOTEL[fre_num];
  197.                                 TR0 = 1;
  198.                                 
  199.                                                 
  200.                 }
  201. }
  202. void main()
  203. {
  204.         TMOD = 0x11;
  205.         ET0 = 1;
  206.         EA = 1;
  207.         beep = 1;
  208.         
  209.         while(1)
  210.         {
  211.                 PlayMusic();
  212.                 if(ss == 8)
  213.                 {
  214.                                 sign = 1;
  215.                 }
  216.                 else
  217.                         Key();
  218.         }
  219. }
復(fù)制代碼
程序有問題 求幫助: 音樂播放器.7z (142.61 KB, 下載次數(shù): 35)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:1106038 發(fā)表于 2023-12-28 20:06 | 只看該作者
哥們我用你這個試了下沒有效果啊
回復(fù)

使用道具 舉報

板凳
ID:1106157 發(fā)表于 2023-12-29 00:55 | 只看該作者
czbj666 發(fā)表于 2023-12-28 20:06
哥們我用你這個試了下沒有效果啊

是部分代碼,我前面沒注意弄了好幾次都不行后面才看到
回復(fù)

使用道具 舉報

地板
ID:1130903 發(fā)表于 2024-8-25 12:41 | 只看該作者
老哥,這個跟著做可以復(fù)現(xiàn)嘛,那個壓縮包是教程麻
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表