微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 请帮我看看是这个程序有问题还是我单片机连线有问题?

请帮我看看是这个程序有问题还是我单片机连线有问题?

时间:10-02 整理:3721RD 点击:
想实现这样一个功能://A:当打火机靠近火焰传感器模块一次时,led灯一直亮,蜂鸣器循环放歌。          //B:当随时向声音传感器模块吹一口气时,led灭,蜂鸣器不再响
现在我只能实现功能A。 B实现不了。但是我检查好久没看出来程序错在哪里了,请帮我看看,谢谢
火焰传感器和声音传感器都是低电平有效,都可以直接接单片机。
//我的思路;         //"打火机靠近火焰传感器模块一次"使进入“led灯一直亮”和“蜂鸣器循环放歌”两个中断  
         //"随时向声音传感器模块吹一口气" 使退出“led灯一直亮”和“蜂鸣器循环放歌”两个中断
         //由主函数中断进入“led灯一直亮”和“蜂鸣器循环放歌”两个部分。
         //在中断1中不断检查是否有吹气声音
//led用P1.0,1.1口  
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit  BEEP=P2^3;                 //蜂鸣器
sbit fire_sensor=P3^0;//定义火焰传感器管脚
sbit sound_sensor=P3^1;  //定义声音传感器管脚。
uchar code SOUNDLONG[]=       //控制音调
{
  18,6,24,24,24,48,
  18,6,24,24,24,48,
  18,6,24,24,24,24,24,
  18,6,24,24,24,48,0
};
uchar code SOUNDTONE[]=       //控制音色
{
212,212,190,212,159,169,
212,212,190,212,142,159,
212,212,106,126,159,169,190,
119,119,126,159,142,159,0        //生日快乐end
};
void delay(uint z);
void Play_Music();
void Music(uchar number);
void delay10us(uchar time);
void delay50us(uchar time);
void main()
{
        uint x=60000,y=110;         //60秒内检测是否有热源,开机超过60秒不再检测
        TH0=(65536-50000)/256;        //两个定时器的初值可任意设置
        TL0=(65536-50000)%256;
        TH1=(65536-50000)/256;         //两个定时器的初值任意设置可
        TL1=(65536-50000)%256;
        EA=1;
        ET0=1;
        ET1=1;
        for(;x>0;x--)
                for(;y>0;y--)
                        {
                                if(fire_sensor==0)        //如果有热源
                                {
                                         TR0=1;
                                        TR1=1;                //开启定时器T0,T1
                                }                                                  
                        }
}
void light() interrupt 1
{
        TR0=0;
        TH0=(65536-65000)/256;                          
        TL0=(65536-65000)%256;
        P1=0xfc;               //1111 1000
        delay(1);             
    if(sound_sensor==0)        //如果有声音(吹气)
        {  
                TR0=0;
                TR1=0;
                P1=0xff; //关掉led
                BEEP=1;//关蜂鸣器
                delay(1000); //延时
        }  
        TR0=1;
}
void sound() interrupt 3
{
        TR1=0;
        while(1)
        {
                   Play_Music();       //生日快乐
                   delay10us(250);
        }
        TR1=1;
}
void Play_Music()
{
  uint k,n;
  uint SoundLong,SoundTone;
  uint i,j,m;
  do
  {
     if(i>=25) i=0;
     SoundLong=SOUNDLONG[i];
     SoundTone=SOUNDTONE[i];
     i++;
     for(n=0;n<SoundLong;n++)
      {
      for(k=0;k<12;k++)
       {
           BEEP=0;
           for(m=0;m<SoundTone;m++);
           BEEP=1;
           for(m=0;m<SoundTone;m++);
          }
      }
      delay50us(6);
  }while((SOUNDLONG[i]!=0)||(SOUNDTONE[j]!=0));               
}
void delay50us(uchar time)
{
  uchar a,b;
  for(a=0;a<time;a++)
    for(b=0;b<6;b++);
}
void delay10us(uchar time)
{
  uchar a,b,c;
  for(a=0;a<time;a++)
     for(b=0;b<10;b++)
             for(c=0;c<120;c++);
}
void delay(uint z)
{
        uint i,j;
        for(i=z;i>0;i--)
                for(j=110;j>0;j--);
}

