标题:
有没有人你帮忙看看代码?GSM模块工作过后红外遥控功能就不能正常使用了
[打印本页]
作者:
繁弱
时间:
2019-5-8 10:29
标题:
有没有人你帮忙看看代码?GSM模块工作过后红外遥控功能就不能正常使用了
要完成的功能是每分钟发送一次短信,除了发短信的时候,其他时候能够通过遥控器控制电机。现在出现问题:GSM第一次发短信之前遥控器正常使用,发过短信之后红外不能使用或者出现乱码等异常情况
有没有人能帮我看看代码!!!(╥╯^╰╥)
#include<reg51.h>
#include <reg51.h> //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
#include <intrins.h> //包含_nop_()函数定义的头文件
#define FOSC_110592M //单片机的晶振大小
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P3^3;
sbit dianji=P1^6;
uint8 irtime; //接收时间
uint8 startflag; //开始检测
uint8 bitnum; //bit位数
uint8 irdata[33]; //寄存没有个bit的时间
uint8 irreceok; //接收完成标志位
uint8 ircode[4]; //将接收的四个字节数据保存
uint8 irprosok; //接收数据处理标志位
sbit rs=P1^0; //1602数据/命令选择引脚 H:数据 L:命令
sbit rw=P1^1; //1602读写引脚 H:数据寄存器 L:指令寄存器
sbit e =P1^2; //1602使能引脚 下降沿触发
//GSM发送短信
uchar text[9]="shidu:00%";
uchar SIM_text[];//GSM接线:5VT==P3.0 5VR==P3.1
/********************************************************************
* 名称 : Delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Delay_uint(uint q)
{
while(q--);
}
/***********************1ms延时函数*****************************/
void Delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/***********************LCD1602程序*****************************/
/********************************************************************
* 名称 : LCD_write_com(uchar com)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void LCD_write_com(uchar com)
{
e=0;
rs=0;
rw=0;
P0=com;
Delay_uint(3);
e=1;
Delay_uint(25);
e=0;
}
/********************************************************************
* 名称 : LCD_write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void LCD_write_data(uchar dat)
{
e=0;
rs=1;
rw=0;
P0=dat;
Delay_uint(3);
e=1;
Delay_uint(25);
e=0;
}
/********************************************************************
* 名称 : LCD_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
LCD_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void LCD_string(uchar hang,uchar add,uchar *d)
{
if(hang==1)
LCD_write_com(0x80+add);
else
LCD_write_com(0x80+0x40+add);
while(1)
{
if(*d == '\0')
break;
LCD_write_data(*d);
d++;
}
}
/********************************************************************
* 名称 : init_1602()
* 功能 : 初始化1602液晶
* 输入 : 无
* 输出 : 无
***********************************************************************/
void init_1602()
{
LCD_write_com(0x38); //初始化
LCD_write_com(0x0c);
LCD_write_com(0x06);
LCD_write_com(0x01);
Delay_uint(100); //延时
}
void int0init()
{
EA=1;
EX0=1;
IT0=1;
}
void time0init()
{
TMOD=0X02; //设置定时器0模式2.该模式为自动装载模式
TH0=0X00;
TL0=0X00;//设定计数初值,每当TL0计数到255时,TH0将把自己的数据给TL0,又重新计数
TR0=1;
ET0=1;
EA=1;
}
void irpros() //红外接收数据处理 ,区分是数据0还是1
{
uint8 i,j,value;
uint8 k=1; //引导码去掉,所以令k=1;
for(j=0;j<4;j++) //取出了一帧数据中的四个字节数据
{
for(i=0;i<8;i++) //取出了一个字节的数据
{
value>>=1;
if(irdata[k]>6)
{
value=value|0x80;
}
k++;
}
ircode[j]=value;
}
irprosok=1;
}
void motopros()
{
if(ircode[2]==0x0c) //按下第一次按键开电机
{
beep=~beep;
dianji=0;
Delay_1ms(100);
}
else if(ircode[2]==0x18) //按下第二次此按键时关闭电机
{
beep=1;
dianji=1;
}
if(ircode[2]==0x5e)
{
//Gsm_send(2);
}
}
/*******************GSM*************************/
//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
void GSM_inti()//初始化程序(必须使用,否则无法收发)
{
TMOD=0x20;//定时器1操作模式2:8位自动重载定时器
#ifdef FOSC_12M //在这里根据晶振大小设置不同的数值初始化串口
TH1=0xf3;//装入初值,波特率2400
TL1=0xf3;
#else
TH1=0xfd;//装入初值,波特率9600
TL1=0xfd;
#endif //end of SOC_12M
TR1=1;//打开定时器
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
/*串行通讯中断,收发完成将进入该中断*/
void Serial_interrupt() interrupt 4
{
// a=SBUF;
P2=SBUF;
RI=0;//接收中断信号清零,表示将继续接收
// flag=1;//进入中断的标志符号
}
void Uart1Send(uchar c)
{
SBUF=c;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
}
//串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
str++;
}
}
//延时函数大概是1s钟,不过延时大的话不准...
void DelaySec(int sec)
{
uint i , j= 0;
for(i=0; i<sec; i++)
{
for(j=0; j<65535; j++)
{
}
}
}
void Gsm_send()
{
Uart1Sends("AT+CSCS=\"GSM\"\r\n");
DelaySec(3);//延时3秒
Uart1Sends("AT+CMGF=1\r\n");
DelaySec(3);//延时3秒
Uart1Sends("AT+CMGS=\"17338711000\"\r\n");//此处修改为对方的电话号
DelaySec(5);//延时3秒
Uart1Sends(text);//修改短信内容
Uart1Send(0x1a);
//DelaySec(13);//延时20秒
}
void main()
{
int k;
init_1602();
int0init();
time0init();
while(1)
{
irpros();
motopros();
if(k==12000)
{
LCD_string(1,12,"ing");
GSM_inti();
Gsm_send();
beep=~beep;
Delay_1ms(100);
k=0;
}
else
{
LCD_string(1,12,"no ");
k++;
}
}
}
void time0() interrupt 1
{
irtime++;//每进来一次就说明定时时间为256us;
}
void init0() interrupt 0
{
if(startflag)
{
if(irtime>32)//检测引导码,求法是用引导码时间除以一次计数时间,看看要多少次
{
bitnum=0;
}
irdata[bitnum]=irtime;
irtime=0;
bitnum++;
if(bitnum==33)
{
bitnum=0;
irreceok=1;//一帧红外数据接收完成标志
}
}
else
{
startflag=1;//将开始标志位置1,等到下次进入中断即可进入if语句
irtime=0;//将开始之前的计数器时间清零。等到下次进入中断的时候才是引导码真正的时间
}
}
复制代码
作者:
QZQ1973
时间:
2019-5-8 12:56
自己不懂,没法帮到你,只能帮你顶上来吧!
作者:
小猫要吃鱼
时间:
2019-5-10 17:32
没有仔细看程序,感觉应该是串口发送中断和红外外部接收中断有冲突了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1