<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 【C51】源碼 4 -- 喇叭播放【寒蟬鳴泣之時】插曲 You

          【C51】源碼 4 -- 喇叭播放【寒蟬鳴泣之時】插曲 You

          作者: 時間:2016-11-17 來源:網(wǎng)絡 收藏
          單片機到喇叭部分,覺得挺好玩,編寫了喇叭播放音樂的程序……

          BGM 取自【寒蟬鳴泣之時】插曲 You,簡譜由網(wǎng)絡提供,感謝作者……先把簡譜附上:

          本文引用地址:http://www.ex-cimer.com/article/201611/315360.htm

          還有一張自制的“鋼琴按鍵頻率分布”,沒寫那么全,只對應本程序,圖如下:

          附上源碼:(初出茅廬,難免有寫的不好的地方,僅作備份之用,歡迎指點,噴子退散……)

          /*******************************************************************
          喇叭播放音樂

          BGM 取自【寒蟬鳴泣之時】的插曲 You

          缺點:

          1、沒有添加調(diào)節(jié)音量的功能
          2、音高、節(jié)拍 都要自己提前寫好,工作量大
          可以改進成:通過解析 midi 文件進行音樂播放
          (midi 里邊就是音高、節(jié)拍信息)
          ********************************************************************/

          #include

          sbitSPK = P1^0;// 喇叭輸入

          /************************************************************************************************************************************
          PIANO_F[ ]:是鋼琴按鍵的頻率,數(shù)組下標對應鋼琴按鍵,如上圖所示
          例:圖上可以看出:8 號鍵對應鋼琴的中央 C,正好是 PIANO_F[8],對應頻率為 261.6 Hz
          注:PIANO_F[0] 不代表任何按鍵,為了方便計數(shù),數(shù)組下標從 1 開始有意義
          *************************************************************************************************************************************/

          float codePIANO_F[ ] = {7.63,
          130.8, 146.8, 164.8, 174.5, 196.0, 220.0, 247.1,
          261.6, 293.6, 329.6, 349.0, 392.0, 440.0, 494.0,
          523.2, 587.2, 659.2, 698.3, 784.0, 880.0, 988.0,
          1046.4, 1174.4, 1318.4, 1396.8, 1567.7, 1760.0, 1975.3};

          /******************************************************************************************************
          PITCH[ ]:指的是 音高,對應上圖中的按鍵號
          例:中音 do:如圖對應 8 號鍵
          高音 do:如圖對應 15 號鍵
          好處:假如歌曲播放到了第 i 個音,那么 PITCH[i] 就是對應鋼琴上的按鍵
          那么 PIANO_F[ PITCH[i] ] 就是對應的琴鍵的頻率,方便編程使用
          注:255 代表 音樂結束
          0 代表 八分休止符
          ******************************************************************************************************/

          unsigned char codePITCH[ ] = {16, 17, 16, 15, 16, 12, 17, 16, 15,
          16, 17, 16, 15, 15, 19, 16,
          16, 17, 16, 15, 16, 12, 17, 16, 15,
          16, 17, 16, 15, 15, 12,
          12, 10, 12, 15, 15,
          16, 16, 16, 17, 17, 12,
          12, 10, 12, 0, 15, 15, 16,
          16, 16, 16, 19, 17, 12,
          12, 10, 0, 12, 0, 15, 15, 15,
          16, 16, 16, 17, 17, 12,
          12, 10, 0, 12, 0, 15, 15, 16,
          16, 16, 16, 19, 17, 26,
          26, 24, 0, 26, 26, 22, 0, 23,
          23, 22, 23, 0, 24, 23, 24, 26,
          26, 24, 0, 26, 26, 22, 0, 23,
          23, 22, 0, 23, 22,
          255};

          /***************************************************************************************************************
          BEAT[ ]:指的是 節(jié)拍,數(shù)值代表基本節(jié)拍的倍數(shù),這里基本節(jié)拍為 十六分音符 長
          例:8,代表 8 倍 十六分音符 長,即:二分音符
          4,代表 4 倍 十六分音符 長,即:四分音符
          2,代表 2 倍 十六分音符 長,即:八分音符
          1,代表 1 倍 十六分音符 長,即:十六分音符
          6,代表 6 倍 十六分音符 長,即:符點四分音符
          ***************************************************************************************************************/

          unsigned char codeBEAT[ ] = {4, 1, 1, 2, 2, 2, 1, 1, 2, 4, 1, 1, 2, 2, 2, 4,
          4, 1, 1, 2, 2, 2, 1, 1, 2, 4, 1, 1, 2, 6, 2,
          2, 4, 2, 6, 2, 2, 2, 2, 2, 6, 2,
          2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2,
          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2,
          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2,
          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8,
          255};

          unsigned chartime_h = 0;// 用于向定時器中斷程序傳遞下一步定時信息
          unsigned chartime_l = 0;

          unsigned inttime = 0;// 根據(jù)按鍵頻率,換算出應該定時多長時間
          unsigned chari;

          voidInit_Timer0(void);// 初始化 定時器 0
          voidDelay(unsigned intt);// 普通延時
          voidDelay_ms(unsigned intt);// 相當近似的延遲 t ms

          voidmain (void)
          {
          Init_Timer0();

          for(i = 0; PITCH[i] != 255; i++) {// 順序播放,255 為音樂結束

          TR0 = 0;// 關 定時器0

          Delay_ms(20);// 延時一段時間,保證按鍵與按鍵之間能分得清楚

          /*********************************************************************************************************************
          定時時間 time 的計算:

          以 中央 C 為例:頻率為 261.6 Hz,就是每秒 261.6 下,倒數(shù)就是 每下 1/261.6 s,
          換成 us 就是 1,000,000/261.6,每響一次是一個上升沿加一個下降沿,
          因此,變換的次數(shù)應該是 2 倍,每次變換所花時間是一半,
          即:1,000,000/(2*261.6)
          **********************************************************************************************************************/

          time = (unsigned int)(1000000 / (2 * PIANO_F[PITCH[i]]));

          time_h = (65536 - time) / 256;
          time_l = (65536 - time) % 256;

          TH0 = time_h;// 定時器賦值
          TL0 = time_l;

          TR0 = 1;// 開 定時器0

          /****************************************************************************************************************
          如果音高是 0,說明是 八分休止符,關定時器,定時器不驅(qū)動喇叭,也就沒有聲音了
          ****************************************************************************************************************/

          if(PITCH[i] == 0) TR0 = 0;

          /********************************************************************************************************
          相當重要的延時!節(jié)拍全部由它控制,不是很精確,其實用 定時器 1 可能更好
          ********************************************************************************************************/

          Delay_ms(BEAT[i] * 30);
          }

          TR0 = 0;// 音樂播放完后,關定時器,收尾

          /*****************************************************************************************************************
          相當重要!沒有此語句將導致循環(huán)執(zhí)行 main 函數(shù)!

          詳細討論參見:http://gaebolg.blog.163.com/blog/static/19826906820122254823928/
          *****************************************************************************************************************/

          while(1);
          }

          voidInit_Timer0(void)
          {
          TMOD = 0x01;// 定時器 0,模式1
          EA = 1;// 開 總中斷
          ET0 = 1;// 開 定時器 0 中斷
          }

          voidTimer0_ISR(void)interrupt1
          {
          TH0 = time_h;// 重裝初值
          TL0 = time_l;

          SPK = !SPK;// 產(chǎn)生方波,驅(qū)動喇叭發(fā)聲
          }

          voidDelay(unsigned intt)
          {
          while(t--);
          }

          voidDelay_ms(unsigned intt)// 根據(jù)測試,可以相當近似的表示 t ms
          {
          while(t--) {
          Delay(245);
          Delay(245);
          }
          }



          關鍵詞: C51喇叭播

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();