找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机电子琴程序Proteus仿真

[复制链接]
跳转到指定楼层
楼主
基本要求如下:
1. 通过单片机编程控制,对按下的按键进行识别,然后控制喇叭发声。电子琴模式下1-7七个按键可弹出“哆、来、咪、发、梭、拉、西”。
2. 当喇叭发声时,用一个数码管反应音符。
附加要求如下:
1. 当音乐切换按键时,可切换播放某首曲子。

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


单片机源程序如下:
  1. /*******51单片机简易电子琴 八音盒 设计***********/
  2. /*********do re mi fa so la si 高音do************/
  3. /******************内置3首歌*********************/
  4. /***《挥着翅膀的女孩》《同一首歌》《两只蝴蝶》***/
  5. /*****************JJ电子直营店*******************/
  6. /********************原创设计********************/

  7. #include <REGX52.H>                        //调系统头文件

  8. #define uchar unsigned char        //uchar代替 unsigned char
  9. #define uint unsigned int        //uint代替 unsigned char
  10.         
  11. #define Key1        P2_0        //定义按键1(播放 "挥着翅膀的女孩")
  12. #define        Key2        P2_1        //定义按键2(播放 "同一首歌")
  13. #define Key3        P2_2        //定义按键3(播放 "两只蝴蝶")

  14. #define SMG                P0                //定义数码管显示端
  15. #define        Speak        P2_4        //定义蜂鸣器接口

  16. uchar sth,stl;                    //定义全局变量 sth stl
  17. uint i,j;                                //定义循环变量i j

  18. uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
  19.                                         0x88,0x83,0xC6,0xA1,0x86,0x8E};//定义数码管显示 0-9,A-F


  20. uchar code Music_hzcb[]={//《挥着翅膀的女孩》系统自带歌曲音符
  21.         0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,
  22. ............................
  23.         0x10,0x03, 0x15,0x00, 0xff,0xff };
  24.   
  25. uchar code Music_Code[]={                 //八个音符        do re mi fa so la si 高音do
  26.         0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x66,
  27.         0xfb,0x03,0xfb,0x8f,0xfc,0x0b,0xfd,0xee};                                                                          
  28. uchar const yinfu1[3][14]={                //低中高三种音符
  29.         0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x66,0xfb,0x03,0xfb,0x8f,0xfc,0x0b,
  30.         0xfc,0x43,0xfc,0xab,0xfd,0x08,0xfd,0x33,0xfd,0x81,0xfd,0xc7,0xfe,0x05,
  31.         0xfb,0x21,0xfe,0x55,0xfe,0x84,0xfe,0x99,0xfe,0xc0,0xfe,0xe3,0xff,0x02};
  32. uchar const length[]={1,2,4,8,16,32,64};        //几分音符查表(节拍)


  33. void delay_ms(uint time)        //毫秒延时函数
  34. {
  35.         uint z;
  36.         uchar x,y;
  37.         for(z=0;z<time;z++)
  38.         for(x=5;x>0;x--)
  39.         for(y=97;y>0;y--);
  40. }

  41. void Time0_Init()                        //定时器T0初始化函数               
  42. {
  43.         TMOD=0x01;        //工作方式1
  44.         TH0=sth;    //定时器高八位赋初值     
  45.         TL0=stl;        //定时器低八位赋初值
  46.         ET0=1;                //使能T0中断
  47.         EA=1;                //打开全局中断
  48.         TR0=0;                //关闭定时器T0
  49. }

  50. void main()         //主函数入口
  51. {
  52.         Time0_Init();        //定时器T0初始化
  53.         Speak=1;                //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  54.         while(1)        //无限循环        
  55.         {
  56.                 switch(P1)                //switch语句判断检测 P1按键状态
  57.                 {  
  58.                         case 0xfe:        //P1=0xfe    "do"按键按下                        
  59.                                                 delay_ms(10);        //延时去抖        
  60.                                                 if(P1==0xfe)        //再判断"do"按键是否按下
  61.                                                 {                                
  62.                                                         SMG=table[1];        //数码管显示"1"        
  63.                                                         i=0;                        //i置0
  64.                                     TR0=0;                  //关闭定时器T0
  65.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "do"
  66.                                                     stl=Music_Code[2*i+1];        //定时器低八位赋值 "do"
  67.                                                         TR0=1;                        //启动定时器T0
  68.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测
  69.                                                         {                                                                                         
  70.                                                                 delay_ms(10);                //延时一下
  71.                                                                 if(P1==0xfe) continue;        //"do"按键按下,跳出(继续发音)
  72.                                                                 else break;                        //松开了,则返回
  73.                                                         }
  74.                                                         SMG=0xff;        //关闭数码管显示
  75.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  76.                                                         TR0=0;                //关闭定时器T0
  77.                                                         for(;;)        
  78.                                                         {
  79.                                                                 while(P1==0xfe);        //等待按键松开                                                                                                         
  80.                                                                 delay_ms(10);                //延时去抖
  81.                                                                 if(P1==0xfe) continue;        
  82.                                                                 else break;                        //确定松开,退出
  83.                                                         }
  84.                                                         TR0=0;                //关闭定时器T0
  85.                                                 }
  86.                                                 break;                        //返回
  87.                         case 0xfd:        //P1=0xfd        "re"按键按下                 
  88.                                                 delay_ms(10);        //延时去抖
  89.                                                 if(P1==0xfd)        //再判断"re"按键是否按下
  90.                                         {
  91.                                                         SMG=table[2];        //数码管显示"2"
  92.                                                         i=1;                        //i置1
  93.                                                         TR0=0;                  //关闭定时器T0
  94.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "re"
  95.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "re"
  96.                                                         TR0=1;                        //启动定时器T0               
  97.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测
  98.                                                         {                                                                                                         
  99.                                                                 delay_ms(10);        //延时一下        
  100.                                                                 if(P1==0xfd) continue;        //"re"按键按下,跳出(继续发音)        
  101.                                                                 else break;                //松开了,则返回
  102.                                                         }
  103.                                                         SMG=0xff;        //关闭数码管显示
  104.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  105.                                                         TR0=0;                //关闭定时器T0
  106.                                                         for(;;)
  107.                                                         {
  108.                                                                 while(P1==0xfd);        //等待按键松开
  109.                                                                 delay_ms(10);                //延时去抖
  110.                                                                 if(P1==0xfd) continue;        
  111.                                                                 else break;                        //确定松开,退出
  112.                                                         }
  113.                                                 }
  114.                                                 TR0=0;                        //关闭定时器T0
  115.                                                 break;                        //返回
  116.                         case 0xef:        //P1=0xef        "mi"按键按下
  117.                                                 delay_ms(10);        //延时去抖                        
  118.                                                 if(P1==0xef)        //再判断"mi"按键是否按下
  119.                                                 {
  120.                                                         SMG=table[3];        //数码管显示"3"
  121.                                                         i=2;                        //i置2        
  122.                                                         TR0=0;                  //关闭定时器T0        
  123.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "mi"        
  124.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "mi"
  125.                                                         TR0=1;                        //启动定时器T0        
  126.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测
  127.                                                         {                                                                                         
  128.                                                                 delay_ms(10);        //延时一下
  129.                                                                 if(P1==0xef) continue;        //"mi"按键按下,跳出(继续发音)
  130.                                                                 else break;                //松开了,则返回
  131.                                                         }
  132.                                                         SMG=0xff;        //关闭数码管显示
  133.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  134.                                                         TR0=0;                //关闭定时器T0
  135.                                                         for(;;)
  136.                                                         {
  137.                                                                 while(P1==0xef);        //等待按键松开        
  138.                                                                 delay_ms(10);                //延时去抖
  139.                                                                 if(P1==0xef) continue;
  140.                                                                 else break;                        //确定松开,退出
  141.                                                         }
  142.                                                 }
  143.                                                 TR0=0;                        //关闭定时器T0
  144.                                                 break;                        //返回               
  145.                         default:         break;                        //没有P1没有按键按下,返回
  146.             }
  147.                 switch(P3)                //switch语句判断检测 P3按键状态
  148.                 {
  149.                         case 0xfe:        //P3=0xfe        "fa"按键按下
  150.                                                 delay_ms(10);        //延时去抖        
  151.                                                 if(P3==0xfe)        //再判断"fa"按键是否按下
  152.                                                 {
  153.                                                         SMG=table[4];        //数码管显示"4"
  154.                                                         i=3;                        //i置3
  155.                                                         TR0=0;                  //关闭定时器T0        
  156.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "fa"        
  157.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "fa"
  158.                                                         TR0=1;                        //启动定时器T0        
  159.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测        
  160.                                                         {                                                                                         
  161.                                                                 delay_ms(10);        //延时一下
  162.                                                                 if(P3==0xfe) continue;        //"fa"按键按下,跳出(继续发音)
  163.                                                                 else break;                //松开了,则返回
  164.                                                         }
  165.                                                         SMG=0xff;        //关闭数码管显示
  166.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  167.                                                         TR0=0;                //关闭定时器T0
  168.                                                         for(;;)
  169.                                                         {
  170.                                                                 while(P3==0xfe);        //等待按键松开
  171.                                                                 delay_ms(10);                //延时去抖
  172.                                                                 if(P3==0xfe) continue;
  173.                                                                 else break;                        //确定松开,退出
  174.                                                         }
  175.                                                 }
  176.                                                 TR0=0;                //关闭定时器T0        
  177.                                                 break;                //返回
  178.                         case 0xf7:         //P3=0xf7        "so"按键按下
  179.                                                 delay_ms(10);        //延时去抖                        
  180.                                                 if(P3==0xf7)        //再判断"so"按键是否按下
  181.                                                 {
  182.                                                         SMG=table[5];        //数码管显示"5"        
  183.                                                         i=4;                        //i置4                        
  184.                                                         TR0=0;                  //关闭定时器T0               
  185.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "so"
  186.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "so"
  187.                                                         TR0=1;                        //启动定时器T0               
  188.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测        
  189.                                                         {                                                                                                         
  190.                                                                 delay_ms(10);                //延时一下
  191.                                                                 if(P3==0xf7) continue;        //"so"按键按下,跳出(继续发音)
  192.                                                                 else break;                        //松开了,则返回
  193.                                                         }
  194.                                                         SMG=0xff;        //关闭数码管显示
  195.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  196.                                                         TR0=0;                //关闭定时器T0
  197.                                                         for(;;)
  198.                                                         {
  199.                                                                    while(P3==0xf7);        //等待按键松开               
  200.                                                                 delay_ms(10);                //延时去抖
  201.                                                                 if(P3==0xf7) continue;
  202.                                                                 else break;                        //确定松开,退出
  203.                                                         }
  204.                                                   }
  205.                                                 TR0=0;                //关闭定时器T0
  206.                                                 break;                //返回
  207.                         case 0xef:         //P3=0xef        "la"按键按下
  208.                                                 delay_ms(10);        //延时去抖
  209.                                                 if(P3==0xef)        //再判断"la"按键是否按下
  210.                                                 {
  211.                                                         SMG=table[6];        //数码管显示"6"
  212.                                                         i=5;                        //i置5
  213.                                                         TR0=0;                  //关闭定时器T0
  214.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "la"
  215.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "la"
  216.                                                         TR0=1;                        //启动定时器T0               
  217.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测        
  218.                                                         {                                                                                         
  219.                                                                 delay_ms(10);                //延时一下
  220.                                                                 if(P3==0xef) continue;        //"la"按键按下,跳出(继续发音)
  221.                                                                 else break;                        //松开了,则返回
  222.                                                         }
  223.                                                         SMG=0xff;        //关闭数码管显示
  224.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  225.                                                         TR0=0;                //关闭定时器T0
  226.                                                         for(;;)
  227.                                                         {
  228.                                                                 while(P3==0xef);        //等待按键松开        
  229.                                                                 delay_ms(10);                //延时去抖
  230.                                                                 if(P3==0xef) continue;
  231.                                                                 else break;                        //确定松开,退出
  232.                                                         }        
  233.                                                 }
  234.                                                 TR0=0;                //关闭定时器T0        
  235.                                                 break;                //返回
  236.                         case 0xdf:         //P3=0xdf        "si"按键按下
  237.                                                 delay_ms(10);        //延时去抖
  238.                                                 if(P3==0xdf)        //再判断"si"按键是否按下
  239.                                                 {
  240.                                                         SMG=table[7];        //数码管显示"7"        
  241.                                                         i=6;                        //i置6
  242.                                                         TR0=0;                  //关闭定时器T0
  243.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "si"
  244.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "si"
  245.                                                         TR0=1;                        //启动定时器T0        
  246.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测        
  247.                                                         {                                                                                         
  248.                                                                 delay_ms(10);                //延时一下
  249.                                                                 if(P3==0xdf) continue;        //"si"按键按下,跳出(继续发音)
  250.                                                                 else break;                        //松开了,则返回
  251.                                                         }
  252.                                                         SMG=0xff;        //关闭数码管显示
  253.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  254.                                                         TR0=0;                //关闭定时器T0
  255.                                                         for(;;)
  256.                                                         {
  257.                                                                 while(P3==0xdf);        //等待按键松开
  258.                                                                 delay_ms(10);                //延时去抖
  259.                                                                 if(P3==0xdf) continue;
  260.                                                                 else break;                        //确定松开,退出
  261.                                                         }
  262.                                                 }
  263.                                                 TR0=0;                //关闭定时器T0
  264.                                                 break;                //返回
  265.                         case 0xbf:        //P3=0xbf        "高音do"按键按下
  266.                                                 delay_ms(10);        //延时去抖        
  267.                                                 if(P3==0xbf)        //再判断"高音do"按键是否按下
  268.                                                 {
  269.                                                         SMG=table[1]&0x7f;  //数码管显示"1"带小数点(1.)
  270.                                                         i=7;                //i置7               
  271.                                                         TR0=0;          //关闭定时器T0
  272.                                                         sth=Music_Code[2*i];        //定时器高八位赋值 "高音do"
  273.                                                         stl=Music_Code[2*i+1];        //定时器低八位赋值 "高音do"
  274.                                                         TR0=1;                //启动定时器T0                        
  275.                                                         for(j=0;j<=1000;j++)        //软件延时,在一定时间里检测               
  276.                                                         {                                                                                         
  277.                                                                 delay_ms(10);                //延时一下
  278.                                                                 if(P3==0xbf) continue;        //"高音do"按键按下,跳出(继续发音)
  279.                                                                 else break;                        //松开了,则返回
  280.                                                         }
  281.                                                         SMG=0xff;        //关闭数码管显示
  282.                                                         Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  283.                                                         TR0=0;                //关闭定时器T0
  284.                                                         for(;;)
  285.                                                         {
  286.                                                                    while(P3==0xbf);        //等待按键松开
  287.                                                                 delay_ms(10);                //延时去抖
  288.                                                                 if(P3==0xbf) continue;
  289.                                                                 else break;                        //确定松开,退出
  290.                                                         }
  291.                                                 }
  292.                                                 TR0=0;                //关闭定时器T0
  293.                                                 break;                //返回
  294.                         default:         break;                //没有P3没有按键按下,返回
  295.                 }
  296.                
  297.                 if(Key1==0)                        //按键1按下(播放 "挥着翅膀的女孩")
  298.                 {
  299.                         delay_ms(10);        //延时去抖
  300.                         if(Key1==0)                //再判断按键1是否按下
  301.                         {
  302.                                 SMG=table[10];        //数码管显示"A"
  303.                                 for(i=0;Music_hzcb[i]!=0xff;i++)        //for循环语句                        
  304.                                 {                                //Music_hzcb[]=0ff时,跳出for循环语句,停止播放音乐
  305.                                         sth=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2];         //定时器高八位赋值
  306.                                         stl=yinfu1[(Music_hzcb[i]%100)/10-1][((Music_hzcb[i]%10)-1)*2+1];//定时器低八位赋值
  307.                                         i++;                //i加1
  308.                                         TR0=1;                //启动定时器T0
  309.                                         delay_ms(4*500/length[Music_hzcb[i]%10]);        //确定几分音符(节拍)               
  310.                                         TR0=0;                //节拍结束,关闭定时器T0                                 
  311.                                 }
  312.                                 SMG=0xff;        //关闭数码管显示
  313.                                 Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  314.                                 for(;;)
  315.                                 {
  316.                                         while(Key1==0);                //等待按键松开        
  317.                                         delay_ms(10);                //延时去抖
  318.                                         if(Key1==0) continue;
  319.                                         else break;                        //确定松开,退出        
  320.                                 }
  321.                         }
  322.                 }
  323.                 if(Key2==0)                        //按键2按下(播放 "同一首歌")        
  324.                 {
  325.                         delay_ms(10);        //延时去抖
  326.                         if(Key2==0)                //再判断按键2是否按下
  327.                         {
  328.                                 SMG=table[11];        //数码管显示"B"
  329.                                 for(i=0;Music_tyshg[i]!=0xff;i++)        //for循环语句
  330.                                 {                                //Music_tyshg[]=0ff时,跳出for循环语句,停止播放音乐
  331.                                         sth=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2];  //定时器高八位赋值
  332.                                         stl=yinfu1[(Music_tyshg[i]%100)/10-1][((Music_tyshg[i]%10)-1)*2+1];//定时器低八位赋值
  333.                                         i++;                //i加1
  334.                                         TR0=1;                //启动定时器T0
  335.                                         delay_ms(4*500/length[Music_tyshg[i]%10]);        //确定几分音符(节拍)
  336.                                         TR0=0;                //节拍结束,关闭定时器T0                                                
  337.                                 }
  338.                                 SMG=0xff;        //关闭数码管显示
  339.                                 Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  340.                                 for(;;)        
  341.                                 {
  342.                                         while(Key2==0);                //等待按键松开        
  343.                                         delay_ms(10);                //延时去抖
  344.                                         if(Key2==0) continue;
  345.                                         else break;                        //确定松开,退出
  346.                                 }
  347.                         }
  348.                 }
  349.                 if(Key3==0)                        //按键3按下(播放 "两只蝴蝶")
  350.                 {               
  351.                         delay_ms(10);        //延时去抖        
  352.                         if(Key3==0)                //再判断按键3是否按下
  353.                         {
  354.                                 SMG=table[12];        //数码管显示"C"               
  355.                                 for(i=0;Music_lzhhd[i]!=0xff;i++)        //for循环语句
  356.                                 {                                //Music_lzhhd[]=0ff时,跳出for循环语句,停止播放音乐
  357.                                         sth=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2];  //定时器高八位赋值
  358.                                         stl=yinfu1[(Music_lzhhd[i]%100)/10-1][((Music_lzhhd[i]%10)-1)*2+1];//定时器低八位赋值
  359.                                         i++;                //i加1        
  360.                                         TR0=1;                //启动定时器T0
  361.                                         delay_ms(4*500/length[Music_lzhhd[i]%10]);        //确定几分音符(节拍)
  362.                                         TR0=0;                //节拍结束,关闭定时器T0                                         
  363.                                 }
  364.                                 SMG=0xff;        //关闭数码管显示
  365.                                 Speak=1;        //蜂鸣器端口置1 (让蜂鸣器处于与电源5V断电状态)
  366.                                 for(;;)
  367.                                 {
  368.                                         while(Key3==0);                //等待按键松开
  369.                                         delay_ms(10);                //延时去抖
  370.                                         if(Key3==0) continue;
  371.                                         else break;                        //确定松开,退出
  372.                                 }
  373.                         }
  374.                 }
  375.         }
  376. }

  377. /**********定时器T0中断服务函数**********/
  378. void time0() interrupt 1        
  379. {
  380.         TR0=0;                 //关闭定时器T0
  381.         TH0=sth;          //定时器高八位赋初值
  382.         TL0=stl;        //定时器低八位赋初值
  383.         Speak=!Speak;        //蜂鸣器端口取反
  384.         TR0=1;                //启动定时器T0
  385. }
复制代码

仿真程序51hei附件下载:
基于51单片机电子琴的设计.7z (76.03 KB, 下载次数: 20)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:262 发表于 2023-12-17 15:09 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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