标题:
单片机电动车GSM遥控报警器,程序出现了死循环没有跳出
[打印本页]
作者:
lzliiiiii
时间:
2020-1-10 14:30
标题:
单片机电动车GSM遥控报警器,程序出现了死循环没有跳出
根据论坛里51单片机GSM报警器的程序,写的用遥控器来控制GSM报警器开和关,现在遥控可以打开报警器工作,不能关闭。出现问题的原因应该是在报警程序里出现了死循环没有跳出来,有啥解决思路?单片机源程序如下:
#include<reg52.h>
#include <intrins.h>
#include <absacc.h> //头文件
#define uint unsigned int
#define uchar unsigned char //宏定义
sbit BUZZ=P2^3; //蜂鸣器
sbit shake=P3^7; //震动传感器
sbit LED_B=P1^3; //布防指示灯 蓝色
sbit LED_S=P1^6; //短信指示灯 绿色
sbit LED_J=P1^0; //报警指示灯 红色
uchar code PhoneNO[]="13151993977"; //接受号码
uchar code somebody[]="8BF76CE8610FFF0167094EBA8FDB516562A58B66830356F4FF01"; //请注意!有人进入报警范围!
uint TIME_50ms=0; //计时的最小分辨率50ms
uint time_continue; //蜂鸣器鸣响时计时数据暂存
bit flag=0,flag_BF=0; //flag:值为0时,是布防计时模式,值为1时,是一分钟等待模式。flag_BF:布防标志位
bit flag_time_start=0; //开始计时标志位
bit again=0; //一分钟等待标志位(当发送一条短信后,不能马上发送第二天,所以等待一分钟后再检测是否有人,有人再发送短信)
bit flag_alam; //报警标志位
bit flag_continue; //继续计时
sbit IR=P3^2; //红外接口标志
unsigned char irtime; //红外用全局变量
bit irpro_ok,irok;
bit key1,key2; //开关键
unsigned char IRcord[4];
unsigned char irdata[33];
void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=222;y>0;y--);
}
void tim0_isr (void) interrupt 1 //定时器0中断
{
irtime++; //用于计数2个下降沿之间的时间
}
void EX0_ISR (void) interrupt 0 //外部中断0服务函数 红外接收信号
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<53&&irtime>=32) //引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata[i]=irtime; //存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}
}
void Uart_init() //中断初始化
{
TMOD |= 0X20; //T1方式2,8位自动重装
TH1=0Xfd;
TL1=0Xfd; // 9600波特率
TR1=1; // 定时器1启动
SM0=0; // 设置串口的工作模式
SM1=1; // 方式1
REN=1; // 允许串口接收数据
ES=1; // 串口中断应许
EA=1; // 开启中断
TMOD |= 0X02;
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
}
void Ir_work(void) //红外键值散转程序
{
switch(IRcord[2]) //判断第三个数码值
{
case 0x15:key1=0,key2=1;break;//key1 开启 对应按键为+
case 0x07:key2=0,key1=1;break;//key2 关闭 对应按键为-
default:break;
}
}
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k,cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value=value|0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
void SendASC(uchar d) //串口发送字符
{
SBUF=d; //数据赋值到缓冲区
while(!TI); //发送完
TI=0; //清零
}
void SendString(uchar *str) //串口发送字符串
{
while(*str) //判断是否发送完,不为\0时继续发送
{
SendASC(*str) ; //发送字符
str++; //字符位置加
delay(1);
}
}
void TIME() //计时函数
{
if(flag==0) //布防计时模式
{
delay(50); //50ms
TIME_50ms++; //50ms变量加1
if(TIME_50ms%10==0) //每500ms(50ms*10)
LED_B=!LED_B; //布防指示灯取反一次
if(TIME_50ms>20) //加到20次,也就是50ms*20=5000ms=1s
{
TIME_50ms=0; //计时变量清零
flag_BF=1; //进入布防状态
LED_B=0; //布防指示灯长亮
flag_time_start=0; //停止计时
again=1; //关闭一分钟等待
}
}
else //一分钟等待模式
{
delay(50); //50ms
TIME_50ms++; //变量加
if(TIME_50ms%10==0) //每加500ms
{
LED_B=!LED_B; //布防指示灯闪烁
if(flag_alam==1) //报警
{
if(flag_continue==0) //进入报警时
{
flag_continue=1; //此标志位置一,防止报警时进入
time_continue=TIME_50ms; //将进入报警时的计时数据暂存
}
BUZZ=!BUZZ; //蜂鸣器取反,也就是闪烁响
LED_J=~LED_J;
if(TIME_50ms>=time_continue+100)//当报警时间达到5s时
{
BUZZ=1;
LED_J=1; //关闭蜂鸣器
flag_continue=0; //标志位清零,等待下次报警
flag_alam=0; //报警变量清零,停止报警
time_continue=0; //暂存计时数据清零
}
}
}
if(TIME_50ms>=1200) //计时达到60秒
{
LED_B=0; //布防指示灯长亮,准备检测热释电信号
TIME_50ms=0; //计时变量清零
flag_time_start=0; //停止计时
again=1; //关闭一分钟等待
}
}
}
void keyscan() //按键扫描函数
{
if(key1==0&&key2==1&&flag_BF==0) //在非布防状态时布防按键按下
{
delay(5); //延时去抖
if(key1==0&&key2==1) //再次判断按键是否按下
{
LED_B=0; //点亮布防LED灯
flag=0; //变量清零
flag_time_start=1; //开始计时变量置一
}
}
if(flag_time_start==1) //开始计时
{
TIME(); //调用计时函数
}
if(key1==1&&key2==0) //撤防按键按下
{
delay(5); //延时去抖
if(key1==1&&key2==0) //再次判断按键是否按下
{
BUZZ=1; //关闭蜂鸣器
LED_J=1;
flag_alam=0; //报警变量清零
flag_BF=0; //布防变量清零
flag=0; //变量清零
flag_time_start=0; //开始计时变量清零
LED_S=1; //关闭发送短信指示灯
LED_B=1; //关闭布防指示灯
}
}
}
void GSM_work() //发送GSM短信
{
unsigned char send_number; //定义发送手机号的变量
if(shake==1&&flag_BF==1) //布防状态且热释电有信号时
flag_alam=1; //报警变量置一
if(shake==1&&flag_BF==1&&again==1) //布防状态且热释电有信号时且不在一分钟等待时间内 或者 手动按下紧急按键
{
LED_S=0; //打开发送短信指示灯
BUZZ=0; //打开蜂鸣器
LED_J=0;
SendString("AT+CMGF=1\r\n"); //设置文本模式
delay(1000); //延时,让GSM模块有一个反应时间
SendString("AT+CSCS=\"UCS2\"\r\n"); //设置短信格式,发送汉字模式
delay(1000); //延时
SendString("AT+CSMP=17,167,0,25\r\n");
delay(1000);
SendString("AT+CMGS="); //信息发送指令 AT+CMGS=
SendASC('"'); //引号
for(send_number=0;send_number<11;send_number++) //在每位号码前加003
{
SendASC('0');
SendASC('0');
SendASC('3');
SendASC(PhoneNO[send_number]); //接收手机号码
}
SendASC('"'); //引号
SendASC('\r'); //发送回车指令
SendASC('\n'); //发送换行指令
delay(1000); //延时
SendString(somebody); //发送短信内容
delay(1000); //延时
SendASC(0x1a); //确定发送短信
again=0; //again清零,也就是进入一分钟等待,当计时到一分钟后,该变量重新置一
flag_time_start=1; //开始计时
flag_alam=1; //报警
LED_S=1; //熄灭发送短信指示灯
flag=1; //变量置一
}
}
void main() //主函数
{
Uart_init(); //调用中断初始化函数
while(1) //进入while循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro(); //红外码值处理函数,处理完成irpro_ok=1
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理
{
Ir_work();
irpro_ok=0; //处理完成标志
}
keyscan(); //按键函数
GSM_work(); //发送短信函数
}
}
复制代码
作者:
飞云居士
时间:
2020-1-13 20:29
死循环处,加一段延时程序。简单的说做10000次加法。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1