找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9383|回复: 19
收起左侧

单片机与SIM900A短信控制开关 LED

  [复制链接]
ID:122140 发表于 2016-5-20 11:36 | 显示全部楼层 |阅读模式
单片机与SIM900A短信控制开关,用短信控制LED-51单片机-2

  1.                                                         /************************************************************
  2. 程序说明:
  3. 首先要确定模块已经注册到网络
  4. 然后正确的硬件连接   P3.0-----STXD或者5VT   P3.1-----SRXD或者5VR   GND---GND(只要保证公地即可,没必要单独接一次)
  5. 然后确认你单片机上的晶振,根据晶振修改自己的程序。
  6. 推荐先将单片机与电脑相连,确定单片机发送的数据是正确的。如果发送的是乱码,请检查晶振与单片机的串口波特率。
  7. 如果通过以上几条还解决不了问题,请看群共享文件 AN0004 。

  8. *************************************************************/
  9. #include <REG51.H>
  10. #include <string.H>
  11. #include <intrins.h>
  12. #define uchar unsigned char
  13. #define uint unsigned int
  14. //以下是板子上LED的配置,把Px_x改成自己对应的脚。
  15. //以下是你的51单片机的晶振大小
  16. #define FOSC_110592M
  17. //#define FOSC_12M
  18. sbit P10=P1^0;
  19. sbit P11=P1^1;
  20. sbit P12=P1^2;
  21. sbit P13=P1^3;
  22. sbit P14=P1^4;
  23. sbit P15=P1^5;
  24. //以下是开机后发送到手机的内容,发送的号码在程序中修改。       
  25. uchar flag_rec_message;        //接收到短信标志位
  26. unsigned char flag_reced_mess=0;
  27. unsigned char fenhao_num;        //数据中分号的个数,用来区分短信数据中各个字段的内容
  28. unsigned int  rec_data_len_uart=0;    //标记Buffer_Uart0接收数组
  29. unsigned char flag_rec_message=0;        //收到了一条短信提醒时的标志位,我没有SIM900A模块,为了能让单片机处理,所以直接让此标志位为1,你做的时候
  30.                                         //通过收到短信的提醒要置此标志位。
  31. unsigned char flag_rec_message_data=0;        //开始接收短信数据
  32. unsigned char flag_start_rec_message;        //开始处理短信数据标志位
  33. unsigned char flag_read_or_un_message;        //1 未读取过,0 读取过
  34. unsigned char flag_send_result=0;
  35. unsigned char message_data[20];        //存储短信数据
  36. unsigned char xdata temp_data_read[11],temp_data_tele_num[15],temp_data_date[21];
  37. unsigned char idata Buffer_Uart0_Rec[25]={0};                 //Uart0中断接收数组
  38.    
  39. //注意,无论接收到信号还是发送完信号,都会进中断服务程序的
  40. /*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
  41. void SerialInti()//初始化程序(必须使用,否则无法收发)
  42. {
  43.         TMOD=0x20;//定时器1操作模式2:8位自动重载定时器

  44. #ifdef FOSC_12M                   //在这里根据晶振大小设置不同的数值初始化串口
  45.         TH1=0xf3;//装入初值,波特率2400
  46.         TL1=0xf3;       
  47. #else        
  48.         TH1=0xfd;//装入初值,波特率9600
  49.         TL1=0xfd;
  50. #endif //end of SOC_12M
  51.        
  52.         TR1=1;//打开定时器
  53.         SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
  54.         SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
  55.         REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
  56.         EA=1;//开总中断
  57.         ES=1;//开串行口中断       
  58. }
  59. unsigned char hand(unsigned char *data_source,unsigned char *ptr)
  60. {
  61.         if(strstr(data_source,ptr)!=NULL)
  62.                 return 1;
  63.         else
  64.                 return 0;
  65. }
  66. void clear_rec_data()
  67. {
  68.         uchar i,temp_len;
  69.         temp_len=strlen(Buffer_Uart0_Rec);
  70.         if(temp_len>25)
  71.         {
  72.                 temp_len=25;
  73.         }
  74.         for(i=0;i<25;i++)
  75.         {
  76.                 Buffer_Uart0_Rec[i]='0';       
  77.         }
  78.         rec_data_len_uart=0;
  79. }
  80. void clear_message_data()
  81. {
  82.         unsigned char temp_len,i;
  83.         temp_len=strlen(message_data);
  84.         if(temp_len>20)
  85.         {
  86.                 temp_len=20;
  87.         }
  88.         for(i=0;i<temp_len;i++)
  89.         {
  90.                 message_data[i]='\0';       
  91.         }
  92. }

  93. /*串行通讯中断,收发完成将进入该中断*/
  94. void Serial_interrupt() interrupt 4
  95. {
  96.         unsigned char temp_rec_data_uart0;       
  97.         temp_rec_data_uart0 = SBUF;//读取接收数据               
  98.         RI=0;//接收中断信号清零,表示将继续接收                       
  99.         if((temp_rec_data_uart0=='I')&&(rec_data_len_uart>3))
  100.         {
  101.                 if((Buffer_Uart0_Rec[rec_data_len_uart-1]=='T')&&(Buffer_Uart0_Rec[rec_data_len_uart-2]=='M')&&(Buffer_Uart0_Rec[rec_data_len_uart-3]=='C')&&(Buffer_Uart0_Rec[rec_data_len_uart-4]=='+'))
  102.                 {
  103.                         flag_reced_mess=1;
  104.                 }
  105.         }
  106.         if(flag_rec_message==1)        //如果检测到收到一条短信,开始执行短信数据接收
  107.         {
  108.                 if((temp_rec_data_uart0=='R')&&(rec_data_len_uart>5))         //如果接收到的数据‘R’,并且已经接了一些数据了,此时可能单片机开始接收短信数据
  109.                 {
  110.                         if((Buffer_Uart0_Rec[rec_data_len_uart-1]=='G')&&(Buffer_Uart0_Rec[rec_data_len_uart-2]=='M')&&(Buffer_Uart0_Rec[rec_data_len_uart-3]=='C')&&(Buffer_Uart0_Rec[rec_data_len_uart-4]=='+'))//说明收到了短信数据 +CMGR
  111.                         {
  112.                                 flag_start_rec_message=1;        //置开始接收短信数据标志位
  113.                                 fenhao_num=0;        //重新开始根据逗号个数查找短信内容
  114.                                 rec_data_len_uart=0;        //前接的数据无用了
  115.                                 flag_rec_message_data=0;
  116.                                
  117.                         }
  118.                 }
  119.         }
  120.         if(flag_start_rec_message==1)        //收到短信数据才进行后续短信数据的提取
  121.         {
  122.                 if(temp_rec_data_uart0=='"')                //如果收到的数据是  ‘,’
  123.                 {
  124.                         fenhao_num++;
  125.                         if(fenhao_num>11)        //一次读取回来的短信数据中逗号的个数不可能超过11个,超过了还没处理完 说明数据有误
  126.                         {
  127.                                 fenhao_num=0;
  128.                                 flag_rec_message=0;                //不对短信数据进行处理
  129.                                 flag_start_rec_message=0;        //无短信数据数据 ,好似不需要处理,待定
  130.                                 flag_rec_message_data=0;
  131.                         }
  132.                         switch (fenhao_num)
  133.                         {
  134.                                 case 1:
  135.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  136.                                         break;
  137.                                 case 2:           //后取短信是否读取
  138.                                         //memcpy(temp_data_read,Buffer_Uart0_Rec+rec_data_len_uart-8,rec_data_len_uart-4);        //多存一些
  139.                                         memcpy(temp_data_read,Buffer_Uart0_Rec+1,7);        //多存一些
  140. //                                        if(hand(temp_data_read,"UNREAD"))
  141. //                                        {
  142. //                                                flag_read_or_un_message=1;        //没读取过
  143. //                                        }
  144. //                                        else
  145. //                                        {
  146. //                                                flag_read_or_un_message=0;        //读取过                                               
  147. //                                        }
  148.                                         //temp_data_read[rec_data_len_uart-3]='\0';
  149.                                         temp_data_read[10]='\0';
  150.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  151.                                         break;
  152.                                 case 3:                //空
  153.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  154.                                         break;
  155.                                 case 4:                 //temp_data_tele_num        获取电话号码
  156.                                         //memcpy(temp_data_tele_num,Buffer_Uart0_Rec+(rec_data_len_uart-13),13);        //多存一些                                               
  157.                                         memcpy(temp_data_tele_num,Buffer_Uart0_Rec+1,14);        //多存一些                                               
  158.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  159.                                         break;
  160.                                 case 5:                //空
  161.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  162.                                         break;                                                                               
  163.                                 case 6:                //空
  164.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  165.                                         break;
  166.                                 case 7:                //时期开始
  167.                                         rec_data_len_uart=0;        //前面数据处理完毕,重新接
  168.                                         break;
  169.                                 case 8:                   //temp_data_date,日期
  170.                                         memcpy(temp_data_date,Buffer_Uart0_Rec+1,20);        //               
  171.                                         flag_rec_message_data=1;        //置开始接收短信数据标志位
  172.                                         fenhao_num=0;
  173.                                         rec_data_len_uart=0;                                                                                                                                                                                    
  174.                                         break;
  175.                                 default:
  176.                                         break;                                       
  177.                         }
  178.                 }
  179.          }
  180.         if(flag_rec_message_data==1)        //开始接收短信内容数据
  181.         {
  182.                 if((temp_rec_data_uart0==0x0a)&&(Buffer_Uart0_Rec[rec_data_len_uart-1]==0x0d)&&(Buffer_Uart0_Rec[rec_data_len_uart-2]==0X4B)&&(Buffer_Uart0_Rec[rec_data_len_uart-3]==0x4F))        //短信接收完毕
  183.                 {
  184.                         if((Buffer_Uart0_Rec[0]!=0x22)||(Buffer_Uart0_Rec[1]!=0x0d)||(Buffer_Uart0_Rec[2]!=0x0a))        //数据有误
  185.                         {           //数据舍弃
  186.                                 rec_data_len_uart=0;
  187.                                 fenhao_num=0;
  188.                                 flag_rec_message=0;                //不对短信数据进行处理
  189.                                 flag_start_rec_message=0;        //无短信数据数据 ,好似不需要处理,待定                                                       
  190.                         }
  191.                         else        //短信数据正确,接收保存
  192.                         {
  193.                                 //memcpy(message_data,Buffer_Uart0_Rec+3,rec_data_len_uart-10);
  194.                                 memcpy(message_data,Buffer_Uart0_Rec+3,6);

  195.                                 rec_data_len_uart=0;
  196.                                 fenhao_num=0;
  197.                                 flag_rec_message=0;                //清来短信标志位
  198.                                 flag_start_rec_message=0;        //无短信数据数据 ,好似不需要处理,待定
  199.                                 flag_send_result=1;       
  200.                                 //message_data[19]='\0';
  201.                                 //P10=~P10;        //用来指示收到短信提示       
  202.                         }
  203.                         //clear_rec_data();
  204.                 }                               
  205.         }
  206.         Buffer_Uart0_Rec[rec_data_len_uart]=temp_rec_data_uart0;        //接收数据
  207.         rec_data_len_uart++;
  208.         if(rec_data_len_uart>24)
  209.         {
  210.                 rec_data_len_uart=0;         //从头开始接收数据
  211.         }       
  212. }
  213. void Uart1Send(uchar c)
  214. {
  215.         SBUF=c;
  216.         while(!TI);//等待发送完成信号(TI=1)出现
  217.         TI=0;       
  218. }
  219. //串行口连续发送char型数组,遇到终止号/0将停止
  220. void Uart1Sends(uchar *str)
  221. {
  222.         while(*str!='\0')
  223.         {
  224.                 SBUF=*str;
  225.                 while(!TI);//等待发送完成信号(TI=1)出现
  226.                 TI=0;
  227.                 str++;
  228.         }
  229. }
  230. //延时函数大概是1s钟,不过延时大的话不准...
  231. void DelaySec(int sec)
  232. {
  233.         uint i , j= 0;
  234.         for(i=0; i<sec; i++)
  235.         {
  236.                 for(j=0; j<65535; j++)
  237.                 {       
  238.                 }
  239.         }
  240. }
  241. void main()
  242. {
  243.         uchar i = 0;
  244.         SerialInti();
  245.         P1=0XFF;        //所有LED 都灭
  246.         Uart1Sends("AT\r\n");
  247.         DelaySec(1);//延时3秒
  248.         Uart1Sends("AT\r\n");
  249.         DelaySec(1);//延时3秒
  250.         Uart1Sends("ATE0\r\n");
  251.         DelaySec(1);//延时3秒
  252. //-----------配置接收短信方式----------------
  253.         Uart1Sends("AT+CMGF=1\r\n");
  254.         DelaySec(1);//延时3秒
  255.         Uart1Sends("AT+CSCS=\"GSM\"\r\n");
  256.         DelaySec(1);//延时3秒
  257.         Uart1Sends("AT+CMGD=1,4\r\n");
  258.         DelaySec(1);//延时3秒
  259.         P10=0;                 //提示初始化完成
  260.         while(1)
  261.         {
  262.                 if(flag_send_result==1)
  263.                 {
  264.                         flag_send_result=0;
  265.                         flag_rec_message=0;
  266.                         Uart1Sends("AT+CMGD=1,4\r\n");         //解析完毕,删除短信
  267.                         _nop_();_nop_();_nop_();
  268.                         _nop_();_nop_();_nop_();
  269.                         for(i=0;i<strlen(temp_data_read);i++)
  270.                         {
  271.                                 Uart1Send(*(temp_data_read+i));       
  272.                         }
  273.                         Uart1Send(0x0d);
  274.                         Uart1Send(0x0a);
  275.                         for(i=0;i<14;i++)
  276.                         {
  277.                                 Uart1Send(*(temp_data_tele_num+i));       
  278.                         }
  279.                         Uart1Send(0x0d);
  280.                         Uart1Send(0x0a);
  281.                         for(i=0;i<20;i++)
  282.                         {
  283.                                 Uart1Send(*(temp_data_date+i));       
  284.                         }
  285.                         Uart1Send(0x0d);
  286.                         Uart1Send(0x0a);
  287.                         for(i=0;i<strlen(message_data);i++)
  288.                         {
  289.                                 Uart1Send(*(message_data+i));       
  290.                         }
  291.                         if(hand(message_data,"LED1"))
  292.                         {
  293.                                 P10=~P10;       
  294.                         }
  295.                         else if(hand(message_data,"LED2"))
  296.                         {
  297.                                 P11=~P11;       
  298.                         }
  299.                         else if(hand(message_data,"LED3"))
  300.                         {
  301.                                 P12=~P12;       
  302.                         }
  303.                         else if(hand(message_data,"LED4"))
  304.                         {
  305.                                 P13=~P13;       
  306.                         }
  307.                         else if(hand(message_data,"LEDON"))
  308.                         {
  309.                                 P1=0;       
  310.                         }
  311.                         else if(hand(message_data,"LEDOFF"))
  312.                         {
  313.                                 P1=0XFF;       
  314.                         }
  315. //                        Uart1Send(0x0d);
  316. //                        Uart1Send(0x0a);
  317.                         clear_message_data();
  318.                 }
  319.                 if(flag_reced_mess==1)
  320.                 {
  321.                         _nop_();_nop_();
  322.                         _nop_();_nop_();
  323.                         _nop_();_nop_();
  324.                         flag_reced_mess=0;       
  325.                         clear_rec_data();       
  326.                         //P10=~P10;        //用来指示收到短信提示
  327.                         //DelaySec(1);//延时3秒
  328. //                        P15=0;
  329.                         Uart1Sends("AT+CMGR=1\r\n");
  330.                         flag_rec_message=1;       
  331.                 }
  332.         }
  333. }