兄弟,你这程序有很大问题,在中断中运行长时间程序,然后这么简单的程序居然用了2个中断,中断不是这样用的
逻辑容易混乱。当然你写这程序是为了连续中断用法那又是另外一回事了
unsigned char Play_Music()
{
  uint k,n;
  uint SoundLong,SoundTone;
  uint i,j,m;
  do
  {
     if(i>=25) i=0;
     SoundLong=SOUNDLONG[i];
     SoundTone=SOUNDTONE[i];
     i++;
     for(n=0;n<SoundLong;n++)
      {
      for(k=0;k<12;k++)
       {
           BEEP=0;
           for(m=0;m<SoundTone;m++);
           BEEP=1;
           for(m=0;m<SoundTone;m++);
          }
      }
      delay50us(6);
if(sound_sensor==0)        //如果有声音(吹气)
{
return 1;
}
  }while((SOUNDLONG[i]!=0)||(SOUNDTONE[j]!=0));   
  return 0
}
void delay50us(uchar time)
{
  uchar a,b;
  for(a=0;a<time;a++)
    for(b=0;b<6;b++);
}

void main()
{
        uint x=60000,y=110;         //60秒内检测是否有热源,开机超过60秒不再检测
        for(;x>0;x--)
                for(;y>0;y--)
                        {
                                if(fire_sensor==0)        //如果有热源
                                {
                                         P1=0x00; //开led
                                                                                 while(1)
                                                                                 {
                                                                                 if( Play_Music())     //一直生日快乐直到吹气退出
                                                                                 {
                                     P1=0xff; //关掉led
                                    BEEP=1;//关蜂鸣器
                                                                        break;
                                                                                 }
                                                                                 }
                                                                                 break;//跳出检测
                                }                                                   
                        }
while(1);
}

下面没有注释的语句都是些放歌啊,延时啊什么的,应该不会错在那里,

没注意打错了,main中初值和中断中初值都是50000,中断中初值不是65000

