普中开发板电子琴实验,为什么我的矩阵键盘s9-s12不能控制蜂鸣器发声

在电子琴实验中,我的矩阵键盘s9-s12不能控制蜂鸣器工作,但数码管可以正常显示,其他也都正常,这是什么情况?
#include <reg51.h> //矩阵键盘接口
                  #define output P1
                  #define input P1
  
              unsigned char code table[]={                  //数组定义,显示数码管
                                                             0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                                              0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
 
        unsigned int code Freq_Tab[] = {     //定时半周期的初始值
     64021,64103,64260,64400,      //低音3 4 5 6
     64524,64580,64684,64777,      //低音7,中音1 2 3
     64820,64898,64968,65030,      //中音4 5 6 7
     65058,65110,65157,65178};  

  unsigned int frequency;
 
 
      sbit SPEAK = P1^5;
 
  void delay1ms(unsigned int n);
  
    unsigned int key_input(void);
 

 
  void main(void)
  {
      TMOD = 0X01;        //定时器T0设置为方式1
      EA = 1;
      ET0 = 1;
      TR0 = 0;
      while(1)
    {
        unsigned int num,temp;
        num = key_input();
        temp = num;
        P0 = table[num];
        if(16 != num)
        {
            frequency = Freq_Tab[num];
            TR0 = 1;
            while(0xf0 != input);        //检测按键松开
            TR0 = 0;
            SPEAK = 1;    
        }        
    }
}

void tm0_isr() interrupt 1
{
     TL0 = frequency;                //载入定时半周期的初始值
     TH0 = frequency >> 8;
     SPEAK = ~SPEAK;                    //发音 
} 

void delay1ms(unsigned int n)   //延时n毫秒
{
   unsigned int a,b,c;
        for(c=n;c>0;c--)
 
        for(b=199;b>0;b--)
 
            for(a=1;a>0;a--);
 
}
unsigned int key_input(void)
{ 
    unsigned char temp1,temp2;            //临时保存读取的行或者列
    unsigned char num = 16;                   //返回按键的值
    input = 0x0f;        
       temp1 = output;                //先读取行
    if(0x0f != temp1)           //按键按下
    {                       
        delay1ms(5);            //延时,消除抖动
        temp1 = output;            //再次读取行
        if(0x0f != temp1)        //说明按键确实按下    
        {
            temp1 = temp1 & 0x0f;    //保留低4位
            input = 0xf0;            //准备读取列
            delay1ms(1);            //延时一下,防止下一句读不到
            temp2 = output;            //直接读取列
            temp2 = temp2 & 0xf0;    //保留高4位
            temp1 = temp1 | temp2;    //将temp1和temp2的值合并
        }
    }
    switch(temp1)
    {
            case 0x77:num=0;break;  
            case 0x7b:num=1;break;  
            case 0x7d:num=2;break;   
            case 0x7e:num=3;break; 
            case 0xb7:num=4;break;               
            case 0xbb:num=5;break;           
            case 0xbd:num=6;break;             
            case 0xbe:num=7;break;   
            case 0xd7:num=8;break;    
            case 0xdb:num=9;break;    
            case 0xdd:num=10;break;   
            case 0xde:num=11;break;    
            case 0xe7:num=12;break;   
            case 0xeb:num=13;break;   
            case 0xed:num=14;break;    
            case 0xee:num=15;break;      
            default:break;
    }
    return num;
}


#define output P1
#define input P1
sbit SPEAK = P1^5

看代码,代码中键盘扫描用的 output、input 使用的是P1 的 8 位
你这个蜂鸣器使用的是 sbit SPEAK = P1^5 ,和这个 P1 是冲突的
你把电路图仔细核对一下这些需要软件读写的端口,核对代码和原理图是否匹配。

建议直接把蜂鸣器写成函数,按下去矩阵按键的时候重复执行蜂鸣器函数松开按键退出函数