找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19136|回复: 8
打印 上一主题 下一主题
收起左侧

一个小巧的单片机音乐程序 内附几首歌代码

  [复制链接]
跳转到指定楼层
楼主
ID:396772 发表于 2018-9-13 17:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学校要求做的课程设计 也查了很多资料 有需要的可以了解一下

单片机源程序如下:
  1.                                                                                                                                  //51单片机播放音乐库文件
  2. ///51单片机播放音乐库文件
  3. /**************************************************************************
  4.    
  5.                                              SOUND PLAY FOR 51MCU
  6.   
  7.                                COPYRIGHT (c)   2005 BY JJJ.
  8.                                        --  ALL RIGHTS RESERVED  --
  9.   
  10.    File Name:       SoundPlay.h
  11.    Author:          Jiang Jian Jun
  12.    Created:         2005/5/16
  13.    Modified:                NO
  14.    Revision:                 1.0
  15.   
  16. *******************************************************************************/

  17. /*说明**************************************************************************
  18. 曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0};        末尾:0,0 表示结束(Important)

  19. 音高由三位数字组成:
  20.                 个位是表示 1~7 这七个音符
  21.                 十位是表示音符所在的音区:1-低音,2-中音,3-高音;
  22.                 百位表示这个音符是否要升半音: 0-不升,1-升半音。

  23. 音长最多由三位数字组成:
  24.                 个位表示音符的时值,其对应关系是:
  25.                         |数值(n):  |0 |1 |2 |3 | 4 | 5 | 6
  26.                         |几分音符: |1 |2 |4 |8 |16 |32 |64                 音符=2^n
  27.                 十位表示音符的演奏效果(0-2):  0-普通,1-连音,2-顿音
  28.                 百位是符点位: 0-无符点,1-有符点

  29. 调用演奏子程序的格式
  30.                 Play(乐曲名,调号,升降八度,演奏速度);
  31.         |乐曲名           : 要播放的乐曲指针,结尾以(0,0)结束;
  32.         |调号(0-11)       :        是指乐曲升多少个半音演奏;
  33.         |升降八度(1-3)          : 1:降八度, 2:不升不降, 3:升八度;
  34.         |演奏速度(1-12000):        值越大速度越快;

  35. ***************************************************************************/
  36. #ifndef __SOUNDPLAY_H_REVISION_FIRST__
  37. #define __SOUNDPLAY_H_REVISION_FIRST__

  38. #include <REGX51.H>

  39. //**************************************************************************

  40. #define SYSTEM_OSC                 11059200//12000000        //定义晶振频率12000000HZ
  41. #define SOUND_SPACE         4/5                 //定义普通音符演奏的长度分率,//每4分音符间隔
  42. sbit    BeepIO    =           P1^0;                //定义输出管脚

  43. unsigned int  code FreTab[12]  = { 212, 222, 232, 242, 252,
  44.                                   262, 272, 312, 322, 332,
  45.                                   342, 352 }; //原始频率表
  46. unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };                                                                   //1~7在频率表中的位置
  47. unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };                                               
  48. unsigned char Sound_Temp_TH0,Sound_Temp_TL0;        //音符定时器初值暂存
  49. unsigned char Sound_Temp_TH1,Sound_Temp_TL1;        //音长定时器初值暂存
  50. //**************************************************************************
  51. void InitialSound(void)
  52. {
  53.         BeepIO = 1;
  54.         Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;        // 计算TL1应装入的初值         (10ms的初装值)
  55.         Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;        // 计算TH1应装入的初值
  56.         TH1 = Sound_Temp_TH1;
  57.         TL1 = Sound_Temp_TL1;
  58.         TMOD  |= 0x11;
  59.         ET0    = 1;
  60.         ET1           = 0;
  61.         TR0           = 0;
  62.         TR1    = 0;
  63.         EA     = 1;
  64. }

  65. void BeepTimer0(void) interrupt 1        //音符发生中断
  66. {
  67.         BeepIO = !BeepIO;
  68.         TH0    = Sound_Temp_TH0;
  69.         TL0    = Sound_Temp_TL0;
  70. }
  71. //**************************************************************************
  72. void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
  73. {
  74.         unsigned int NewFreTab[12];                //新的频率表
  75.         unsigned char i,j;
  76.         unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
  77.         unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
  78.         for(i=0;i<12;i++)                                 // 根据调号及升降八度来生成新的频率表
  79.         {
  80.                 j = i + Signature;
  81.                 if(j > 11)
  82.                 {
  83.                         j = j-12;
  84.                         NewFreTab[i] = FreTab[j]*2;
  85.                 }
  86.                 else
  87.                         NewFreTab[i] = FreTab[j];

  88.                 if(Octachord == 1)
  89.                         NewFreTab[i]>>=2;
  90.                 else if(Octachord == 3)
  91.                         NewFreTab[i]<<=2;
  92.         }                                                                       
  93.        
  94.         SoundLength = 0;
  95.         while(Sound[SoundLength] != 0x00)        //计算歌曲长度
  96.         {
  97.                 SoundLength+=2;
  98.         }

  99.         Point = 0;
  100.         Tone   = Sound[Point];       
  101.         Length = Sound[Point+1];                         // 读出第一个音符和它时时值
  102.        
  103.         LDiv0 = 12000/Speed;                                // 算出1分音符的长度(几个10ms)        
  104.         LDiv4 = LDiv0/4;                                         // 算出4分音符的长度
  105.         LDiv4 = LDiv4-LDiv4*SOUND_SPACE;         // 普通音最长间隔标准
  106.         TR0          = 0;
  107.         TR1   = 1;
  108.         while(Point < SoundLength)
  109.         {
  110.                 SL=Tone%10;                                                                 //计算出音符
  111.                 SM=Tone/10%10;                                                                 //计算出高低音
  112.                 SH=Tone/100;                                                                 //计算出是否升半
  113.                 CurrentFre = NewFreTab[SignTab[SL-1]+SH];         //查出对应音符的频率        
  114.                 if(SL!=0)
  115.                 {
  116.                         if (SM==1) CurrentFre >>= 2;                 //低音
  117.                         if (SM==3) CurrentFre <<= 2;                 //高音
  118.                         Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
  119.                         Sound_Temp_TH0 = Temp_T/256;
  120.                         Sound_Temp_TL0 = Temp_T%256;
  121.                         TH0 = Sound_Temp_TH0;  
  122.                         TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿
  123.                 }
  124.                 SLen=LengthTab[Length%10];         //算出是几分音符
  125.                 XG=Length/10%10;                         //算出音符类型(0普通1连音2顿音)
  126.                 FD=Length/100;
  127.                 LDiv=LDiv0/SLen;                         //算出连音音符演奏的长度(多少个10ms)
  128.                 if (FD==1)
  129.                         LDiv=LDiv+LDiv/2;
  130.                 if(XG!=1)       
  131.                         if(XG==0)                                 //算出普通音符的演奏长度
  132.                                 if (SLen<=4)       
  133.                                         LDiv1=LDiv-LDiv4;
  134.                                 else
  135.                                         LDiv1=LDiv*SOUND_SPACE;
  136.                         else
  137.                                 LDiv1=LDiv/2;                 //算出顿音的演奏长度
  138.                 else
  139.                         LDiv1=LDiv;
  140.                 if(SL==0) LDiv1=0;
  141.                         LDiv2=LDiv-LDiv1;                 //算出不发音的长度
  142.                   if (SL!=0)
  143.                 {
  144.                         TR0=1;
  145.                         for(i=LDiv1;i>0;i--)         //发规定长度的音
  146.                         {
  147.                                 while(TF1==0);
  148.                                 TH1 = Sound_Temp_TH1;
  149.                                 TL1 = Sound_Temp_TL1;
  150.                                 TF1=0;
  151.                         }
  152.                 }
  153.                 if(LDiv2!=0)
  154.                 {
  155.                         TR0=0; BeepIO=1;
  156.                         for(i=LDiv2;i>0;i--)         //音符间的间隔
  157.                         {
  158.                                 while(TF1==0);
  159.                                 TH1 = Sound_Temp_TH1;
  160.                                 TL1 = Sound_Temp_TL1;
  161.                                 TF1=0;
  162.                         }
  163.                 }
  164.                 Point+=2;
  165.                 Tone=Sound[Point];
  166.                 Length=Sound[Point+1];
  167.         }
  168.         BeepIO = 1;
  169. }
  170. //**************************************************************************
  171. //#endif

  172. /***************************************************************************
  173. 附:3首曲谱编码表

  174. //挥着翅膀的女孩
  175. unsigned char code Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,
  176.                                   0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,
  177.                                   0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,
  178.                                   0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,
  179.                                   0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,
  180.                                   0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,
  181.                                   0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,
  182.                                   0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,
  183.                                   0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,
  184.                                   0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,
  185.                                   0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
  186.                                   0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
  187.                                   0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
  188.                                   0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03,
  189.                                   0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,
  190.                                   0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
  191.                                   0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
  192.                                   0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
  193.                                   0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
  194.                                   0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,
  195.                                   0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,
  196.                                   0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,
  197.                                   0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,
  198.                                   0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,
  199.                                   0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,
  200.                                   0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,
  201.                                   0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,
  202.                                   0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
  203.                                   0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04,
  204.                                   0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
  205.                                   0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,
  206.                                   0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,
  207.                                   0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
  208.                                   0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02,
  209.                                   0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,
  210.                                   0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};
  211. //同一首歌
  212. unsigned char code Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,
  213.                                   0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,
  214.                                   0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,
  215.                                   0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,
  216.                                   0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,
  217.                                   0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,
  218.                                   0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,
  219.                                   0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,
  220.                                   0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,
  221.                                   0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,
  222.                                   0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,
  223.                                   0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,
  224.                                   0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,
  225.                                   0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,
  226.                                   0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,
  227.                                   0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,
  228.                                   0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,
  229.                                   0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,
  230.                                   0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,
  231.                                   0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,
  232.                                   0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,
  233.                                   0x00,0x00 };
  234. //两只蝴蝶                                 
  235. unsigned char code Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
  236.                                   0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
  237.                                   0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
  238.                                   0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,
  239. ……………………

  240. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
音乐程序.rar (641.6 KB, 下载次数: 157)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:429208 发表于 2019-2-3 14:08 | 只看该作者
信息分享
回复

使用道具 举报

板凳
ID:497951 发表于 2019-4-17 19:05 来自手机 | 只看该作者
感谢分享,学习了?
回复

使用道具 举报

地板
ID:536351 发表于 2019-5-12 18:56 | 只看该作者
感谢分享 学到了
回复

使用道具 举报

5#
ID:71883 发表于 2019-6-29 13:46 | 只看该作者
编译不通过
回复

使用道具 举报

6#
ID:613854 发表于 2019-12-17 15:33 | 只看该作者
感恩                  
回复

使用道具 举报

7#
ID:689551 发表于 2020-2-2 20:55 | 只看该作者
怎么我的编译不通过??
回复

使用道具 举报

8#
ID:701390 发表于 2020-3-2 20:49 | 只看该作者
不会调用
回复

使用道具 举报

9#
ID:90566 发表于 2020-5-15 10:34 | 只看该作者
这个得调用两个定时器呀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表