修改了一下,重发一次
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit  BEEP=P2^3;                 //蜂鸣器
sbit fire_sensor=P3^0;//定义火焰传感器管脚
sbit sound_sensor=P3^1;  //定义声音传感器管脚。//有时得要定义全局变量 ,用于控制是否进入中断
uchar code SOUNDLONG[]=       //控制音调
{
  18,6,24,24,24,48,
  18,6,24,24,24,48,
  18,6,24,24,24,24,24,
  18,6,24,24,24,48,0
};
uchar code SOUNDTONE[]=       //控制音色
{
212,212,190,212,159,169,
212,212,190,212,142,159,
212,212,106,126,159,169,190,
119,119,126,159,142,159,0        //生日快乐end
};
void delay(uint z);
void Play_Music();
void Music(uchar number);
void delay10us(uchar time);
void delay50us(uchar time);
void main()
{
        uint x=60000,y=110;                  //60秒内检测是否有热源
        TH0=(65536-50000)/256;                          //两个定时器的初值随便,反正只进一次中断且进中断后延时液与定时器无关
        TL0=(65536-50000)%256;
        TH1=(65536-50000)/256;                          //两个定时器的初值随便,反正只进一次中断且进中断后延时液与定时器无关
        TL1=(65536-50000)%256;
        EA=1;
        ET0=1;
        ET1=1;
        for(;x>0;x--)
                for(;y>0;y--)
                        {
                                if(fire_sensor==0)                 //如果有热源
                                {
                                         TR0=1;
                                        TR1=1;                                //开启定时器T0,T1
                                }                                                  
                        }
}
void light() interrupt 1
{
        TR0=0;
        TH0=(65536-50000)/256;                          
        TL0=(65536-50000)%256;
        P1=0xfc;               //1111 1000
        delay(1);       //延时多少秒有待测试,根据音乐定,音乐大约33秒        //但是后来发现中断执行是有先后顺序的,就像语句一样,中断1第一遍执行完了之后才会开始执行中断2的第一遍       
    if(sound_sensor==0)                //如果有声音  //在中断1或3里面检测是否应该关灯与停止放音乐,而不是在main中,因为main函数这部分语句只执行一次,可能等不到有声音就执行过去了
        {  
                TR0=0;
                TR1=0;
                P1=0xff;//关掉led
                BEEP=1;
                delay(1000);
        }  
        TR0=1;
}
void sound() interrupt 3
{
        TR1=0;
        TH1=(65536-50000)/256;                          
        TL1=(65536-50000)%256;
        while(1)
        {
                   Play_Music();       //生日快乐
                   delay10us(250);
        }
        TR1=1;
//        if(sound_sensor==0)                //如果有声音  //在中断1或3里面检测是否应该关灯与停止放音乐,而不是在main中,因为main函数这部分语句只执行一次,可能等不到有声音就执行过去了
//        {
//        P1=0xff;//关掉led
//        EA=0;
//        delay(1);
//        }
}
void Play_Music()
{
  uint k,n;
  uint SoundLong,SoundTone;
  uint i,j,m;
  do
  {
     if(i>=25) i=0;
     SoundLong=SOUNDLONG[i];
     SoundTone=SOUNDTONE[i];
     i++;
     for(n=0;n<SoundLong;n++)
      {
      for(k=0;k<12;k++)
       {
           BEEP=0;
           for(m=0;m<SoundTone;m++);
           BEEP=1;
           for(m=0;m<SoundTone;m++);
          }
      }
      delay50us(6);
  }while((SOUNDLONG[i]!=0)||(SOUNDTONE[j]!=0));               
}
void delay50us(uchar time)
{
  uchar a,b;
  for(a=0;a<time;a++)
    for(b=0;b<6;b++);
}
void delay10us(uchar time)
{
  uchar a,b,c;
  for(a=0;a<time;a++)
     for(b=0;b<10;b++)
             for(c=0;c<120;c++);
}
void delay(uint z)
{
        uint i,j;
        for(i=z;i>0;i--)
                for(j=110;j>0;j--);
}

能给图看看吗

第一张是板子和传感器整个


这是单片机左边接线


这是右边接线


上面是声音传感器,下面是火焰传感器。


谢谢,看懂了,确实不用中断,下载好后没问题了。我写太复杂了。

已解决,下面是完整程序。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit  BEEP=P2^3;                 //蜂鸣器
sbit fire_sensor=P3^0;//定义火焰传感器管脚
sbit sound_sensor=P3^1;  //定义声音传感器管脚。
void delay50us(uchar time);
uchar code SOUNDLONG[]=       //控制音调
{
  18,6,24,24,24,48,
  18,6,24,24,24,48,
  18,6,24,24,24,24,24,
  18,6,24,24,24,48,0
};
uchar code SOUNDTONE[]=       //控制音色
{
212,212,190,212,159,169,
212,212,190,212,142,159,
212,212,106,126,159,169,190,
119,119,126,159,142,159,0        //生日快乐end
};
unsigned char Play_Music()
{
  uint k,n;
  uint SoundLong,SoundTone;
  uint i,j,m;
  do
  {
     if(i>=25) i=0;
     SoundLong=SOUNDLONG[i];
     SoundTone=SOUNDTONE[i];
     i++;
     for(n=0;n<SoundLong;n++)
      {
              for(k=0;k<12;k++)
               {
                 if(sound_sensor==0)        //如果有声音(吹气)
                  {
                        return 1;
                 }
           BEEP=0;
           for(m=0;m<SoundTone;m++);
           BEEP=1;
           for(m=0;m<SoundTone;m++);
         }
      }
      delay50us(6);
          if(sound_sensor==0)        //如果有声音(吹气)
          {
                return 1;
          }
  }
  while((SOUNDLONG[i]!=0)||(SOUNDTONE[j]!=0));   
  return 0;
}
void delay50us(uchar time)
{
  uchar a,b;
  for(a=0;a<time;a++)
    for(b=0;b<6;b++);
}

