找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机按键控制蜂鸣器演奏音乐

[复制链接]
跳转到指定楼层
楼主
按键控制蜂鸣器演奏音乐

下载:
单片机演奏音乐.rar (44.26 KB, 下载次数: 94)
  1. #include<reg52.h>
  2. sbit spek=P3^7;  //声音输出端  
  3. sbit set=P3^2;  //设定及退出键,按奇数次为设定功能;偶数次为退出功能
  4. sbit up=P3^1;  //上一曲
  5. sbit down=P3^0;  //下一曲  
  6. bit flag1,flag2;  //按键扫描标志位,新键值标志位  
  7. unsigned char f_t,n,i,key,k_max; //音符频率对应的二分之一周期值,节拍常数值,查表用计数器,键值,最大键值
  8. unsigned char *p_music;  //指向音乐数据数组的指针
  9. void timer_ms(unsigned char tim);  //毫秒级延时函数声明
  10. void timer_us(unsigned char t);  //微秒级延时函数
  11. void key_scan(void);  //按键扫描函数
  12. void key_manage();  //键值处理函数
  13. //格式为:频率常数,节拍常数,频率常数,节拍常数  
  14. unsigned char code music_table1[]={
  15.         0x18,0x30,0x1c,0x10,0x20,0x40,0x1c,0x10,0x18,  
  16.         0x10,0x20,0x10,0x1c,0x10,0x18,0x40,0x1c,0x20,
  17.                 0x20,0x20,0x1c,0x20,0x18,0x20,0x20,0x80,0xff,
  18.                 0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,
  19.                 0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,
  20.                 0x26,0x20,0x20,0x20,0x30,0x80,0xff,0x20,0x20,
  21.                 0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,
  22.                 0x20,0x30,0x20,0x2b,0x40,0x20,0x20,0x1c,0x10,
  23.                 0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,
  24.                 0x20,0x2b,0x40,0x20,0x30,0x1c,0x10,0x18,0x20,
  25.                 0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,
  26.                 0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x80,
  27.                 0x20,0x30,0x1c,0x10,0x20,0x10,0x1c,0x10,0x20,
  28.                 0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,
  29.                 0x20,0x15,0x1f,0x05,0x20,0x10,0x1c,0x10,0x20,
  30.                 0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,
  31.                 0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,
  32.                 0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,
  33.                 0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1c,
  34.                 0x10,0x18,0x40,0x1c,0x20,0x20,0x20,0x26,0x40,
  35.                 0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,
  36.                 0x80,0x00}; //八月桂花香  
  37. unsigned char code music_table2[]={
  38.         0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,
  39.                 0x10,0x20,0x80,0x26,0x20,0x30,0x20,0x30,0x20,
  40.                 0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,
  41.                 0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,
  42.                 0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,
  43.                 0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,
  44.                 0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,
  45.                 0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,
  46.                 0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,
  47.                 0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,
  48.                 0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,
  49.                 0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,
  50.                 0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,
  51.                 0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
  52.                 0x20,0x20,0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,
  53.                 0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
  54.                 0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,
  55.                 0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,
  56.                 0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,
  57.                 0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,
  58.                 0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,
  59.                 0x10,0x30,0x20,0x39,0x20,0x26,0x10,0x2b,0x10,
  60.                 0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,
  61.                 0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,
  62.                 0x00};  //祝你平安  
  63. unsigned char code music_table3[]={
  64.         0x20,40,0x26,20,0x20,20,0x17,80,0x1c,40,0x17,40,
  65.                 0x20,80,0x20, 40,0x2f,20,0x2a,20,0x26,40,0x2a,20,
  66.                 0x2f,20,0x2a,80,0xff,0x20,40,0x26,20,0x20,20,0x17,60,
  67.                 0x19,20, 0x1c,40,0x17,40,0x20,80,0x20,40,0x2a,20,
  68.                 0x26,20,0x24,60,0x32,20,0x2f,80,0xff,0x1c,40,0x17,40,
  69.                 0x17, 80,0x19,40,0x1c,20,0x19,20,0x17,80,0x1c,20,
  70.                 0x19,20,0x17,20,0x1c,20,0x1c,20,0x20,20,0x26,20,0x2f,20,
  71.                 0x2a,80,0xff,0x20,40,0x26,20,0x20,20,0x17,60,0x19,20,
  72.                 0x1c,40,0x17,40,0x20,80,0x20,40,0x2a,20,0x26, 20,
  73.                 0x24,60,0x32,20,0x2f,80,0xff,0x20,40,0x26,20,0x20,20,
  74.                 0x17,80,0x1c,40,0x17,40,0x20,80,0x20,40, 0x2f,20,0x2a,20,
  75.                 0x26,40,0x2a,20,0x2f,20,0x2a,80,0xff,0x20,40,0x26,20,
  76.                 0x20,20,0x17,60,0x19,20,0x1c, 40,0x17,40,0x20,80,0x20,40,
  77.                 0x2a,20,0x26,20,0x24,60,0x32,20,0x2f,80,0};  //送别
  78. main()
  79. {
  80.      spek=0;     
  81.          P3=0x7f;      
  82.          TMOD=0x01;  //T0工作于方式1,即16位定时器模式     
  83.          IE=0x82;  //开总中断,T0中断     
  84.          flag2=0;  //     
  85.          flag1=0;     
  86.          key=1;        
  87.          k_max=3;  //最大键值(取值范围1~254)     
  88.          n=0;     
  89.          i=0;
  90.          p_music=music_table1;  //指针赋初值     
  91.          while (1)     
  92.          {
  93.            switch (p_music[i])           
  94.                  {     
  95.                    case 0x00: i=0;  //歌曲完,则停止0.5S后重新开始            
  96.                    timer_ms(250);  //延时0.25ms            
  97.                    timer_ms(250);            
  98.                    break;         
  99.                    case 0xff: i++;  //遇到休止符则停止100us            
  100.                    timer_ms(250);   
  101.                    timer_ms(250);            
  102.                    break;         
  103.                 default:   f_t=p_music[i++];            
  104.                 n=p_music[i++];            
  105.                 spek=1;            
  106.                 TR0=1;            
  107.                 while (n!=0)            
  108.                 {              
  109.                     spek=~spek;                  
  110.                         timer_us(4*f_t);  //改变f_t前面的系数可以调整音符频率的高低
  111.                                     }              
  112.                        TR0=0;            
  113.                            spek=0;   
  114.                            if(set==0)   
  115.                            {     
  116.                            key_scan();     
  117.                            key_manage();   
  118.                            }         
  119.                          }     
  120.         }
  121. }   
  122. /**************************************************************
  123. 函数名称: 定时器0的中断处理程序 函数功能: 完成10毫秒定时 入口参数:  
  124. 出口参数:  其      它:   **************************************************************/
  125. void timer0() interrupt 1 using 2
  126. {  
  127.      TH0=(65536-10000)/256;  //定时10毫秒     
  128.          TL0=(65536-10000)%256;     
  129.          n--; }  
  130. /**************************************************************
  131. 函数名称: 延时程序  函数功能: 完成微秒级的延时  入口参数:
  132. t为需延时的时间(取值范围1~255;延时时间5~1275us) 出口参数:  
  133. 其      它:   **************************************************************/
  134. void timer_us(unsigned char t)
  135. {
  136.      while (--t);  //本语句执行一次需5us的时间
  137.          }  
  138. /**************************************************************
  139. 函数名称: 按键扫描函数 函数功能: 完成按键扫描处理  入口参数:
  140. 应为在中断函数中被调用,所以不能有参数传递 出口参数:  其      它:   
  141. **************************************************************/
  142. void key_scan(void)
  143. {
  144.       timer_ms(10);  //延时10ms等待按键状态稳定
  145.      if (set==0)  //再次确认     
  146.          {      
  147.                while (set==0);  //等待按键松开         
  148.                    flag1=1;  //该位为1,表示进入按键扫描处理;为0,表示本次按键扫描处理完成         
  149.                    while (flag1)         
  150.                    {              
  151.                       if (up==0)  //加一键            
  152.                            {              
  153.                                timer_ms(10);               
  154.         if (up==0)                 
  155.          {                     
  156.                 while (!up);                     
  157.                         key++;                     
  158.                         if (key>k_max) key=1;                 
  159.                         }            
  160.                         }              
  161.           if (down==0)  //减一键            
  162.           {                 
  163.                  timer_ms(10);                    
  164.                          if (down==0)                 
  165.                          {                  
  166.                             while (!down);                     
  167.                                 key--;                     
  168.                                 if (key<1) key=k_max;              
  169.                                    }            
  170.                  }   
  171.                  if (set==0)  //退出键            
  172.                  {               
  173.                     timer_ms(10);                 
  174.                         if (set==0)                 
  175.                         {                     
  176.                              while (set==0);                     
  177.                                  flag1=0;  //表示本次按键扫描处理完成                     
  178.                                  flag2=1;  //该位置1,表示有新键值要处理                 
  179.                                  }            
  180.                  }//以上键值处理的范围为1到254个键值         
  181.         }      
  182. }
  183. }  
  184. /**************************************************************
  185. 函数名称: 键值处理函数  函数功能: 完成按键键值的处理  
  186. 入口参数: 应为在中断函数中被调用,所以不能有参数传递
  187. 出口参数:  其      它:   
  188. **************************************************************/
  189. void key_manage()
  190. {
  191.      flag2=0;     
  192.          switch (key)     
  193.          {   
  194.             case 1: p_music=music_table1;  //键值为1 播放第一首乐曲            
  195.                 goto kh1;      
  196.                 case 2: p_music=&music_table2[0];  //键值为2 播放第2首乐曲            
  197.                 goto kh1;  
  198.                 case 3: p_music=&music_table3[0];  //键值为3 播放第3首乐曲            
  199.                 goto kh1;      
  200.                 default:  key=1;               
  201.                 p_music=music_table1;
  202.                 kh1: TH0=(65536-10000)/256;      
  203.                 TL0=(65536-10000)%256;     
  204.                  break;     
  205.                  }
  206.                   n=0;     
  207.                   i=0;
  208. }   
  209. /*----------------------------------------------------------------------------------------------------
  210. 函数名称: timer_ms  函数说明: 1ms延时子程序  入口参数: tim为接收主调传来需延时的毫秒数,取值范围1~256,定时时间1~256ms
  211. 出口参数: 其    它:  ----------------------------------------------------------------------------------------------------*/   
  212. void timer_ms(unsigned char tim)
  213. {  
  214.         unsigned char j;   
  215.                 while(tim--)   
  216.                 {      
  217.                      for(j=0;j<200;j++);   //延时1ms   
  218.                          }
  219.         }
复制代码


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:148964 发表于 2016-11-20 22:25 | 只看该作者
不错。。。。。。。。。。。。。。
回复

使用道具 举报

板凳
ID:190307 发表于 2017-4-18 18:02 | 只看该作者
按键不管用啊
回复

使用道具 举报

地板
ID:170476 发表于 2017-4-19 20:22 | 只看该作者
按键怎么接啊
回复

使用道具 举报

5#
ID:60515 发表于 2017-4-19 20:26 来自手机 | 只看该作者
请问是接有源蜂鸣器还是嗽叭?
回复

使用道具 举报

6#
ID:204652 发表于 2017-5-25 11:30 | 只看该作者
按键怎么不管用啊
回复

使用道具 举报

7#
ID:219500 发表于 2017-7-25 10:23 | 只看该作者
不错,学习学习
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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