找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这个单片机电子琴为什么按下去的时候不响?怎么解决 求帮助

[复制链接]
跳转到指定楼层
楼主
ID:411679 发表于 2019-6-1 21:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>   //包含51单片机寄存器定义的头文件
sbit P14=P1^4;      //将P14位定义为P1.4引脚
sbit P15=P1^5;      //将P15位定义为P1.5引脚
sbit P16=P1^6;      //将P16位定义为P1.6引脚
sbit P17=P1^7;      //将P17位定义为P1.7引脚
unsigned char keyval;    //定义变量储存按键值
unsigned char q;    //定义变量储存按键值
sbit sound=P2^0;    //将sound位定义为P2.0
sbit  P22=P2^2;      //将P22位定义为P2.2引脚
unsigned int C;     //全局变量,储存定时器的定时常数
unsigned int f;     //全局变量,储存音阶的频率
unsigned char s;     //全局变量,储存节拍
//定义 KEY_PORT 为 P1 端口
#define KEY_PORT P1
//以下是C调低音的音频宏定义
#define l_dao 262   //将“l_dao”宏定义为低音“1”的频率262Hz
#define l_re 286    //将“l_re”宏定义为低音“2”的频率286Hz
#define l_mi 311    //将“l_mi”宏定义为低音“3”的频率311Hz
#define l_fa 349    //将“l_fa”宏定义为低音“4”的频率349Hz
#define l_sao 392   //将“l_sao”宏定义为低音“5”的频率392Hz
#define l_la 440    //将“l_a”宏定义为低音“6”的频率440Hz
#define l_xi 494    //将“l_xi”宏定义为低音“7”的频率494Hz
      
     //以下是C调中音的音频宏定义
#define dao 523     //将“dao”宏定义为中音“1”的频率523Hz
#define re 587      //将“re”宏定义为中音“2”的频率587Hz
#define mi 659      //将“mi”宏定义为中音“3”的频率659Hz
#define fa 698      //将“fa”宏定义为中音“4”的频率698Hz
#define sao 784     //将“sao”宏定义为中音“5”的频率784Hz
#define la 880      //将“la”宏定义为中音“6”的频率880Hz
#define xi 987      //将“xi”宏定义为中音“7”的频率53
      
//以下是C调高音的音频宏定义
#define h_dao 1046     //将“h_dao”宏定义为高音“1”的频率1046Hz
#define h_re 1174      //将“h_re”宏定义为高音“2”的频率1174Hz
#define h_mi 1318      //将“h_mi”宏定义为高音“3”的频率1318Hz
#define h_fa 1396     //将“h_fa”宏定义为高音“4”的频率1396Hz
#define h_sao 1567    //将“h_sao”宏定义为高音“5”的频率1567Hz
#define h_la 1760     //将“h_la”宏定义为高音“6”的频率1760Hz
#define h_xi 1975     //将“h_xi”宏定义为高音“7”的频率1975Hz
/**************************************************************
函数功能:软件延时子程序
**************************************************************/
void delay20ms(void)   
{
   unsigned char i,j;
for(i=0;i<100;i++)
  for(j=0;j<60;j++)
           ;
}

/*******************************************
函数功能:节拍的延时的基本单位,延时200ms
******************************************/
void delay()               
   {
     unsigned char i,j;
    for(i=0;i<250;i++)
     for(j=0;j<250;j++);
   }
