找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2488|回复: 0
打印 上一主题 下一主题
收起左侧

基于15f2k61s2以及GSM 8的中文短信收发单片机程序

[复制链接]
跳转到指定楼层
楼主
1、使用单片机串口2与模块通信;接法如下
    STC单片机15f2k61s2   GPRS模块
    P1.0(RXD2)->RXD
    P1.1(TXD2)->TXD
    GND      ->GND

   
    晶振选用22.1184MHz (可选用内部晶振)
2、板子上电后运行指示灯RUNING_LED会以一秒的频率闪烁;
3、打开代码修改短信中心号、接收方手机号和短信内容,编译成功后下载到单片机里面,就可以实现发送一条中文短信,中文短信具体的解析可以参考串口调试笔记

单片机源程序如下:
  1. /**********************************************************************************
  2. * 工程名  :
  3. * 描述    :通过手机发送短信控制LED
  4. * 实验平台:STC15XX
  5. * 库版本  :

  6. **********************************************************************************/

  7. #include "string.h"
  8. #include "delay.h"
  9. #include "uart.h"
  10. #define uchar unsigned char
  11. #define uint  unsigned int
  12. #define Buf1_Max 32                                           //串口1缓存长度
  13. #define Buf2_Max 200                                           //串口2缓存长度
  14. /*************        本地常量声明        **************/
  15. sbit RUNING_LED = P2^6;                                        //运行指示灯
  16. sbit LED                          = P2^3;                                        //控制指示灯
  17. sbit PWR_MG323         = P2^0;       
  18. sbit l1                          = P4^5;                                        //控制指示灯
  19. sbit l2         = P4^1;                               
  20. sbit yw=P1^5;

  21. static unsigned char *content="0891683108706505F011000D91688133102684F80008AA2c745E876079D1628063D0919260A8FF0C5F53524D533A57DF70DF96FE91CF8D856807FF0C8BF76CE8610FFF01";//瑞蝠科技提醒您,当前区域烟雾量超标,请注意!
  22. /************************短信内容解析**************************************/
  23. /*
  24.    //短信中心号(倒序)      目标手机(倒序)         短信内容(测试已经完成)
  25.      8613800756500F          8618330162488F         
  26. 0891 683108706505F0 11000D91 688133102684F8 0008AA0C 70DF96FE91CF8D856807FF01

  27. */
  28. /*************  本地变量声明        **************/

  29. xdata u8 Uart2_Buf[Buf2_Max];
  30. xdata u8 Uart1_Buf[Buf1_Max];
  31. u8 Times=0,First_Int = 0,shijian=0;
  32. uchar num;
  33. uchar phone[]="\"18330162488\"";
  34. //u8 Time_count=0;
  35. bdata u8 Flag;//定时器标志位
  36. sbit Timer0_start =Flag^0;        //定时器0延时启动计数器
  37. sbit Uart2_Start  =Flag^1;        //串口2开始接收数据
  38. sbit Uart2_End                =Flag^2;        //串口2接收数据结束
  39. xdata uchar tab1[]="0010\0";
  40. xdata uchar tab2[]="0020\0";
  41. xdata uchar tab3[]="0030\0";
  42. //uchar dj=1;
  43. bit a=0;
  44. /*************        本地函数声明        **************/
  45. void GPIO_config(void); //端口初始化配置
  46. void Timer0Init(void);  //定时器0初始化
  47. void CLR_Buf2(void);    //清除串口2接收缓存
  48. u8 Find(u8 *a);         //查找字符串
  49. void Second_AT_Command(u8 *b,u8 *a,u8 wait_time); //发送AT指令函数
  50. void Set_Pdu_Mode(void);//设置短信模式PDU
  51. void Set_Text_Mode(void);
  52. void Wait_CREG(void);   //查询等待模块注册成功
  53. void Send_Pdu_Sms(void);//发送一条中文短信
  54. void Send_Pdu_Sms1(void);
  55. void Check_New_Message(void);
  56. uchar zh(void);
  57. void Send_Text_Sms(void);
  58. void ChangeNum(uchar* num, uchar* des);
  59. void CLR_Buf1(void);
  60. /*******************************************************************************
  61. * 函数名 : main
  62. * 描述   : 主函数
  63. * 输入   :
  64. * 输出   :
  65. * 返回   :
  66. * 注意   : 串口2负责与MG323模块通信,串口1用于串口调试,可以避免在下载程序时数据
  67.                                          还发送到模块
  68. *******************************************************************************/
  69. void main(void)
  70. {
  71.     uchar f=0,i=0,n=0;
  72.     uchar sz[7]={0x42,0x4d,0xe1,0x00,0x00,0x01,0x70};
  73.         GPIO_config();
  74.         Uart1Init();
  75.         Uart2Init();
  76.         Timer0Init();
  77.         EA=1;        //开总中断
  78.        
  79.         Wait_CREG();    //查询等待模块注册成功
  80.         Second_AT_Command("AT+CMGD=1,4","OK",3);// 删除sim卡上已发的和未发的全部短信
  81.         Second_AT_Command("AT+CMGD=1,2","OK",3);// 删除已读短信  
  82.         Set_Text_Mode();
  83.         l1=0;
  84.         delay_ms(1000);
  85.         for(n=0;n<3;n++)
  86.         {
  87.         for( i=0;i<7;i++)
  88.         UART1_SendData(sz[i]);
  89.         delay_ms(1000);
  90.         }
  91.         while(f==0)
  92.         {
  93.          f=zh();
  94.         }
  95.         Send_Text_Sms();
  96.         l2=0;
  97.         while(1)
  98.         {
  99.        
  100.         Check_New_Message();
  101. //       
  102.         if(yw==0)
  103.         {
  104.         delay_ms(10);
  105.         if(yw==0&&a==0)
  106.         {
  107.     Set_Pdu_Mode();//设置短信为PDU模式
  108.         Send_Pdu_Sms();//发送一条短消息
  109.         Set_Text_Mode();
  110. //        Send_Text_Sms();
  111.         a=1;
  112.         }
  113.         }
  114.         if(yw==1)
  115.         a=0;
  116.         }
  117.         delay_ms(1000);
  118. }

  119. /*******************************************************************************
  120. * 函数名 : Uart1
  121. * 描述   : 串口1中断服务入口函数
  122. * 输入   :
  123. * 输出   :
  124. * 返回   :
  125. * 注意   :
  126. *******************************************************************************/
  127. void Uart1() interrupt 4
  128. {
  129.     if (RI)
  130.     {
  131.         RI = 0;                 //清除RI位
  132.                 Uart1_Buf[num]=SBUF;
  133.                 num++;
  134.                 if(num>=32)
  135.                 num=0;
  136.     }
  137.     if (TI)
  138.     {
  139.         TI = 0;                 //清除TI位
  140.     }
  141. }

  142. /*******************************************************************************
  143. * 函数名 : Uart2
  144. * 描述   : 串口2中断服务入口函数
  145. * 输入   :
  146. * 输出   :
  147. * 返回   :
  148. * 注意   :
  149. *******************************************************************************/
  150. void Uart2() interrupt 8
  151. {
  152.                 IE2  &= ~0x01;   //关闭串口2中断
  153.     if (S2CON & S2RI)
  154.     {
  155.       S2CON &= ~S2RI;         //清除S2RI位
  156.                         Uart2_Buf[First_Int] = S2BUF;            //将接收到的字符串存到缓存中
  157.                         First_Int++;                                        //缓存指针向后移动
  158.                         if(First_Int > Buf2_Max)                       //如果缓存满,将缓存指针指向缓存的首地址
  159.                         {
  160.                                 First_Int = 0;
  161.                         }
  162.     }
  163.     if (S2CON & S2TI)
  164.     {
  165.       S2CON &= ~S2TI;         //清除S2TI位
  166.     }
  167.                 IE2  |= 0x01;   //使能串口2中断
  168. }
  169. /*******************************************************************************
  170. * 函数名 : Timer0_ISR
  171. * 描述   : 定时器0中断服务入口函数,20ms中断一次
  172. * 输入   :
  173. * 输出   :
  174. * 返回   :
  175. * 注意   :
  176. *******************************************************************************/
  177. void Timer0_ISR() interrupt 1
  178. {
  179.         static u8 Time_count=0;
  180.         TR0=0;//关定时器
  181.         Time_count++;
  182.         if(Time_count>=50)
  183.         {
  184.                 Time_count = 0;
  185.                 RUNING_LED =~RUNING_LED;
  186.         }
  187.         if(Timer0_start)
  188.         Times++;
  189.         if(Times > (50*shijian))
  190.         {
  191.                 Timer0_start = 0;
  192.                 Times = 0;
  193.         }
  194.         TR0=1;//开定时器
  195. }
  196. /*******************************************************************************
  197. * 函数名 : GPIO_config
  198. * 描述   : IO口配置函数
  199. * 输入   :
  200. * 输出   :
  201. * 返回   :
  202. * 注意   :
  203. *******************************************************************************/
  204. void        GPIO_config(void)
  205. {
  206.                 P3M1 &= 0XC3;  //配置P32~P35为推挽输出
  207.                 P3M0 |=        ~0XC3;
  208.                 LED=0;
  209.                 RUNING_LED=0;
  210. }
  211. void Timer0Init(void)                //20毫秒@22.1184MHz
  212. {
  213.         AUXR &= 0x7F;        //12T模式
  214.         TMOD &= 0xF0;        //设置定时器模式 16位重载
  215.         TL0 = 0x00;                //设定定时器初值
  216.         TH0 = 0x70;                //设定定时器初值
  217.         TF0 = 0;                        //清除TF0标志
  218.         TR0 = 1;                        //定时器0开始计时
  219.         ET0 = 1;            //使能定时器0中断
  220. }
  221. /*******************************************************************************
  222. * 函数名 : CLR_Buf2
  223. * 描述   : 清除串口2缓存数据
  224. * 输入   :
  225. * 输出   :
  226. * 返回   :
  227. * 注意   :
  228. *******************************************************************************/
  229. void CLR_Buf2(void)
  230. {
  231.         u16 k;
  232.         for(k=0;k<Buf2_Max;k++)      //将缓存内容清零
  233.         {
  234.                 Uart2_Buf[k] = 0x00;
  235.         }
  236.     First_Int = 0;              //接收字符串的起始存储位置
  237. }
  238. void CLR_Buf1(void)
  239. {
  240.         u16 k;
  241.         for(k=0;k<Buf2_Max;k++)      //将缓存内容清零
  242.         {
  243.                 Uart1_Buf[k] = 0x00;
  244.         }
  245.     num = 0;              //接收字符串的起始存储位置
  246. }
  247. /*******************************************************************************
  248. * 函数名 : Find
  249. * 描述   : 判断缓存中是否含有指定的字符串
  250. * 输入   :
  251. * 输出   :
  252. * 返回   : unsigned char:1 找到指定字符,0 未找到指定字符
  253. * 注意   :
  254. *******************************************************************************/

  255. u8 Find(u8 *a)
  256. {
  257.   if(strstr(Uart2_Buf,a)!=NULL)
  258.             return 1;
  259.         else
  260.                         return 0;
  261. }

  262. /*******************************************************************************
  263. * 函数名 : Second_AT_Command
  264. * 描述   : 发送AT指令函数
  265. * 输入   : 发送数据的指针、发送等待时间(单位:S)
  266. * 输出   :
  267. * 返回   :
  268. * 注意   :
  269. *******************************************************************************/

  270. void Second_AT_Command(u8 *b,u8 *a,u8 wait_time)         
  271. {
  272.         u8 i;
  273.         u8 *c;
  274.         c = b;                                                                                //保存字符串地址到c
  275.         CLR_Buf2();
  276.   i = 0;
  277.         while(i == 0)                    
  278.         {
  279.                 if(!Find(a))           //查找需要应答的字符
  280.                 {
  281.                         if(Timer0_start == 0)//超时重新发送命令
  282.                         {
  283.                                 b = c;                                                 //将字符串地址给b
  284.                                 for (b; *b!='\0';b++)
  285.                                 {
  286.                                         UART2_SendData(*b);
  287.                                 }
  288.                                 UART2_SendLR();       
  289.                                 Times = 0;
  290.                                 shijian = wait_time;
  291.                                 Timer0_start = 1;  //开始计时
  292.                    }
  293.     }
  294.           else
  295.                 {
  296.                         i = 1;
  297.                         Timer0_start = 0;  
  298.                 }
  299.         }
  300.         CLR_Buf2();
  301. }

  302. /*******************************************************************************
  303. * 函数名 : Set_Pdu_Mode
  304. * 描述   : 设置短信为TEXT文本模式
  305. * 输入   :
  306. * 输出   :
  307. * 返回   :
  308. * 注意   :
  309. *******************************************************************************/
  310. void Set_Pdu_Mode(void)
  311. {
  312.         Second_AT_Command("ATE0","OK",3);                                                                                  //取消回显       
  313.         Second_AT_Command("AT+CMGF=0","OK",3);                                                                //设置PDU模式       
  314.         Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);//所有操作都在SIM卡中进行
  315. }
  316. /*******************************************************************************
  317. * 函数名 : Send_Pdu_Sms
  318. * 描述   : 发送PDU文本短信
  319. * 输入   :
  320. * 输出   :
  321. * 返回   :
  322. * 注意   :
  323. *******************************************************************************/
  324. void Send_Pdu_Sms(void)
  325. {

  326.         Second_AT_Command("AT+CMGS=59",">",3); //发送数据长度:27(具体的计算方法看串口调试比较)接收到“>”才发送短信内容
  327.         UART2_SendString(content);     //发送短信内容
  328.         UART2_SendData(0X1A);          //发送结束符
  329. }
  330. /*******************************************************************************
  331. * 函数名 : GPS
  332. * 描述   : 发送PDU文本短信
  333. * 输入   :
  334. * 输出   :
  335. * 返回   :
  336. * 注意   :
  337. *******************************************************************************/
  338. //void GPS(void)
  339. //{
  340. //        Second_AT_Command("AT+CGNSPWR=1\r\n","OK",2);   //打开GPS电源
  341. //        delay_ms(100);
  342. //        Second_AT_Command("AT+CGNSSEQ=\"RMC\"\r\n","OK",2);//定义NMEA解析
  343. //        Second_AT_Command("AT+CGNSINF\r\n","+CGNSINF: 1,1,",3);//等待定位成功
  344. //        Second_AT_Command("AT+CGNSURC=0\r\n","OK",1); //设置GPS输出参数
  345. //}

  346. /*******************************************************************************
  347. * 函数名 : Wait_CREG
  348. * 描述   : 等待模块注册成功
  349. * 输入   :
  350. * 输出   :
  351. * 返回   :
  352. * 注意   :
  353. *******************************************************************************/
  354. void Wait_CREG(void)
  355. {
  356.         u8 i;
  357.         u8 k;
  358.         i = 0;
  359.         CLR_Buf2();
  360.   while(i == 0)                               
  361.         {
  362.                 CLR_Buf2();        
  363.                 UART2_SendString("AT+CREG?");//查询模块网络注册状态
  364.                 UART2_SendLR();
  365.                 delay_ms(5000);                                                 
  366.             for(k=0;k<Buf2_Max;k++)                             
  367.             {
  368.                         if(Uart2_Buf[k] == ':')
  369.                         {
  370.                                 if((Uart2_Buf[k+4] == '1')||(Uart2_Buf[k+4] == '5')) //表明网络注册成功
  371.                                 {
  372.                                         i = 1;
  373. //                                        UART1_SendString("信号检测中\n");
  374.                                   break;
  375.                                 }
  376.                         }
  377.                 }
  378.         }
  379. }
  380. void Set_Text_Mode(void)
  381. {
  382.         Second_AT_Command("ATE0","OK",3);
  383.                                                                                         //取消回显       
  384.         Second_AT_Command("AT+CNMI=3,2,0,0,0","OK",3);                                                        //新短信直接输出
  385.         Second_AT_Command("AT+CMGF=1","OK",3);                                                                //TEXT模式       
  386.         Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);                //所有操作都在SIM卡中进行       
  387. }
  388. void Send_Text_Sms(void)
  389. {
  390.         unsigned char temp[50]="AT+CMGS=";
  391.         unsigned char temp1[70]="\0";
  392.         strcat(temp,phone); //字符串拼接函数(库函数)
  393.         Second_AT_Command(temp,">",3); //等待接收到“>”才发送短信内容
  394.         strcat(temp1,"PM1.0:");
  395.         strcat(temp1,tab1); //字符串拼接函数(库函数)
  396.         strcat(temp1,"ug/m3\nPM2.5:"); //字符串拼接函数(库函数)
  397.         strcat(temp1,tab2); //字符串拼接函数(库函数)
  398.         strcat(temp1,"ug/m3\nPM10 :"); //字符串拼接函数(库函数)
  399.         strcat(temp1,tab3);
  400.         strcat(temp1,"ug/m3\n"); //字符串拼接函数(库函数)
  401.         UART2_SendString(temp1);     //发送短信内容
  402.         UART1_SendString(temp1);     //发送短信内容
  403.         UART2_SendData(0X1A);          //发送结束符
  404.         l2=~l2;
  405. }
  406. void Check_New_Message(void)
  407. {
  408.         u8 temp=0;
  409.         uchar *hao,j,f;

  410.         if(strstr(Uart2_Buf,"+CMT")!=NULL)                   //若缓存字符串中含有"+CMT"就表示有新的短信
  411.         {
  412.                    l2=~l2;
  413.                 delay_ms(50);//等待数据全部接收完成
  414. //                UART1_SendString(Uart2_Buf);
  415.                 if(strstr(Uart2_Buf,"67E58BE2")!=NULL)
  416.                 {
  417. //                  UART1_SendString("验证通过\n");
  418.                   hao=strstr(Uart2_Buf,"+CMT");
  419.                   for(j=0;j<11;j++)
  420.                   {
  421.                    phone[j+1]=*(hao+j+10);
  422.                   }
  423.                   while(f==0)
  424.                   {
  425.                   f=zh();
  426.                   }
  427.                   Set_Text_Mode();
  428.                   Send_Text_Sms();
  429.                   
  430.                 }
  431.                 CLR_Buf2();
  432.        
  433.         }
  434. }
  435. uchar zh()
  436. {
  437. uint pm1,pm2,pm10;
  438. uchar i,dj;
  439. uchar cx[]={0x42,0x4d,0xe2,0x00,0x00,0x01,0x71};
  440. CLR_Buf1();
  441.         for(i=0;i<7;i++)
  442.         UART1_SendData(cx[i]);
  443. delay_ms(1000);
  444. if(Uart1_Buf[0]==0x42&&Uart1_Buf[1]==0x4d&&Uart1_Buf[2]==0x00&&Uart1_Buf[3]==0x1c)
  445. {
  446. // pm1=Uart1_Buf[4]*256+Uart1_Buf[5];
  447. // pm2=Uart1_Buf[6]*256+Uart1_Buf[7];
  448. // pm10=Uart1_Buf[8]*256+Uart1_Buf[9];
  449. pm1=Uart1_Buf[10]*256+Uart1_Buf[11];
  450. pm2=Uart1_Buf[12]*256+Uart1_Buf[13];
  451. pm10=Uart1_Buf[14]*256+Uart1_Buf[15];
  452. // CLR_Buf1();
  453. tab1[0]=pm1/1000+0x30;
  454. tab1[1]=pm1%1000/100+0x30;
  455. tab1[2]=pm1%100/10+0x30;
  456. tab1[3]=pm1%10+0x30;
  457. if(tab1[0]==0x00)
  458. {
  459.   tab1[0]=' ';
  460.   if(tab1[1]==0x00)
  461.   {
  462.    tab1[1]=' ';
  463.    if(tab1[2]==0x00)
  464.    tab1[2]=' ';
  465.   }
  466. }
  467. tab2[0]=pm2/1000+0x30;
  468. tab2[1]=pm2%1000/100+0x30;
  469. tab2[2]=pm2%100/10+0x30;
  470. tab2[3]=pm2%10+0x30;
  471.   if(tab2[0]==0x00)
  472. {
  473.   tab2[0]=' ';
  474.   if(tab2[1]==0x00)
  475. ……………………

  476. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
4.发送中文短信.rar (99.78 KB, 下载次数: 20)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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