找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1566|回复: 2
收起左侧

有没有人你帮忙看看代码?GSM模块工作过后红外遥控功能就不能正常使用了

[复制链接]
ID:480386 发表于 2019-5-8 10:29 | 显示全部楼层 |阅读模式
要完成的功能是每分钟发送一次短信,除了发短信的时候,其他时候能够通过遥控器控制电机。现在出现问题:GSM第一次发短信之前遥控器正常使用,发过短信之后红外不能使用或者出现乱码等异常情况

有没有人能帮我看看代码!!!(╥╯^╰╥)

  1. #include<reg51.h>
  2. #include <reg51.h>                 //调用单片机头文件
  3. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  4. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535
  5. #include <intrins.h>                 //包含_nop_()函数定义的头文件
  6. #define FOSC_110592M                 //单片机的晶振大小
  7. typedef unsigned char uint8;
  8. typedef unsigned int uint16;
  9. typedef unsigned int u16;          //对数据类型进行声明定义
  10. typedef unsigned char u8;

  11. sbit beep=P3^3;
  12. sbit dianji=P1^6;

  13. uint8 irtime;          //接收时间
  14. uint8 startflag;  //开始检测
  15. uint8 bitnum;          //bit位数
  16. uint8 irdata[33]; //寄存没有个bit的时间
  17. uint8 irreceok;          //接收完成标志位
  18. uint8 ircode[4];  //将接收的四个字节数据保存
  19. uint8 irprosok;          //接收数据处理标志位

  20. sbit rs=P1^0;         //1602数据/命令选择引脚 H:数据              L:命令
  21. sbit rw=P1^1;         //1602读写引脚                 H:数据寄存器          L:指令寄存器
  22. sbit e =P1^2;         //1602使能引脚          下降沿触发

  23. //GSM发送短信
  24. uchar text[9]="shidu:00%";
  25. uchar SIM_text[];//GSM接线:5VT==P3.0 5VR==P3.1

  26. /********************************************************************
  27. * 名称 : Delay_uint()
  28. * 功能 : 小延时。
  29. * 输入 : 无
  30. * 输出 : 无
  31. ***********************************************************************/
  32. void Delay_uint(uint q)
  33. {
  34.         while(q--);
  35. }


  36. /***********************1ms延时函数*****************************/
  37. void Delay_1ms(uint q)
  38. {
  39.         uint i,j;
  40.         for(i=0;i<q;i++)
  41.                 for(j=0;j<120;j++);
  42. }

  43. /***********************LCD1602程序*****************************/
  44. /********************************************************************
  45. * 名称 : LCD_write_com(uchar com)
  46. * 功能 : 1602命令函数
  47. * 输入 : 输入的命令值
  48. * 输出 : 无
  49. ***********************************************************************/
  50. void  LCD_write_com(uchar com)
  51. {
  52.         e=0;
  53.         rs=0;
  54.         rw=0;
  55.         P0=com;
  56.         Delay_uint(3);
  57.         e=1;
  58.         Delay_uint(25);
  59.         e=0;
  60. }

  61. /********************************************************************
  62. * 名称 : LCD_write_data(uchar dat)
  63. * 功能 : 1602写数据函数
  64. * 输入 : 需要写入1602的数据
  65. * 输出 : 无
  66. ***********************************************************************/
  67. void  LCD_write_data(uchar dat)
  68. {
  69.         e=0;
  70.         rs=1;
  71.         rw=0;
  72.         P0=dat;
  73.         Delay_uint(3);
  74.         e=1;
  75.         Delay_uint(25);
  76.         e=0;       
  77. }

  78. /********************************************************************
  79. * 名称 :  LCD_string(uchar hang,uchar add,uchar *p)
  80. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  81.                    LCD_string(1,5,"ab cd ef;")
  82. * 输入 : 行,列,需要输入1602的数据
  83. * 输出 : 无
  84. ***********************************************************************/
  85. void  LCD_string(uchar hang,uchar add,uchar *d)
  86. {
  87.         if(hang==1)   
  88.                 LCD_write_com(0x80+add);
  89.         else
  90.                 LCD_write_com(0x80+0x40+add);
  91.                 while(1)
  92.                 {
  93.                         if(*d == '\0')  
  94.                                 break;
  95.                         LCD_write_data(*d);
  96.                         d++;
  97.                 }       
  98. }

  99. /********************************************************************
  100. * 名称 : init_1602()
  101. * 功能 : 初始化1602液晶
  102. * 输入 : 无
  103. * 输出 : 无
  104. ***********************************************************************/
  105. void init_1602()
  106. {
  107.          LCD_write_com(0x38);          //初始化
  108.          LCD_write_com(0x0c);
  109.          LCD_write_com(0x06);
  110.          LCD_write_com(0x01);
  111.          Delay_uint(100);          //延时

  112. }
  113. void int0init()
  114. {
  115.         EA=1;
  116.         EX0=1;
  117.         IT0=1;
  118. }
  119. void time0init()
  120. {
  121.         TMOD=0X02;        //设置定时器0模式2.该模式为自动装载模式
  122.         TH0=0X00;
  123.         TL0=0X00;//设定计数初值,每当TL0计数到255时,TH0将把自己的数据给TL0,又重新计数
  124.         TR0=1;
  125.         ET0=1;
  126.         EA=1;       
  127. }
  128. void irpros() //红外接收数据处理 ,区分是数据0还是1
  129. {
  130.         uint8 i,j,value;
  131.         uint8 k=1;        //引导码去掉,所以令k=1;
  132.         for(j=0;j<4;j++)  //取出了一帧数据中的四个字节数据
  133.         {
  134.                 for(i=0;i<8;i++)        //取出了一个字节的数据               
  135.                 {
  136.                         value>>=1;
  137.                         if(irdata[k]>6)
  138.                         {
  139.                                 value=value|0x80;
  140.                         }
  141.                         k++;
  142.                 }
  143.                 ircode[j]=value;
  144.         }
  145.         irprosok=1;
  146. }
  147. void motopros()
  148. {
  149.         if(ircode[2]==0x0c)  //按下第一次按键开电机
  150.         {                       
  151.                 beep=~beep;
  152.                 dianji=0;
  153.                 Delay_1ms(100);                                                       
  154.         }
  155.         else if(ircode[2]==0x18)        //按下第二次此按键时关闭电机
  156.         {
  157.                 beep=1;       
  158.                 dianji=1;               
  159.         }
  160.         if(ircode[2]==0x5e)
  161.         {
  162.                 //Gsm_send(2);
  163.         }                               
  164. }

  165. /*******************GSM*************************/
  166. //注意,无论接收到信号还是发送完信号,都会进中断服务程序的
  167. /*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
  168. void GSM_inti()//初始化程序(必须使用,否则无法收发)
  169. {
  170.         TMOD=0x20;//定时器1操作模式2:8位自动重载定时器

  171. #ifdef FOSC_12M                   //在这里根据晶振大小设置不同的数值初始化串口
  172.         TH1=0xf3;//装入初值,波特率2400
  173.         TL1=0xf3;       
  174. #else        
  175.         TH1=0xfd;//装入初值,波特率9600
  176.         TL1=0xfd;
  177. #endif //end of SOC_12M
  178.        
  179.         TR1=1;//打开定时器
  180.         SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
  181.         SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
  182.         REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
  183.         EA=1;//开总中断
  184.         ES=1;//开串行口中断       
  185. }

  186. /*串行通讯中断,收发完成将进入该中断*/
  187. void Serial_interrupt() interrupt 4
  188. {
  189. //        a=SBUF;
  190.         P2=SBUF;
  191.         RI=0;//接收中断信号清零,表示将继续接收
  192. //        flag=1;//进入中断的标志符号
  193. }


  194. void Uart1Send(uchar c)
  195. {
  196.         SBUF=c;
  197.         while(!TI);//等待发送完成信号(TI=1)出现
  198.         TI=0;       
  199. }

  200. //串行口连续发送char型数组,遇到终止号/0将停止
  201. void Uart1Sends(uchar *str)
  202. {
  203.         while(*str!='\0')
  204.         {
  205.                 SBUF=*str;
  206.                 while(!TI);//等待发送完成信号(TI=1)出现
  207.                 TI=0;
  208.                 str++;
  209.         }
  210. }

  211. //延时函数大概是1s钟,不过延时大的话不准...
  212. void DelaySec(int sec)
  213. {
  214.         uint i , j= 0;

  215.         for(i=0; i<sec; i++)
  216.         {
  217.                 for(j=0; j<65535; j++)
  218.                 {       
  219.                 }
  220.         }
  221. }


  222. void Gsm_send()
  223. {
  224.                         Uart1Sends("AT+CSCS=\"GSM\"\r\n");
  225.                         DelaySec(3);//延时3秒
  226.                         Uart1Sends("AT+CMGF=1\r\n");
  227.                         DelaySec(3);//延时3秒
  228.                         Uart1Sends("AT+CMGS=\"17338711000\"\r\n");//此处修改为对方的电话号
  229.                         DelaySec(5);//延时3秒
  230.                         Uart1Sends(text);//修改短信内容
  231.                         Uart1Send(0x1a);
  232.                         //DelaySec(13);//延时20秒
  233. }

  234. void main()
  235. {
  236.         int k;
  237.         init_1602();
  238.         int0init();
  239.         time0init();
  240.         while(1)
  241.         {
  242.                 irpros();
  243.                 motopros();
  244.                 if(k==12000)
  245.                 {
  246.                         LCD_string(1,12,"ing");
  247.                         GSM_inti();
  248.                         Gsm_send();
  249.                         beep=~beep;
  250.                         Delay_1ms(100);
  251.                         k=0;
  252.                 }
  253.                 else
  254.                 {
  255.                         LCD_string(1,12,"no ");
  256.                         k++;
  257.                 }
  258.                        
  259.         }               
  260. }
  261. void time0() interrupt 1
  262. {
  263.         irtime++;//每进来一次就说明定时时间为256us;       
  264. }
  265. void init0() interrupt 0
  266. {
  267.         if(startflag)
  268.         {
  269.                 if(irtime>32)//检测引导码,求法是用引导码时间除以一次计数时间,看看要多少次
  270.                 {
  271.                         bitnum=0;       
  272.                 }
  273.                 irdata[bitnum]=irtime;
  274.                 irtime=0;
  275.                 bitnum++;
  276.                 if(bitnum==33)
  277.                 {
  278.                         bitnum=0;
  279.                         irreceok=1;//一帧红外数据接收完成标志
  280.                 }
  281.         }
  282.         else
  283.         {
  284.                 startflag=1;//将开始标志位置1,等到下次进入中断即可进入if语句
  285.                 irtime=0;//将开始之前的计数器时间清零。等到下次进入中断的时候才是引导码真正的时间
  286.         }
  287. }
复制代码



回复

使用道具 举报

ID:512205 发表于 2019-5-8 12:56 | 显示全部楼层
自己不懂,没法帮到你,只能帮你顶上来吧!
回复

使用道具 举报

ID:497670 发表于 2019-5-10 17:32 | 显示全部楼层
没有仔细看程序,感觉应该是串口发送中断和红外外部接收中断有冲突了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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