找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机电子琴程序原理图PCB文件,供大家参考学习使用

[复制链接]
跳转到指定楼层
楼主
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


制作出来的实物图如下:


单片机源程序如下:
  1. /************************************************************************
  2. *硬件连接:二十二个微动开关,一个蜂鸣器,二十一个弹奏键,一个功能切换。        *
  3. *功    能:电子琴弹奏,按键切换播放。                                                                        *
  4. 弹奏模式切换,添加歌曲。                                                        *
  5. *添加LED灯模式。                                                                        *
  6. *LED灯状态调试。                                                                        *
  7. ************************************************************************/

  8. #include<reg51.h>
  9. sbit QH=P2^7;           //P2^7口定义为切换功能
  10. sbit BUZZ=P1^7;           //P1^7口定义为蜂鸣器
  11. unsigned int H,L;  //定时器0缓冲变量
  12. unsigned char  k=0x00; //按键标志位

  13. void init(void)                 //初始化程序
  14. {
  15.         P0=P1=P2=P3=0xff; //初始化P0,P1,P2,P3口将他们的初值全为1
  16.         BUZZ=1;                      //初始化蜂鸣器鸣器
  17.         QH=1;                  //初始按键为1关闭状态
  18.         ET0=1;                     //初始化开定时计数器0中断
  19.         EA=1;            //初始化开总中断
  20.         TMOD=0x01;                 //设计定时计数器timer 0工作方式为1

  21. }
  22. void delayms(unsigned int i)         //延时1ms程序 用来按键消抖
  23. {
  24.         unsigned int j;
  25.         while(i--)
  26.                         for(j=600;j>0;j--);
  27. }
  28. void delay(unsigned int i)                //按键延时程序  用来扫描按键 算音长值
  29. {
  30.         unsigned int j;
  31.         while(i--)
  32.         {
  33.                  for(j=600;j>0;j--);
  34.                          if(!QH)                                  //判断在唱歌模式是否摁下模式转换按钮
  35.                         delayms(10);
  36.                         if(!QH)
  37.                         {
  38.                                 k=~k;                          //如果按下改变标志位的值。
  39.                                                 }
  40.                         while(!QH);
  41.         }
  42. }


  43. void tanzou(void)                   //弹奏模式
  44. {
  45.         unsigned int tone[]={262,294,330,349,392,440,494};  //低音
  46.         unsigned int tone1[]={523,587,659,698,784,880,988};        //中音
  47.         unsigned int tone2[]={1046,1175,1318,1397,1568,1760,1976};//高音
  48.         unsigned int a=0,b=0,c=0;  //定义a,b,c三个变量。
  49.            switch(~P1)                                  //高音7键判断键值符合符合键值跳出判断
  50.                 {        case 0x00:a=0;break;
  51.                     case 0x01:a=1;P0=~0x01;break; //按下按钮对应的灯亮
  52.                           case 0x02:a=2;P0=~0x02;break; //因为不管是中高低音都有同样的音,所以我们把相同的音放在一个灯上。
  53.                         case 0x04:a=3;P0=~0x04;break;
  54.                           case 0x08:a=4;P0=~0x08;break;
  55.                         case 0x10:a=5;P0=~0x10;break;
  56.                     case 0x20:a=6;P0=~0x20;break;
  57.                     case 0x40:a=7;P0=~0x40;break;
  58.                 }
  59.                 if(a!=0)                                    // 判断键值
  60.                 {
  61.                         H=(65536-1000000/tone[a-1]/2)/256;                // 取值,取对应数组中的音值。
  62.                         L=(65536-1000000/tone[a-1]/2)%256;

  63.                         TH0=H;
  64.                         TL0=L;                                    //定时计数器0赋值
  65.                         TR0=1;                                            //开定时计数器0
  66.                         while(P1!=0xff);                    //判断按键是否弹起
  67.                         TR0=0;                                    //关定时计数器0
  68.                         BUZZ=1;                                    //关蜂鸣器
  69.                 }
  70.                 else
  71.                 {
  72.                         TR0=0;                                    //没有任何按键按下关定时计数器0
  73.                         BUZZ=1;                                    //关蜂鸣器
  74.                 }
  75.                 if(a!=1||a!=2||a!=3||a!=4||a!=5||a!=6||a!=7)         //如果没有按键按下那么P0口为全1
  76.                 {
  77.                            P0=0xff;
  78.                 }
  79.                 switch(~P2)                                    //中音7键
  80.                 {        case 0x00:b=0;break;
  81.                     case 0x01:b=1;P0=~0x01;break;
  82.                           case 0x02:b=2;P0=~0x02;break;
  83.                         case 0x04:b=3;P0=~0x04;break;
  84.                           case 0x08:b=4;P0=~0x08;break;
  85.                         case 0x10:b=5;P0=~0x10;break;
  86.                     case 0x20:b=6;P0=~0x20;break;
  87.                     case 0x40:b=7;P0=~0x40;break;
  88.                         }
  89.                 if(b!=0)                                // 中音7键判断键值符合符合键值跳出判断
  90.                 {
  91.                         H=(65536-1000000/tone1[b-1]/2)/256;                // 取值,取对应数组中的音值。
  92.                         L=(65536-1000000/tone1[b-1]/2)%256;

  93.                         TH0=H;
  94.                         TL0=L;                                   //定时计数器0赋值
  95.                         TR0=1;                                           //开定时计数器0
  96.                         while(P2!=0xff);                   //判断按键是否弹起 出入不等于全一那么持续响按下的音
  97.                         TR0=0;                                   //没有任何键按下关定时计数器0
  98.                         BUZZ=1;                                    //关蜂鸣器
  99.                         }
  100.                 else
  101.                 {
  102.                         TR0=0;                                   //关定时计数器0
  103.                         BUZZ=1;                                    //关蜂鸣器
  104.                 }
  105.                 if(a!=1||a!=2||a!=3||a!=4||a!=5||a!=6||a!=7)
  106.                 {
  107.                            P0=0xff;
  108.                 }
  109.                 switch(~P3)                                  //低音7键判断键值符合符合键值跳出判断
  110.                 {
  111.                         case 0x00:c=0;break;
  112.                            case 0x01:c=1;P0=~0x01;break;
  113.                           case 0x02:c=2;P0=~0x02;break;
  114.                         case 0x04:c=3;P0=~0x04;break;
  115.                     case 0x08:c=4;P0=~0x08;break;
  116.                         case 0x10:c=5;P0=~0x10;break;
  117.                         case 0x20:c=6;P0=~0x20;break;
  118.                         case 0x40:c=7;P0=~0x40;break;
  119.                 }
  120.                 if(c!=0)
  121.                 {
  122.                         H=(65536-1000000/tone2[c-1]/2)/256;           // 取值,取对应数组中的音值
  123.                         L=(65536-1000000/tone2[c-1]/2)%256;
  124.                         TH0=H;
  125.                         TL0=L;
  126.                         TR0=1;
  127.                         while(P3!=0xff);                       //判断按键是否弹起
  128.                         TR0=0;                                        //关定时计数器0
  129.                         BUZZ=1;                                       //关蜂鸣器
  130.                 }
  131.                 else
  132.                 {
  133.                         TR0=0;                                          //没有任何按键按下关定时计数器0
  134.                         BUZZ=1;                                          //关蜂鸣器
  135.                 }
  136.                 if(a!=1||a!=2||a!=3||a!=4||a!=5||a!=6||a!=7)
  137.                 {
  138.                            P0=0xff;
  139.                 }
  140.           }
  141. void bofang(void)           //播放模式
  142. {
  143.         unsigned int i=0;         //定义i=0


  144.         //播放的音调
  145.         unsigned int code tone[]={        523,587,659,698,784,880,988, //中音7调
  146.                                                     1046,1175,1318,1397,1568,1760,1976, //高音7调
  147.                                                       262,294,330,349,392,440,494,99 //低音7调
  148.                                                   };
  149.         //1.茉莉花
  150.         unsigned int code yd[]={3,3,5,6,8,8,6,5,5,6,5,3,3,5,6,8,8,6,5,5,6,5,5,5,5,3,5,6,6,5,
  151.                                                  3,2,3,5,3,2,1,1,2,1,3,2,1,3,2,3,5,6,8,5,2,3,5,2,3,1,20,19,
  152.                                                  20,1,2,3,1,2,1,20,19,0,99};
  153.         float code yc[]={        1,0.5,0.5,0.5,0.5,0.5,0.5,1,0.5,0.5,2,1,0.5,0.5,0.5,0.5,0.5,0.5,1,0.5,0.5,2,
  154.                                          1,1,1,0.5,0.5,1,1,2,1,0.5,0.5,1,0.5,0.5,1,0.5,0.5,2,0.5,0.5,0.5,0.5,1.5,0.5,1,0.5,0.5,2,
  155.                                          1,0.5,0.5,0.5,0.5,0.5,0.5,2,1,1,1.5,0.5,0.5,0.5,0.5,0.5,3,1};


  156.         P0=0XFF;
  157.         while(yd[i]!=99)

  158.         {
  159.                  H=(65536-1000000/tone[yd[i]-1]/2)/256;           // 取值,取对应数组中的音值
  160.                  L=(65536-1000000/tone[yd[i]-1]/2)%256;
  161.                  TH0=H;
  162.                  TL0=L;
  163.                  TR0=1;
  164.                  delay(400*yc[i]);
  165.                  if(k==0x00)break;                           //如果标志位等于0x00那么跳出播放模式
  166.                  TR0=0;                                                  //关定时计数器0
  167.                  BUZZ=1;                                          //关蜂鸣器
  168.                  i++;                                                                  //i的值每次加1
  169.                  if(i==99)  break;                                        //当i等于99的时候跳出循环
  170.         }


  171. }

  172. void main(void)                                        //主函数
  173. {
  174.         init();                         //调用初始化程序
  175.         while(1)
  176.         {
  177.                 if(!QH)
  178.                         {
  179.                         delayms(10);
  180.                         if(!QH)
  181.                                 {                                      //判断QH是否按下
  182.                                         k=~k;                //两种模式切换
  183.                                 }
  184.                                 while(!QH);
  185.                                 delayms(10);
  186.                          }
  187.                 switch(k)         //判断按键
  188.                 {
  189.                         case 0x00:tanzou();break; //调用子函数
  190.                         case 0xff:bofang();break;
  191.                 }


  192.     }
  193. }

  194. void timer0(void) interrupt 1        //定时计数器0
  195. {
  196.         TR0=0;                            //关定时计数器0
  197.         TH0=H;                                                  //接收赋值
  198.         TL0=L;                                                  //接收赋值
  199.         BUZZ=~BUZZ;                                         //蜂鸣器发声
  200.         TR0=1;                             //开定时计数器0
  201. }

复制代码

原理图Altium Designer PCB文件和代码下载: 电子琴.7z (11.93 MB, 下载次数: 29)

评分

参与人数 1黑币 +50 收起 理由
admin + 50

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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