找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机电动车GSM遥控报警器,程序出现了死循环没有跳出

[复制链接]
跳转到指定楼层
楼主
ID:684626 发表于 2020-1-10 14:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
根据论坛里51单片机GSM报警器的程序,写的用遥控器来控制GSM报警器开和关,现在遥控可以打开报警器工作,不能关闭。出现问题的原因应该是在报警程序里出现了死循环没有跳出来,有啥解决思路?单片机源程序如下:

  1. #include<reg52.h>
  2. #include <intrins.h>
  3. #include <absacc.h>                         //头文件

  4. #define uint unsigned int
  5. #define uchar unsigned char        //宏定义

  6. sbit BUZZ=P2^3;                                   //蜂鸣器
  7. sbit shake=P3^7;                           //震动传感器
  8. sbit LED_B=P1^3;                           //布防指示灯         蓝色
  9. sbit LED_S=P1^6;                           //短信指示灯         绿色
  10. sbit LED_J=P1^0;                           //报警指示灯         红色

  11. uchar code PhoneNO[]="13151993977";                //接受号码
  12. uchar code somebody[]="8BF76CE8610FFF0167094EBA8FDB516562A58B66830356F4FF01";        //请注意!有人进入报警范围!                                                                                                  

  13. uint TIME_50ms=0;                           //计时的最小分辨率50ms
  14. uint time_continue;                           //蜂鸣器鸣响时计时数据暂存
  15. bit flag=0,flag_BF=0;                  //flag:值为0时,是布防计时模式,值为1时,是一分钟等待模式。flag_BF:布防标志位
  16. bit flag_time_start=0;                 //开始计时标志位
  17. bit again=0;                                   //一分钟等待标志位(当发送一条短信后,不能马上发送第二天,所以等待一分钟后再检测是否有人,有人再发送短信)
  18. bit flag_alam;                                   //报警标志位
  19. bit flag_continue;                           //继续计时

  20. sbit IR=P3^2;                          //红外接口标志
  21. unsigned char  irtime;        //红外用全局变量
  22. bit irpro_ok,irok;
  23. bit key1,key2;                        //开关键
  24. unsigned char IRcord[4];
  25. unsigned char irdata[33];

  26. void delay(uint z)                           //延时函数
  27. {
  28.         uint x,y;
  29.         for(x=z;x>0;x--)
  30.         for(y=222;y>0;y--);
  31. }

  32. void tim0_isr (void) interrupt 1            //定时器0中断
  33. {
  34.   irtime++;                                                          //用于计数2个下降沿之间的时间
  35. }

  36. void EX0_ISR (void) interrupt 0                 //外部中断0服务函数           红外接收信号
  37. {
  38.         static unsigned char  i;             //接收红外信号处理
  39.         static bit startflag;                //是否开始处理标志位
  40.         if(startflag)                        
  41.         {
  42.                 if(irtime<53&&irtime>=32)                //引导码 TC9012的头码,9ms+4.5ms
  43.             i=0;
  44.                     irdata[i]=irtime;                        //存储每个电平的持续时间,用于以后判断是0还是1
  45.                     irtime=0;
  46.                     i++;
  47.                            if(i==33)
  48.                       {
  49.                                   irok=1;
  50.                                 i=0;
  51.                           }
  52.         }
  53.         else
  54.         {
  55.                 irtime=0;
  56.                 startflag=1;
  57.         }
  58. }

  59. void Uart_init()        //中断初始化
  60. {
  61.         TMOD |= 0X20;                //T1方式2,8位自动重装   
  62.         TH1=0Xfd;
  63.         TL1=0Xfd;            // 9600波特率
  64.         TR1=1;                     // 定时器1启动  
  65.         SM0=0;                    // 设置串口的工作模式
  66.         SM1=1;                     // 方式1
  67.         REN=1;                          // 允许串口接收数据          
  68.         ES=1;                        // 串口中断应许
  69.         EA=1;                    // 开启中断
  70.                
  71.         TMOD |= 0X02;
  72.         TH0=0x00; //重载值
  73.         TL0=0x00; //初始化值
  74.         ET0=1;    //开中断
  75.         TR0=1;

  76.         IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  77.         EX0 = 1;   //使能外部中断
  78. }

  79. void Ir_work(void)                        //红外键值散转程序
  80. {
  81.        switch(IRcord[2])        //判断第三个数码值
  82.                  {
  83.                          case 0x15:key1=0,key2=1;break;//key1 开启 对应按键为+
  84.                          case 0x07:key2=0,key1=1;break;//key2 关闭 对应按键为-
  85.              default:break;
  86.                          }
  87. }

  88. void Ircordpro(void)//红外码值处理函数
  89. {
  90.         unsigned char i, j, k,cord,value;
  91.         k=1;
  92.         for(i=0;i<4;i++)      //处理4个字节
  93.         {
  94.                 for(j=1;j<=8;j++) //处理1个字节8位
  95.                 {
  96.                         cord=irdata[k];
  97.                         if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
  98.                         value=value|0x80;
  99.                         if(j<8)
  100.                         {
  101.                                 value>>=1;
  102.                         }
  103.                         k++;
  104.                 }
  105.                 IRcord[i]=value;
  106.                 value=0;     
  107.         }
  108.         irpro_ok=1;//处理完毕标志位置1
  109. }

  110. void SendASC(uchar d)        //串口发送字符
  111. {
  112.        
  113.         SBUF=d;                                //数据赋值到缓冲区
  114.         while(!TI);                        //发送完
  115.         TI=0;                                //清零
  116. }

  117. void SendString(uchar *str)          //串口发送字符串
  118. {
  119.         while(*str)                                  //判断是否发送完,不为\0时继续发送
  120.         {
  121.                 SendASC(*str) ;                  //发送字符
  122.                 str++;                                  //字符位置加
  123.                 delay(1);
  124.         }
  125. }

  126. void TIME()                                                //计时函数
  127. {
  128.         if(flag==0)                                        //布防计时模式
  129.         {
  130.                 delay(50);                                //50ms
  131.                 TIME_50ms++;                        //50ms变量加1
  132.                 if(TIME_50ms%10==0)                //每500ms(50ms*10)
  133.                 LED_B=!LED_B;                        //布防指示灯取反一次               
  134.                 if(TIME_50ms>20)                //加到20次,也就是50ms*20=5000ms=1s
  135.                 {
  136.                         TIME_50ms=0;                //计时变量清零
  137.                         flag_BF=1;                        //进入布防状态
  138.                         LED_B=0;                        //布防指示灯长亮
  139.                         flag_time_start=0;        //停止计时
  140.                         again=1;                        //关闭一分钟等待
  141.                 }       
  142.         }
  143.         else                                                //一分钟等待模式
  144.         {
  145.                 delay(50);                                //50ms
  146.                 TIME_50ms++;                        //变量加
  147.                 if(TIME_50ms%10==0)                //每加500ms
  148.                 {
  149.                         LED_B=!LED_B;                //布防指示灯闪烁
  150.                         if(flag_alam==1)        //报警
  151.                         {
  152.                                 if(flag_continue==0)                        //进入报警时
  153.                                 {
  154.                                         flag_continue=1;                         //此标志位置一,防止报警时进入
  155.                                         time_continue=TIME_50ms;        //将进入报警时的计时数据暂存
  156.                                 }
  157.                                 BUZZ=!BUZZ;                                                //蜂鸣器取反,也就是闪烁响
  158.                                 LED_J=~LED_J;
  159.                                 if(TIME_50ms>=time_continue+100)//当报警时间达到5s时
  160.                                 {
  161.                                         BUZZ=1;       
  162.                                         LED_J=1;                                        //关闭蜂鸣器
  163.                                         flag_continue=0;                        //标志位清零,等待下次报警
  164.                                         flag_alam=0;                                //报警变量清零,停止报警
  165.                                         time_continue=0;                        //暂存计时数据清零
  166.                                 }       
  167.                         }
  168.                 }
  169.                 if(TIME_50ms>=1200)                   //计时达到60秒
  170.                 {
  171.                         LED_B=0;                           //布防指示灯长亮,准备检测热释电信号
  172.                         TIME_50ms=0;                   //计时变量清零
  173.                         flag_time_start=0;           //停止计时
  174.                         again=1;                           //关闭一分钟等待
  175.                 }
  176.         }
  177. }

  178. void keyscan()                                                //按键扫描函数
  179. {
  180.         if(key1==0&&key2==1&&flag_BF==0)                 //在非布防状态时布防按键按下
  181.         {
  182.                 delay(5);                                        //延时去抖
  183.                 if(key1==0&&key2==1)                                    //再次判断按键是否按下
  184.                 {
  185.                         LED_B=0;                            //点亮布防LED灯
  186.                         flag=0;                                    //变量清零
  187.                         flag_time_start=1;      //开始计时变量置一
  188.                 }
  189.         }
  190.         if(flag_time_start==1)                        //开始计时
  191.         {
  192.                 TIME();                                                //调用计时函数
  193.         }
  194.         if(key1==1&&key2==0)                                                //撤防按键按下
  195.         {                          
  196.                 delay(5);                                        //延时去抖
  197.                 if(key1==1&&key2==0)                                    //再次判断按键是否按下
  198.                 {
  199.                         BUZZ=1;                                        //关闭蜂鸣器
  200.                         LED_J=1;
  201.                         flag_alam=0;                        //报警变量清零
  202.                         flag_BF=0;                                //布防变量清零
  203.                         flag=0;                                        //变量清零
  204.                         flag_time_start=0;                //开始计时变量清零
  205.                         LED_S=1;                                //关闭发送短信指示灯
  206.                         LED_B=1;                                //关闭布防指示灯
  207.                 }
  208.         }
  209. }

  210. void GSM_work()                                                //发送GSM短信
  211. {
  212.         unsigned char send_number;                //定义发送手机号的变量
  213.         if(shake==1&&flag_BF==1)                //布防状态且热释电有信号时
  214.         flag_alam=1;                                        //报警变量置一       
  215.         if(shake==1&&flag_BF==1&&again==1)                          //布防状态且热释电有信号时且不在一分钟等待时间内  或者   手动按下紧急按键
  216.         {
  217.                 LED_S=0;                                                                 //打开发送短信指示灯
  218.                 BUZZ=0;                                                                         //打开蜂鸣器
  219.                 LED_J=0;
  220.                 SendString("AT+CMGF=1\r\n");                         //设置文本模式               
  221.                 delay(1000);                                                         //延时,让GSM模块有一个反应时间
  222.                 SendString("AT+CSCS=\"UCS2\"\r\n");                 //设置短信格式,发送汉字模式               
  223.                 delay(1000);                                                         //延时       
  224.                 SendString("AT+CSMP=17,167,0,25\r\n");
  225.                 delay(1000);               
  226.                 SendString("AT+CMGS=");                                                         //信息发送指令 AT+CMGS=
  227.                 SendASC('"');                                                                         //引号
  228.                 for(send_number=0;send_number<11;send_number++)         //在每位号码前加003
  229.                 {
  230.                         SendASC('0');
  231.                         SendASC('0');
  232.                         SendASC('3');
  233.                         SendASC(PhoneNO[send_number]);                                 //接收手机号码
  234.                 }     
  235.                 SendASC('"');                                                                         //引号
  236.                 SendASC('\r');                                //发送回车指令
  237.                 SendASC('\n');                                //发送换行指令               
  238.                 delay(1000);                                //延时
  239.                 SendString(somebody);                //发送短信内容       
  240.                 delay(1000);                                //延时               
  241.                 SendASC(0x1a);                                //确定发送短信               
  242.                 again=0;                                        //again清零,也就是进入一分钟等待,当计时到一分钟后,该变量重新置一
  243.                 flag_time_start=1;                        //开始计时
  244.                 flag_alam=1;                                //报警               
  245.                 LED_S=1;                                        //熄灭发送短信指示灯
  246.                 flag=1;                                                //变量置一
  247.         }
  248. }

  249. void main()                                                                //主函数
  250. {       
  251.         Uart_init();                                                //调用中断初始化函数
  252.         while(1)                                                        //进入while循环
  253.         {
  254.                 if(irok)                        //如果接收好了进行红外处理
  255.                 {   
  256.                         Ircordpro();                                //红外码值处理函数,处理完成irpro_ok=1
  257.                         irok=0;
  258.                 }
  259.                 if(irpro_ok)                   //如果处理好后进行工作处理
  260.                 {
  261.                         Ir_work();
  262.                          irpro_ok=0;                                        //处理完成标志
  263.                 }       
  264.                 keyscan();                                                //按键函数
  265.                 GSM_work();                                                //发送短信函数       
  266.         }          
  267. }
复制代码




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

使用道具 举报

沙发
ID:404160 发表于 2020-1-13 20:29 | 只看该作者
死循环处,加一段延时程序。简单的说做10000次加法。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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