复制代码

0.png

51单片机控制SIM900A来接收短信的程序.zip

45.75 KB, 下载次数: 130, 下载积分: 黑币 -5

单片机与SIM900A短信控制开关

评分

参与人数 2黑币 +55 收起 理由
BSLZNB + 5 回帖助人的奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:128535 发表于 2016-6-29 12:23 | 显示全部楼层
unsigned char hand(unsigned char *data_source,unsigned char *ptr) {         if(strstr(data_source,ptr)!=NULL)                 return 1;         else                 return 0; }是什么意思???
回复

使用道具 举报

ID:128535 发表于 2016-6-29 12:24 | 显示全部楼层
求解
回复

使用道具 举报

ID:128939 发表于 2016-7-2 17:54 | 显示全部楼层
下载看一下,谢谢Q
回复

使用道具 举报

ID:134715 发表于 2016-7-23 14:22 | 显示全部楼层
真的可以实现吗?你要发的短信是不是提前设置好的固定的哪几个字呢?还是说我随意发一个什么短信都可以控制开关呢?
回复

使用道具 举报

ID:134832 发表于 2016-7-24 15:47 | 显示全部楼层
博主,你的程序怎么实现不了啊?求解啊
回复

使用道具 举报

ID:117930 发表于 2017-1-8 18:36 | 显示全部楼层
谢谢你的代码 我也正在尝试用GSM短信控制继电器
回复

