找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3011|回复: 4
收起左侧

求大师指导为啥我的单片机STC51红外遥控程序,按着按着就死机了,需要复位才好

[复制链接]
ID:404202 发表于 2018-11-1 12:45 | 显示全部楼层 |阅读模式


//----------------------------------------------------------------------------------------------------------------------------------
//程序名
//程序功能:红外线遥控七色小灯
// --------------------------------------------------------------------------------------------------------------------------------
#include<reg51.h>                                             //头文件
sbit IRIN=P3^2;                                                 //定义红外IR信号输入位
sbit R_LED=P0^0;                             //定义发红光LED控制引脚        
sbit G_LED=P0^1;                             //定义发绿光LED控制引脚
sbit B_LED=P0^2;                             //定义发蓝光LED控制引脚
sbit SPK=P2^7;                               //定义压电喇叭信号输入位
unsigned char IRDATA[7];                             //定义数组,存储红外接收到的数据
void delay(unsigned char x);                 //延时约x*0.1ms 函数
void fs_d ( );                               //发声函数
void IR_ZX();                                //遥控执行函数


//-------------------------------------- 主函数 --------------------------------------


void main()                                   //主函数
{
        EA=1;                                     //允许总中断
    EX0=1;                                    //允许外部中断INT0中断
        IT0=1;                                    //外部中断INT0采用脉冲触发方式
        fs_d ( );
        {       
          IRIN=1;                                 //IR 输入位设置为高电平
          P0=0xff;
             IR_ZX();  
          while(1);                               //无限循环
    }
}


//-------------------------------------- 延时函数  -----------------------------------


void delay(unsigned char x)                           //延时约x*0.1ms  
{                                                                                         
        unsigned char i;                                                                
        while(x--)                                                           
        {for(i=0;i<10;i++){}}                                
}


//------------------------------------- 中断解码函数 ----------------------------------


void IR_IN() interrupt 0 using 0                        //外部中断INT0函数
{
unsigned char j,k,n=0;                                            //定义变量,且n=0
    EX0=0;                                                                            //暂时先关中断
        delay(20);                                                        //延时0.10ms*20=2ms
        if(IRIN==1)                                                //如果IRIN出现高电平,是干扰信号
         {                                                                    
           EX0=1;
           return;                                  //返回                 
         }
        while(!IRIN){delay(1);}                                //避开9ms前导低电平信


   for(j=0;j<4;j++)                                                    //一共有4组数据
     {       
          for(k=0;k<8;k++)                                            //每组数据有8位
         {
   while(IRIN){delay(1);}                            // 避开4.5ms高电平
   while(!IRIN){delay(1);}                                 
// 开始接收数据         
   while(IRIN)                                                 
         {
           delay(1);                                             //延时0.1ms
       n++;                                                             //每过0.1ms时n就加1
           if(n>=30)                                         //如果超过30,放弃
                {                                                              
                  EX0=1;
                  return;}                               //返回
                }
                  
              IRDATA[j]=IRDATA[j]>>1;                //右移1位
          if(n>=8){IRDATA[j]=IRDATA[j]|0x80;}                                                                   
              n=0;                                         //n清0
            }
     }
//检查接收的数据和数据反码是否相反          
    if(IRDATA[2]!=~IRDATA[3])                         //判断数据码和数据反码是不是相反
           {                                                                         //否则就放弃
             EX0=1;
             return;
           }       
//        遥控执行          
     else   
             EX0=1;                                  //开中断
         fs_d ( );                               //调用发声函数       
        }       




//-------------------------------------  发声函数  -----------------------------------------
void fs_d ( )                                                  
  {                                                                                                                   
        unsigned char i;                                               
        for(i=0;i<100;i++)
         {
           delay(4);                                                     
           SPK=~SPK;
         }                                                                        
           SPK=1;
}
            
//------------------------------------  遥控执行函数 --------------------------------------


void IR_ZX()                                       //遥控执行函数
     {
       while(1)
        {
                  switch(IRDATA[2])  
            {
//发红色光   
                         case 0x01:                     
               {
                                 G_LED=1;                          //绿光LED熄灭
                 B_LED=1;                          //蓝光LED熄灭
                 R_LED=0;                          //红光LED亮
                 break;
                          }
//发黄色光         
             case 0x02:                     
               {
                             B_LED=1;                         //蓝光LED熄灭
                 R_LED=0;                         //红光LED亮
                 G_LED=0;                         //绿光LED亮
                 break;
                          }
  //发绿色光               
            case 0x03:                        
               {
                     B_LED=1;                         //蓝光LED熄灭
                 R_LED=1;                         //红光LED灭
                 G_LED=0;                         //绿光LED亮
                 break;
                          }
//发青色光
            case 0x04:                        
               {
                     R_LED=1;                          //红光LED熄灭
                 G_LED=0;                          //绿光LED亮
                 B_LED=0;                          //蓝光LED亮
                 break;
                          }
  //发蓝色光        
             case 0x05:                        
               {
                     R_LED=1;                          //红光LED熄灭
                 G_LED=1;                          //绿光LED熄灭
                 B_LED=0;                          //蓝光LED亮
                 break;
                          }   
  //发紫色光
             case 0x06:                        
               {
                     G_LED=1;                          //绿光LED熄灭
                 R_LED=0;                          //红光LED亮                                   
                 B_LED=0;                          //蓝光LED亮
                 break;
                          }
  //发白色光
             case 0x07:                          
               {
                 R_LED=0;                          //红光LED亮
                 G_LED=0;                          //绿光LED亮
                 B_LED=0;                          //蓝光LED亮
                 break;
                          }
  //关闭彩灯            
                    case 0x08:                           
               {
                     R_LED=1;                          //红光LED熄灭
                 G_LED=1;                          //绿光LED熄灭
                 B_LED=1;                          //蓝光LED熄灭
                 break;
                          }
            }
        }
     }  


//-------------------------------------------------------------------------------------------------  
          
                  
                  
               




回复

使用道具 举报

ID:303383 发表于 2018-11-1 14:03 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

ID:419091 发表于 2018-11-1 14:16 | 显示全部楼层
你在每个while内设断点,然后Debug运行,看看卡在哪里了,应该是卡在某一个while循环里出不来了
回复

使用道具 举报

ID:401564 发表于 2018-11-1 15:36 | 显示全部楼层
用的是STC的单片机吗?
如果是,那就先看一下你所用的单片机的数据手册,重点看时钟,如果你这个程序是在89C52上面的,用在了5A60S2上面肯定是不行的,虽然延时函数一样,但执行的时钟不一样,所以,时间也不一样
而红外检测是要等待一个电平的,有可能是你这个电平已经过了,而且,由于红外发射器的误差,就变成了有时候给收得到,有时候按了没反应,有时候就卡住不再动了.
为了防止它不动,你可以在中断函数里加入看门狗,而在主函数清除看门狗数据,这样一来,只要卡在某个地方了,看门狗会帮你复位的.
以上是按我曾经写过的一个红外程序,用在两个不同的51上面的经验而写的.

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:149144 发表于 2018-11-1 16:56 | 显示全部楼层
unsigned char IRDATA[7] = {‘\0’};
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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