要完成的功能是每分钟发送一次短信,除了发短信的时候,其他时候能够通过遥控器控制电机。现在出现问题: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;//将开始之前的计数器时间清零。等到下次进入中断的时候才是引导码真正的时间
- }
- }
复制代码
|