/*******************************************
函数功能:输出音频
入口参数:f
******************************************/
void Output_Sound(void)
{
  C=(50000/f)*10;    //计算定时常数
  TH0=(8192-C)/32;     //可证明这是13位计数器TH0高8位的赋初值方法
  TL0=(8192-C)%32;     //可证明这是13位计数器TL0低5位的赋初值方法
  TR0=1;               //开定时T0
  for(s=0;s<2;s++)
  delay();             //延时200ms,播放音频
  TR0=0;               //关闭定时器
  sound=1;        //关闭蜂鸣器
  keyval=0xff;     //播放按键音频后,将按键值更改,停止播放
}
/*******************************************
函数功能:按键检测
输出参数:keyval
******************************************/
unsigned char KeyScan(void)
{
  KEY_PORT = 0x0f;  // P1.0-1.3输出高电平,P1.4-P1.7输出低电平
if (KEY_PORT != 0x0f) // 检测是否有键按下
{
  delay20ms();  // 消抖
  if (KEY_PORT != 0x0f)  // 确认按下
  {
   // 行
   switch (KEY_PORT)
   {
    case 0x07 : keyval = 1; break;
    case 0x0b : keyval = 2; break;
    case 0x0d : keyval = 3; break;
    case 0x0e : keyval = 4; break;
    default   :    break;
   }
   // 列
   KEY_PORT = 0xf0;
   switch (KEY_PORT)
   {
    case 0x70: keyval = keyval + 0; break;
    case 0xb0: keyval = keyval + 4; break;
    case 0xd0:  keyval = keyval + 8; break;
    case 0xe0: keyval = keyval + 12; break;
   }
   return keyval;
  }  
      
  }
   return 0;
}
/*******************************************
函数功能:主函数
******************************************/
void main(void)
  {  
    unsigned char n=0,m=0,k=0,z,i=0;
   
    unsigned char pu[92];     //定义数组pu[]用于存储键盘扫描结果,最多储存92个按键
     while(1)
     {
           
     
    EA=1;         //开总中断
    ET0=1;         //定时器T0中断允许
    ET1=1;        //定时器T1中断允许
    TR1=1;        //定时器T1启动,开始键盘扫描
    TMOD=0x10;    //分别使用定时器T1的模式1,T0的模式0
          TH1=(65536-500)/256;  //定时器T1的高8位赋初值
     TL1=(65536-500)%256;  //定时器T1的高8位赋初值            
     q=KeyScan();
     while(n!=1&&m<=i)            //无限循环
       {
       if(P22==0)        //当P22==0,播放之前的按键
       i=m-1;
       else{i=m;}
      
        switch(q)
         {
            case 1:f=dao;            //如果第1个键按下,将中音1的频率赋给f
              Output_Sound();     //转去计算定时常数
                                                   pu[m]=dao;       //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;           //付值完毕m自动加1用于对数组的下一个元素付值
          break;
            case 2:f=l_xi;           //如果第2个键按下,将低音7的频率赋给f
       Output_Sound();    //转去计算定时常数
                                                   pu[m]=l_xi;        //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
          break;
                                               case 3:f=l_la;           //如果第3个键按下,将低音6的频率赋给f
       Output_Sound();    //转去计算定时常数
                                                   pu[m]=l_la;       //将键盘扫描的结果付数组pu[]的元素
                                                    m++;  i++;           //付值完毕m自动加1用于对数组的下一个元素付值
          break;
            case 4:f=l_sao;          //如果第4个键按下,将低音5的频率赋给f
       Output_Sound();    //转去计算定时常数
                                                   pu[m]=l_sao;      //将键盘扫描的结果付数组pu[]的元素
                                                    m++;  i++;           //付值完毕m自动加1用于对数组的下一个元素付值
          break;
            case 5:f=sao;             //如果第5个键按下,将中音5的频率赋给f
              Output_Sound();    //转去计算定时常数
                                                   pu[m]=sao;        //将键盘扫描的结果付数组pu[]的元素
                                                    m++;  i++;           //付值完毕m自动加1用于对数组的下一个元素付值
          break;
            case 6:f=fa;              //如果第6个键按下,将中音4的频率赋给f
               Output_Sound();    //转去计算定时常数
                                                    pu[m]=fa;            //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
                                               case 7:f=mi;             //如果第7个键按下,将中音3的频率赋给f
               Output_Sound();    //转去计算定时常数
                                                    pu[m]=mi;             //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 8:f=re;              //如果第8个键按下,将中音2的频率赋给f
               Output_Sound();    //转去计算定时常数
                                                    pu[m]=re;            //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
                  break;
            case 9:f=h_re;           //如果第9个键按下,将高音2的频率赋给f
         Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_re;          //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 10:f=h_dao;           //如果第10个键按下,将高音1的频率赋给f
         Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_dao;            //将键盘扫描的结果付数组pu[]的元素
                                                    m++;  i++;           //付值完毕m自动加1用于对数组的下一个元素付值
           break;
                                               case 11:f=xi;            //如果第11个键按下,将中音7的频率赋给f
         Output_Sound();    //转去计算定时常数
                                                    pu[m]=xi;                //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 12:f=la;            //如果第12个键按下,将中音6的频率赋给f
         Output_Sound();    //转去计算定时常数
                                                    pu[m]=la;                 //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 13:f=h_la;          //如果第13个键按下,将高音6的频率赋给f
                Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_la;               //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 14:f=h_sao;          //如果第14个键按下,将高音5的频率赋给f
         Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_sao;               //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
                                               case 15:f=h_fa;          //如果第15个键按下,将高音4的频率赋给f
                Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_fa;               //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;
            case 16:f=h_mi;           //如果第16个键按下,将高音3的频率赋给f
                Output_Sound();    //转去计算定时常数
                                                    pu[m]=h_mi;                //将键盘扫描的结果付数组pu[]的元素
                                                    m++; i++;            //付值完毕m自动加1用于对数组的下一个元素付值
           break;  
                            case 17:n=1;            //n==1,跳出循环
                              break;
                               }
                 }
            while(pu[k]!=0)                                          //播放通过按键写入的音乐
              {
                f=pu[k];
                Output_Sound();
        k++;
               
               }
      for(z=0;z<41;z++)                     //清空pu[]
           {
            pu[z]=0;
           }
   
   
        }
  }
/**************************************************************
函数功能:定时器T0的中断服务子程序,使P2.0引脚输出音频方波
**************************************************************/
  void Time0_serve(void ) interrupt 1 using 1  
  {
         
        TH0=(8192-C)/32;     //可证明这是13位计数器TH0高8位的赋初值方法
        TL0=(8192-C)%32;     //可证明这是13位计数器TL0低5位的赋初值方法
       sound=!sound;        //将P3.7引脚取反,输出音频方波
  }
  
/**************************************************************
函数功能:定时器T1的中断服务子程序,进行键盘扫描,判断键位
**************************************************************/
  void time1_serve(void) interrupt 3 using 2    //定时器T1的中断编号为3,使用第2组寄存器
  {
     TR1=0;                  //关闭定时器T0
     q=KeyScan();   
     TR1=1;                    //开启定时器T1
     TH1=(65536-500)/256;  //定时器T1的高8位赋初值
    TL1=(65536-500)%256;  //定时器T1的高8位赋初值   
}

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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