void main()
{
        uint x,y;         //60秒内检测是否有热源,开机超过60秒不再检测
        for(x=60000;x>0;x--)
                for(y=110;y>0;y--)
                        {
                                if(fire_sensor==0)        //如果有热源
                                {
                                         P1=0x00; //开led
                                         while(1)
                                          {
                                                           if( Play_Music())     //一直生日快乐直到吹气退出
                                                    {
                                                                 P1=0xff; //关掉led
                                                                 BEEP=1;//关蜂鸣器
                                                            break;
                                                    }
                                          }
                                             break;//跳出检测
                                }                                                   
                        }
while(1);
}

原来那个版本音乐难听,现在修改了音乐,比较和听,重发一下。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit  BEEP=P2^3;                 //蜂鸣器
sbit fire_sensor=P3^0;//定义火焰传感器管脚
sbit sound_sensor=P3^1;  //定义声音传感器管脚。
sbit light_sensor=P3^2;//定义光电传感器管脚
//生日快乐歌的音符频率表,不同频率由不同的延时来决定
uchar code SONG_TONE[]=
{
        212,212,190,212,
        159,169,212,212,
        190,212,142,159,
        212,212,106,126,
        159,169,190,119,
        119,126,159,142,
        159,0
};
//生日快乐歌节拍表,节拍决定每个音符的演奏长短
uchar code SONG_LONG[]=
{
        9,3,12,12,                                           //9,3,12,12
        12,24,9,3,                                           //12,24,9,3
        12,12,18,24,                                   //12,12,12,24
        10,4,20,20,                                           //9,3,12,12
        19,14,14,12,                                           //12,12,12,9
        8,16,16,16,                                           //3,12,12,12
        24,0                                                   //24,0
};
void DelayMS(uint x)
{
uchar t;
while(x--)
        {
                for(t=0;t<80;t++);            //播放函数        yuanlai s 120                
        }
}
uint PlayMusic()                                                          //大改
{
        uint i=0,j,k;
        while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
        {
                 //播放各个音符,SONG_LONG 为拍子长度
                for(j=0;j<SONG_LONG[i]*30;j++)                  //20
                {
                if(sound_sensor==0)
                        {
                                P1=0xff;
                                BEEP=1;
                                return 1;                  //return 1?
                        }                  
                        BEEP=~BEEP;
                        //SONG_TONE 延时表决定了每个音符的频率
                        for(k=0;k<SONG_TONE[i]/3;k++)         ;  //3                                       
                }
                        DelayMS(30);//yuanlai s 10
                        i++;
        }
        return 0;                //return 0?
}
        //光电传感器要实现的功能:在有光(光太强)时不能点亮蜡烛,在无光(弱光)时可以点亮蜡烛
void main()
{                                                                                          
                             while(1)
                                                         {
                                if((fire_sensor==0)&&(light_sensor==1))        //如果有热源,且没光(或弱光)
                                {
                                         P1=0x00; //开led                                               
                                         while(1)
                                          {
                                                           if( PlayMusic())     //一直生日快乐直到吹气退出
                                                    {
                                                                 P1=0xff; //关掉led
                                                                 BEEP=1;//关蜂鸣器
                                                            break;       
                                                    }                   
                                          }                          
                                                                                                 //break是跳出最近的循环
                                }            
                                                                                                                 
                              }          
                                                 
}

串口那块不太懂,想问下,下面是书上程序
uchar readbyte()
{
      uchar i,k;
      SCL=0;
      delay();
      SDA=1;
      for(i=0;i<8;i--)
      {
            SCL=1;
            delay();
            k=(k<<1)|SDA;//这一句看不懂,不知道为什么就能完成8位的接收
            SCL=0;
            delay();
      }
       delay();
       return k;
}
书上的解释是:串行接收一个字节时需要将8位一位一位地接收,然后再组合成一个字节,上面代码中我们定义了一个临时变量k,将k左移一位后与SDA进行“或”运算,依次把8个独立的位放入一个字节中来完成接收。
它为什么要k<<1之后与SDA1  按位或?怎么完成把8位放入一个字节? 这个字节放入了谁中?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top