使用道具 举报

ID:171032 发表于 2017-4-9 15:51 | 显示全部楼层
想下载下来看看
回复

使用道具 举报

ID:199562 发表于 2017-5-12 14:56 | 显示全部楼层
谢谢分享,正好学习这方面的知识。
回复

使用道具 举报

ID:200456 发表于 2017-5-14 19:21 | 显示全部楼层
程序在哪里改手机号?
回复

使用道具 举报

ID:79874 发表于 2017-6-21 09:35 | 显示全部楼层
谢谢分享,学学
回复

使用道具 举报

ID:79874 发表于 2017-6-21 09:35 | 显示全部楼层
谢谢分享,学学
回复

使用道具 举报

ID:134715 发表于 2017-9-13 15:09 | 显示全部楼层

请叫我雷锋
回复

使用道具 举报

ID:245031 发表于 2017-11-1 21:29 来自手机 | 显示全部楼层
800C可以用吗
回复

使用道具 举报

ID:258093 发表于 2017-12-6 11:13 | 显示全部楼层
有短信控制LED灯的亮度吗
回复

使用道具 举报

ID:160072 发表于 2018-5-20 22:01 | 显示全部楼层
感谢 我就是想看下这个程序
回复

使用道具 举报

ID:382813 发表于 2019-4-2 15:21 来自手机 | 显示全部楼层
5083 发表于 2017-1-8 18:36
谢谢你的代码 我也正在尝试用GSM短信控制继电器

兄弟,你控制继电器成功了吗?
回复

使用道具 举报

ID:289921 发表于 2019-4-23 10:58 | 显示全部楼层
281770683 发表于 2019-4-2 15:21
兄弟,你控制继电器成功了吗?

兄弟,你的成功没
回复

使用道具 举报

ID:486462 发表于 2022-2-6 20:56 | 显示全部楼层
测试了好久没有用是啥情况
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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