找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机音乐盒程序图和与源代码

[复制链接]
跳转到指定楼层
楼主

单片机源程序如下:
  1. #include <reg51.h>                 //头文件        
  2. #define uchar unsigned char
  3. #define uint unsigned int          //宏定义
  4. uchar STH0;                                  //定时器变量
  5. uchar STL0;                                  //定时器变量
  6. bit FY=0;                                         //模式变量,为0时弹奏模式,为1时播放模式
  7. uchar Song_Index=0,Tone_Index=0;//单首歌曲音符数  
  8. uchar k, key;                                         //k:按键数值变量。key:按键的键值(也就是有按键按下时的P0口状态)
  9. sbit SPK=P3^7 ;                                 //定义喇叭的接口
  10. sbit LED1=P3^5;
  11. sbit LED2=P3^4;                                 //定义两个LED的接口
  12. uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,//数码管显示的数组(1 2 3 4 5 6 7 8 9)
  13.                                                 0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xa3,0x8c,0xc8};        //(A B C D E F H O P N)
  14. unsigned char code num1[]=                        "   Music:       ";
  15. uchar code Song[][100]=         //内置音乐数组,song【歌曲序号】【音符顺序】
  16. {
  17.         //        1        2        3        4        5        6        7
  18.         //        8        9        10        11        12        13        14
  19.         //        15        16        17        18        19        20        21

  20.         {12,10,9,9,10,8,9,10,
  21.         12,10,9,9,5,10,11,10,
  22.         10,10,14,10,9,8,7,8,
  23.         9,10,13,6,8,10,9,6,
  24.         8,7,5,6,12,10,9,9,
  25.         9,10,8,9,10,12,10,9,
  26.         9,9,5,10,11,10,10,10,
  27.         14,10,9,8,7,8,9,10,
  28.         13,6,8,10,9,6,8,7,
  29.         5,6,-1},                                 //烟花易冷

  30.         {13,12,10,12,15,13,
  31.         12,13,10,12,13,12,10,8,6,12,
  32.         10,9,9,10,12,12,13,10,9,
  33.         8,12,10,9,8,6,8,5,-1},//世上只有妈妈好

  34.         {10,10,11,10,9,8,9,12,9,9,
  35.         8,8,9,8,7,6,7,10,7,7,
  36.         6,9,10,9,8,6,5,9,10,9,
  37.         8,6,6,9,10,9,8,6,7,8,-1}, //当你孤单你会想起谁

  38.         {5,3,5,8,6,8,
  39.         5,5,1,2,3,2,1,2,5,
  40.         3,5,8,7,6,8,5,5,2,
  41.         3,4,0,1,6,8,8,7,6,
  42.         7,8,6,7,8,6,6,5,3,
  43.         1,2,5,3,5,8,7,6,8,
  44.         5,5,2,3,4,0,1,-1},                 //送别

  45.         {5,6,8,6,6,5,6,5,3,5,
  46.         5,6,8,6,6,5,6,5,6,1,
  47.         1,2,3,2,2,2,1,2,1,6,
  48.         3,2,5,6,8,6,6,5,6,5,
  49.         6,1,1,2,3,4,4,5,6,6,
  50.         5,6,8,6,8,6,5,5,1,6,
  51.         5,5,6,8,3,2,3,1,-1},           //最浪漫的事

  52.         {5,9,10,9,10,12,13,12,8,9,
  53.         10,13,12,10,12,12,13,15,13,12,
  54.         10,12,10,8,9,10,8,6,10,9,
  55.         12,9,10,9,10,12,13,12,8,9,
  56.         10,13,12,12,13,15,13,
  57.         12,10,12,10,8,6,10,9,8,6,
  58.         8,9,9,8,-1},                                //发如雪

  59.         {5,8,9,10,9,10,11,12,12,12,
  60.         11,10,9,5,8,9,10,11,12,12,
  61.         12,13,12,9,10,8,8,6,9,9,
  62.         10,10,8,12,8,12,8,7,8,8,6,
  63.         9,9,10,10,12,12,
  64.         12,13,12,9,10,8,
  65.         5,8,9,10,9,10,11,12,12,12,
  66.         11,10,9,5,8,9,10,9,10,11,
  67.         12,12,12,9,10,8,8,6,9,9,
  68.         10,10,8,12,8,12,12,7,8,-1},        //简单爱

  69.         {8,9,10,8,8,9,10,8,10,11,12,10,11,12,
  70.         12,13,12,11,10,8,12,13,12,11,10,8,8,5,8,8,5,8,-1},        //两只老虎

  71.         {5,5,6,5,8,7,
  72.         5,5,6,5,9,8,
  73.         5,5,12,10,8,7,6,
  74.         11,11,10,8,9,8,-1},                        //生日快乐

  75.         {6,8,9,10,12,10,8,9,6,8,9,10,
  76.         12,12,13,9,10,10,12,13,
  77.         12,13,15,14,13,12,13,10,8,9,10,12,8,6,
  78.         8,9,10,13,12,10,13,13,
  79.         12,11,10,9,10,12,6,8,9,8,9,
  80.         10,12,13,15,14,13,12,10,13,-1},        //让我们荡起双桨

  81.         {8,8,12,12,13,13,12,
  82.         11,11,10,10,9,9,8,
  83.         12,12,11,11,10,10,9,
  84.         12,12,11,11,10,10,9,
  85.         8,8,12,12,13,13,12,
  86.         11,11,10,10,9,9,8,-1},                        //小星星

  87.         {12,10,12,10,12,10,8,9,11,10,9,12,
  88.         12,10,12,10,12,10,8,9,11,10,9,8,
  89.         9,9,11,11,10,8,12,9,11,10,9,12,
  90.         12,10,12,10,12,10,8,9,11,10,9,8,-1}, //粉刷匠

  91.         {8,9,10,11,12,12,12,11,10,
  92.         11,11,11,10,9,8,10,12,
  93.         8,9,10,11,12,12,12,11,10,
  94.         11,11,11,10,9,8,10,8,
  95.         13,13,13,12,11,12,12,12,11,10,
  96.         11,11,11,10,9,8,10,12,
  97.         13,13,13,12,11,12,12,12,11,10,
  98.         11,11,11,10,9,8,10,8,-1},                        //洋娃娃和小熊跳舞

  99.         {12,10,12,13,15,16,17,16,15,13,12,15,
  100.         17,16,15,12,17,16,15,12,
  101.         10,12,13,15,16,17,15,13,15,16,
  102.         13,13,14,13,13,17,15,14,15,13,
  103.         12,10,12,13,15,16,17,16,15,13,12,15,
  104.         17,17,17,17,15,16,16,16,16,12,
  105.         12,10,12,13,15,16,17,16,15,13,12,
  106.         15,15,-1},                                                           //小红花

  107.         {8,9,10,11,12,10,8,15,13,11,12,12,10,
  108.         8,9,10,11,12,10,9,8,9,10,9,12,
  109.         8,9,10,11,12,10,8,15,13,11,12,10,
  110.         8,9,10,11,12,10,9,8,9,10,8,8,
  111.         15,13,11,12,12,8,15,13,11,12,10,
  112.         8,9,10,11,12,10,9,8,9,10,8,8,
  113.         15,13,11,12,12,8,15,13,11,12,10,
  114.         8,9,10,11,12,10,9,8,9,10,8,8,-1},        //小红帽

  115.         {10,12,16,15,12,11,10,10,10,11,12,
  116.         13,12,10,12,16,15,12,11,
  117.         10,12,12,13,14,15,15,16,12,12,14,13,12,
  118.         10,12,15,13,15,16,15,14,12,10,12,
  119.         16,15,12,11,10,12,12,13,14,15,15,-1},        //雪绒花
  120. };
  121. uchar code Len[][100]= //内置音乐对应的节拍(音符持续时间)
  122. {
  123.         {1,1,2,4,1,1,1,4,
  124.         1,1,2,2,1,1,1,4,
  125.         1,1,1,1,2,1,1,1,
  126.         1,1,3,1,1,1,1,1,
  127.         1,1,1,6,1,1,2,1,
  128.         1,1,1,1,4,1,1,2,
  129.         1,1,1,1,1,4,1,1,
  130. 3,1,2,1,1,3,1,2,1,1,1,1,1,
  131.         3,1,1,1,1,1,1,2,
  132.         2,6,-1},

  133.         {3,1,2,2,2,1,
  134.         1,4,2,1,1,2,2,1,1,1,
  135.         1,4,3,1,2,1,1,2,2,
  136.         4,3,1,1,1,1,1,6,-1},

  137.         {2,1,1,2,1,1,2,2,2,3,
  138.         2,1,1,2,1,1,2,2,2,3,
  139.         2,1,1,1,1,2,2,1,1,1,
  140.         1,2,2,1,1,1,1,1,1,6,-1},

  141.         {2,3,1,3,2,2,
  142.         4,2,1,1,2,1,1,4,2,
  143.         1,1,2,1,2,2,4,2,1,
  144.         1,2,1,4,2,2,4,2,1,
  145.         1,4,1,1,1,1,1,1,1,
  146.         1,8,2,1,1,2,1,2,2,
  147.         4,2,1,1,2,2,4,-1},

  148.         {1,1,1,2,1,1,1,1,1,5,
  149.         1,1,1,2,1,1,1,1,1,5,
  150.         1,1,1,1,1,1,1,1,1,1,
  151.         2,3,1,1,1,2,1,1,1,1,
  152.         1,5,1,1,1,2,1,1,1,1,
  153.         1,2,1,3,1,1,1,4,1,1,
  154.         5,1,1,1,1,1,1,6,-1},

  155.         {1,1,2,1,1,1,1,3,1,1,
  156.         1,1,1,1,3,1,1,2,1,1,
  157.         1,1,2,1,1,1,1,1,1,1,
  158.         1,1,2,1,1,1,1,3,1,1,
  159.         1,1,3,1,1,2,1,
  160.         1,1,1,2,1,1,1,1,1,1,
  161.         1,1,1,4,-1},

  162.         {1,1,1,1,1,1,1,1,1,1,
  163.         1,1,3,1,1,1,1,1,1,1,
  164.         1,1,2,1,1,2,1,1,1,1,
  165.         1,1,1,1,1,1,1,1,1,1,1,
  166.         1,1,1,1,1,1,
  167.         1,1,2,1,1,2,
  168.         1,1,2,1,1,1,1,1,1,1,
  169.         1,1,3,1,1,1,1,1,1,1,
  170.         1,1,2,1,1,2,1,1,1,1,
  171.         1,1,2,1,1,1,1,1,1,-1},

  172.         {2,2,2,2,2,2,2,2,2,2,4,2,2,4,
  173.         1,1,1,1,2,2,1,1,1,1,2,2,2,2,4,2,2,4,-1},

  174.         {1,1,2,2,2,4,
  175.         1,1,2,2,2,4,
  176.         1,1,2,2,2,2,2,
  177.         1,1,2,2,2,4,-1},

  178.         {1,1,1,3,1,1,1,2,4,1,1,1,
  179.         3,1,2,2,4,1,1,4,
  180.         3,1,1,1,1,1,1,2,1,1,3,1,2,2,
  181.         1,1,1,1,5,4,3,1,
  182.         1,1,2,4,3,1,1,1,3,1,1,
  183.         2,2,2,2,1,1,1,1,4,-1},

  184.         {2,2,2,2,2,2,3,
  185.         2,2,2,2,2,2,3,
  186.         2,2,2,2,2,2,3,
  187.         2,2,2,2,2,2,3,
  188.         2,2,2,2,2,2,3,
  189.         2,2,2,2,2,2,4,-1},

  190.         {1,1,1,1,1,1,2,1,1,1,1,2,
  191.         1,1,1,1,1,1,2,1,1,1,1,2,
  192.         1,1,1,1,1,1,2,1,1,1,1,2,
  193.         1,1,1,1,1,1,2,1,1,1,1,3,-1},

  194.         {1,1,1,1,1,1,1,1,1,
  195.         1,1,1,1,1,1,1,2,
  196.         1,1,1,1,1,1,1,1,1,
  197.         1,1,1,1,1,1,1,2,
  198.         1,1,1,1,1,1,1,1,1,2,
  199.         1,1,1,1,1,1,1,2,
  200.         1,1,1,1,1,1,1,1,1,1,
  201.         1,1,1,1,1,1,1,3,-1},

  202.         {1,1,1,1,1,1,2,1,1,1,1,4,
  203.         2,1,1,4,2,1,1,4,
  204.         2,1,1,2,2,1,1,1,1,4,
  205.         2,1,1,3,1,1,1,1,1,4,
  206.         1,1,1,1,1,1,2,1,1,1,1,4,
  207.         1,1,1,1,4,1,1,1,1,4,
  208.         1,1,1,1,1,1,2,1,1,1,1,
  209.         4,4,-1},

  210.         {1,1,1,1,2,1,1,2,1,1,1,1,2,
  211.         1,1,1,1,1,1,1,1,2,2,2,2,
  212.         1,1,1,1,2,1,1,2,1,1,2,2,
  213.         1,1,1,1,1,1,1,1,2,2,2,2,
  214.         2,1,1,1,1,2,2,1,1,2,2,
  215.         1,1,1,1,1,1,1,1,2,2,2,2,
  216.         2,1,1,1,1,2,2,1,1,2,2,
  217.         1,1,1,1,1,1,1,1,2,2,2,2,-1},

  218.         {2,2,4,2,2,4,2,2,1,1,2,
  219.         4,4,2,2,4,2,2,4,
  220.         2,2,1,1,2,4,4,4,1,2,1,1,2,
  221.         2,2,4,2,2,2,2,4,4,2,2,
  222.         4,2,2,4,2,2,1,1,1,4,4,-1}
  223. };
  224. uint code tab[]={         //内置16个音符弹奏和播放时都是调用此数组内的数据用于定时器初值
  225.         63500,                                                                                 //超低音 si
  226.         63628,63835,64021,64103,64260,64400,64524,          //低音do-si
  227.         64580,64684,64777,64820,64898,64968,65030,          //           do-si
  228.         65058,65110,65157,65178,65217,65252,65283,         //高音do-si
  229.         65313 };                                                                         //超高音do

  230. void delay1 (uint ms)      //粗略1ms延时函数,不精确  
  231. {
  232.         uchar t;
  233.         while (ms--)
  234.         for(t=0;t<120;t++);
  235. }
  236. void delay(void)
  237. {
  238.         uchar i;
  239.         for (i=300;i>0;i--);
  240. }
  241. uchar getkey(void)                                  //矩阵按键扫描函数
  242. {
  243.         uchar scancode,tmpcode;
  244.         if((P1&0xf0)==0xf0)                         //无按键按下时此表达式成立
  245.         return (0);                                         //此函数返回值为0
  246.         scancode = 0xfe;                          //如果上面的if表达式不成立,此语句才可以执行
  247.         while((scancode&0x10)!=0)    //有按键按下时,此表达式成立
  248.         {                                                
  249.                 P1=scancode;                           //将P0口赋值
  250.                 if((P1&0xf0)!=0xf0)           //判断P0口的状态
  251.                 {
  252.                         tmpcode = (P1&0xf0)|0x0f;                 //P0口的状态与上0xf0,然后或上0x0f
  253.                         return((~scancode)+(~tmpcode));         //将两个变量的值取反相加后返回此函数
  254.                 }
  255.                 else scancode=(scancode<<1)|0x01;           //如果上面的if语句不成立,将scancode左移一位
  256.         }
  257.         return(0xff);
  258. }

  259. void anjian()                                 //按键键值识别
  260. {   
  261.         P1=0xf0;                                 //P1口赋值
  262.         if((P1&0xf0)!=0xf0)            //判断是否有按键按下
  263.         {
  264.                 delay();                      //去抖
  265.                 if((P1&0xf0)!=0xf0)  //再次判断有无按键按下  
  266.                 {
  267.                         key=getkey();         //扫描按键
  268.                         Tone_Index=0;    //播放音符顺序清零
  269.                         switch(key)            //根据扫描的按键编码将k赋值
  270.                         {
  271.                                 case 0x88:         //按键编码为0x88
  272. k = 0; //k赋值0k = 0;                 //k赋值0
  273.                                 break;                  //已经确定键值后提前跳出switch
  274.                                 case 0x48:   //如果不满足上一个case则继续向下判断,直到有符合
  275.                                 k = 1;                  //k赋值1
  276.                                 break;       //下同,略         
  277.                                 case 0x28:   
  278.                                 k = 2 ;
  279.                                 break;  
  280.                                 case 0x18:   
  281.                                 k = 3 ;
  282.                                 break;  
  283.                                 case 0x84:   
  284.                                 k = 4 ;
  285.                                 break;
  286.                                 case 0x44:   
  287.                                 k = 5 ;
  288.                                 break;
  289.                                 case 0x24:   
  290.                                 k = 6 ;
  291.                                 break;
  292.                                 case 0x14:   
  293.                                 k = 7 ;
  294.                                 break;
  295.                                 case 0x82:   
  296.                                 k = 8 ;
  297.                                 break;
  298.                                 case 0x42:   
  299.                                 k = 9 ;
  300.                                 break;
  301.                                 case 0x22:   
  302.                                 k = 10 ;
  303.                                 break;
  304.                                 case 0x12:   
  305.                                 k = 11 ;
  306.                                 break;
  307.                                 case 0x81:   
  308.                                 k = 12 ;
  309.                                 break;
  310.                                 case 0x41:   
  311.                                 k = 13 ;
  312.                                 break;
  313.                                 case 0x21:   
  314.                                 k = 14 ;
  315.                                 break;
  316.                                 case 0x11:   
  317.                                 k = 15 ;
  318.                                 break;
  319.                                 default :                 //如果以上都不符合,直接跳出,无键值输出
  320.                                 break;
  321.                         }
  322.                 }
  323.         }
  324. }

  325. void main(void)                                                   //主函数
  326. {
  327.         SPK=0;
  328.         LED1=1;                                                           
  329.         LED2=0;                                                    //开机默认弹奏模式
  330.         P0=0xc0;                                                   //数码管显示0
  331.         IE=0x87;                                                   //定义外部中断控制器
  332.         TMOD=0x01;                                                   //定义定时器0的工作方式
  333.         IT0=1;                                                           //外部中断0为下降沿触发
  334.         IT1=1;                                                           //外部中断1为下降沿触发
  335.         while(1)                                                   //进入死循环
  336.         {
  337.                 P1=0xf0;                                            //P1口赋值
  338.                 if((P1&0xf0)!=0xf0)                           //判断P0口是否有变化
  339.                 {        
  340. anjian(); //读取键值anjian();                                   //读取键值
  341.                         P0=DSY_CODE[k];                           //显示键值,也就是显示音符
  342.                         if(FY==0)                                   //如果是弹奏模式
  343.                         {
  344.                                 STH0 = tab[k]/256;
  345.                                 STL0 = tab[k]%256;           //根据k的值赋初值给T0
  346.                                 TR0 = 1;               //打开定时器用于定时产生频率发生     
  347.                                 while ((P1&0xf0)!=0xf0); //按键不松开的话,T0就一直产生频率
  348.                                 TR0=0;                 //按键松开后关闭T0计时,频率停止
  349.                         }
  350.                         else  //如果是播放模式(上面的if语句不成立就执行else)
  351.                         {
  352.                                 while (FY==1)                                                          //进入播放模式
  353.                                 {
  354.                                         if(Song[k][Tone_Index]==-1)                  //一首播放完退出
  355.                                         {
  356.                                                 Tone_Index=0;
  357.                                                 SPK=0;
  358.                                                 break;
  359.                                         }  
  360.                                         STH0=(tab[Song[k][Tone_Index]])/256;
  361.                                         STL0=(tab[Song[k][Tone_Index]])%256; //将内置音乐数组的数据赋给定时器做为初值计时
  362.                                 //        P0=DSY_CODE[Song[k][Tone_Index]];          //显示播放的音符
  363.                                         TR0 = 1;                                                          //打开定时器定时开关
  364.                                         delay1(300*Len[k][Tone_Index]);          //节拍数组延时
  365.                                         Tone_Index++;                                                  //变量加准备播放下一个音符
  366.                                         TR0=0;                                                                 //停止定时器
  367.                                         anjian();                                                         //扫描按键
  368.                                         P0=DSY_CODE[k];                                                 //显示音乐序号
  369.                                         while((P1&0xf0)!=0xf0);
  370.                                 }
  371.                         }
  372.                 }
  373.         }
  374. }

  375. void EXO_IXT() interrupt 0                  //外部中断0
  376. {
  377.         FY=0;                                                  //弹奏模式
  378.         LED1=1;
  379.         LED2=0;                                                  //点亮弹奏模式指示灯
  380.         Tone_Index=0;                                  //歌曲音符序号清零,以便于下次播放内置音乐时从头播放
  381. }
  382. void EX1_INT() interrupt 2                  //外部中断1
  383. {
  384.         FY=1;                                                  //播放模式
  385.         LED1=0;                                                  //点亮播放模式指示灯
  386.         LED2=1;
  387. }
  388. void time0_int(void) interrupt 1 using 0   //定时器0
  389. {      
  390.         TH0 = STH0;                                   //定时器赋初值
  391.         TL0 = STL0;
  392.         SPK=!SPK;                             //喇叭引脚取反,产生频率的音乐
  393. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:895633 发表于 2021-3-25 08:09 | 只看该作者
需要什么实物  能说一下吗 楼主 我想做出来
回复

使用道具 举报

板凳
ID:889344 发表于 2021-3-25 21:01 | 只看该作者
517538964 发表于 2021-3-25 08:09
需要什么实物  能说一下吗 楼主 我想做出来

仿真图上都有标注的
回复

使用道具 举报

地板
ID:896316 发表于 2021-3-26 19:45 | 只看该作者
517538964 发表于 2021-3-25 08:09
需要什么实物  能说一下吗 楼主 我想做出来

名称        数量(个)        型号        备注
电阻        3               
数码管        1        7SEG-DIGITAL       
开关        3                BUTTON
单片机        1        AT89C51       
三极管        3        2N3906       
扬声器        1                SPEAKER
电源        2                5V
电容        3                22pf(2个)
晶振        1                CRYSTAL
译码器        1        74LS138       
地址锁存器        1        74LS373       
七路反向器        1        ULN2003A       
三态反向八D锁存器        1        74LS374       
回复

使用道具 举报

5#
ID:896316 发表于 2021-3-26 19:46 | 只看该作者
而通过的 发表于 2021-3-25 21:01
仿真图上都有标注的

名称        数量(个)        型号        备注
电阻        3               
数码管        1        7SEG-DIGITAL       
开关        3                BUTTON
单片机        1        AT89C51       
三极管        3        2N3906       
扬声器        1                SPEAKER
电源        2                5V
电容        3                22pf(2个)
晶振        1                CRYSTAL
译码器        1        74LS138       
地址锁存器        1        74LS373       
七路反向器        1        ULN2003A       
三态反向八D锁存器        1        74LS374       
这是我自己在百度搜的,不知道可以不可以,错了请指教
回复

使用道具 举报

6#
ID:895633 发表于 2021-3-27 00:57 | 只看该作者
本帖最后由 517538964 于 2021-3-27 12:33 编辑
缘来yy 发表于 2021-3-26 19:46
名称        数量(个)        型号        备注
电阻        3               
数码管        1        7SEG-DIGITAL        

谢谢 做出来就需要这么多东西吗 我就按照你写的买了、要提交材料,我不知道具体买什么  还有你的仿真图能发我一下吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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