ITshao9 发表于 2016-5-31 11:05

GU900E模块实现收发短信,打电话

实现了收发短信,并且支持字符短信和PDU格式短信,支持电话拨打与接听长期工作稳定
//GU900E.C1./************************************************************************************************************* 2.   * 文件名:         GU900E.c 3.   * 功能:          STM32 GU900E底层驱动函数 4.   * 作者:          5.   * 创建时间:      2016-5-166.   * 最后修改时间:2016-5-16 7.   * 详细:          GSM_CDMA发送短信等 8.                      2014-04-22:添加字节超时与总超时 9.*************************************************************************************************************/10. #include "system.h"11. #include "usart.h"12. #include "GU900E.h"13. #include "delay.h"14. #include "string.h"15. #include "ucos_ii.h"16. #include "unicode_gbk.h"17. #include "main.h"18.   19.   20. //GU900E通信缓冲区21. u8GU900E_Buff;//缓冲区22.   23.   24. //调试开关25. #define GU900E_DBUG 026. #if GU900E_DBUG27.   #include "system.h"28.   #define GU900E_debug(format,...)    uart_printf(format,##__VA_ARGS__)29. #else30.   #define GU900E_debug(format,...)    /\31. /32. #endif//GU900E_DBUG33.   34. //所有短信接收缓冲区35. //#define PDU_BUFF_SIZE 1024*20         //20KB可以一次读取50条未读短信36. u8SmsPduBuff;          //PDU数据缓冲区37.   38.   39.   40. static u8 PhoneNumtoPDUChar(u8 *pNum, char *pChar,u8 NumLen);       //将电话号码字符转换为PDU要求的字符41. static u8 ChartoPhoneNum(char *pChar, char *pNum, u8 CharLen);      //将字符转换为电话号码42. static u32 StringToUnicodeStr(char *pStr, char *pucode,u32 SrtLen); //将字符串转换为unicode,并存储为16进制样式的字符串43. static u32 UnicodeStrToString(u8 *pucode,char *pStr,u32 SrtLen);    //将字符unicode转换为字符串44. static u32 GSM_StringToHex(char *pStr, u8 NumDigits);               //将16进制样式字符串转换为16进制整型数(必须保证字符串字母都是大写)45. static void GSM_HexToString(u32 HexNum,char *pStr, u8 NumDigits);   //将整型数字转换为16进制样式字符串(字母为大写,不带结束符)46. static int gsmDecode7bit(const u8* pSrc, char* pDst, int nSrcLength);//7bit编码解码47. static int gsmEncode7bit(const char* pSrc,u8* pDst);48. static u16 GSM_GetU2SCharOffset(char *pBuff,u16 CharNum);49.   50.   51. static PHONE_NUMBER SMSServeNumber;                                 //全局短信中心号码52.   53.   54.   55.   56. /************************************************************************************************************************* 57. * 函数                :   void GU900E_SetSMSServeNumber(char *pSMSServeNumber,u8 NumLen) 58. * 功能                :   设置全局短信中心号码 59. * 参数                :   pSMSServeNumber:短信中心号码,NumLen:短信中心号码长度 60. * 返回                :   无 61. * 依赖                :   无 62. * 作者                : 63. * 时间                :   2016-5-1764. * 最后修改时间    :   2016-5-1765. * 说明                :   用于发送短信的时候进行调用 66. *************************************************************************************************************************/67. void GU900E_SetSMSServeNumber(char *pSMSServeNumber,u8 NumLen)68. {69.   u8 i;70.       71.   if(NumLen > PHONE_NUMBER_MAX_LEN) NumLen = PHONE_NUMBER_MAX_LEN; //限制电话号码长度72.   for(i = 0;i < NumLen;i ++)73.   {74.         SMSServeNumber.PhoneNumBuff = pSMSServeNumber;75.   }76.   SMSServeNumber.PhoneNumLen = NumLen;77.   SMSServeNumber.PhoneNumBuff = '\0';   //添加结束符78.   GU900E_debug("设置短信中心号码为:%s\r\n",SMSServeNumber.PhoneNumBuff);79. }80.   81.   82.   83.   84. /************************************************************************************************************************* 85. * 函数                :   bool GSM_CheckNotASCII(char *pBuff,u16 Len) 86. * 功能                :   检查字符串中是否含有非ASCII编码 87. * 参数                :   pBuff:字符串缓冲区;Len:长度 88. * 返回                :   FALSE:字符串全部为ASCII编码;TRUE:字符串含有非ASCII编码,一般为汉字编码 89. * 依赖                :   无 90. * 作者                : 91. * 时间                :   2016-5-1792. * 最后修改时间    :   2016-5-1793. * 说明                :   用于选择发送短信的模式,选择U2S或者7BIT编码

ITshao9 发表于 2016-5-31 11:08

94.        *************************************************************************************************************************/
95.        bool GSM_CheckNotASCII(char *pBuff,u16 Len)
96.        {
97.          u16 i;
98.             
99.          for(i = 0;i < Len;i ++)
100.          {
101.                if(pBuff >= 0x80)
102.                    return TRUE;
103.          }
104.          return FALSE;
105.        }
106.          
107.          
108.          
109.        /*************************************************************************************************************************
110.        * 函数                :   static u16 GSM_GetU2SCharOffset(char *pBuff,u16 CharNum)
111.        * 功能                :   计算指定字符的偏移位置
112.        * 参数                :   pBuff:字符串缓冲区;
113.                                CharNum:字符偏移
114.        * 返回                :   字符串大小
115.        * 依赖                :   无
116.        * 作者                :   H F Y-GU900
117.        * 时间                :   2016-5-17
118.        * 最后修改时间    :   2016-5-17
119.        * 说明                :   计算指定数量的字符(不分中英文)的大小,比如PDU,U2S模式下,短信只能有70个字符,但是不分中英文
120.                                此时英文只占用一个字节,但是中文占用2个字节
121.        *************************************************************************************************************************/
122.        static u16 GSM_GetU2SCharOffset(char *pBuff,u16 CharNum)
123.        {
124.          u16 i;
125.          u16 cnt = 0;
126.             
127.          
128.          for(i = 0;i < CharNum;)
129.          {
130.                if(pBuff >= 0x80) //中文
131.                {
132.                    cnt +=2;
133.                    i +=2;
134.                }
135.                else if(pBuff == 0)//字符串结束
136.                {
137.                    break;
138.                }
139.                else                  //ASCII
140.                {
141.                    cnt += 1;
142.                    i ++;
143.                }
144.          }
145.          return cnt;
146.        }
147.          
148.          
149.          
150.        /*************************************************************************************************************************
151.        * 函数                :   bool GU900E_WaitSleep(void)
152.        * 功能                :   等待GSM模块空闲,并重新唤醒
153.        * 参数                :   TimeOut:等待超时,时间单位ms
154.        * 返回                :   TRUE:成功;FALSE:超时
155.        * 依赖                :   无
156.        * 作者                :   H F Y-GU900
157.        * 时间                :   2016-5-17
158.        * 最后修改时间    :   2016-5-17
159.        * 说明                :   用于等待操作完成,防止快速操作造成模块不响应
160.        *************************************************************************************************************************/
161.        bool GU900E_WaitSleep(u32 TimeOut)
162.        {
163.          u32 i;
164.          u32 cnt;
165.             
166.          TimeOut /= 100;
167.          TimeOut +=1;
168.             
169.          GU900E_SetDTR(1);                           //等待模块空闲后进入SLEEP模式
170.             
171.          for(i = 0;i < TimeOut;i ++)
172.          {
173.                GSM_Delay100MS();                     //延时100ms
174.                GU900E_SendATcom("AT");               //发送"AT",同步波特率,并且等待应答
175.                if(AT_RETURN_TIME_OUT == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 15)) //等待响应,超时150ms
176.                {
177.                    break;
178.                }
179.          }
180.          GU900E_SetDTR(0);                           //唤醒
181.          if(i == TimeOut)   
182.          {
183.                GU900E_debug("模块进入空闲模式失败!\r\n");
184.                return FALSE;
185.          }
186.          GSM_Delay100MS();                     //延时100ms
187.             
188.          GU900E_debug("模块进入空闲模式成功!\r\n");
189.          GU900E_TestAT(10);
190.          return TRUE;
191.        }
192.          
193.          
194.          
195.        /*************************************************************************************************************************
196.        *函数         :   bool GSM_SendSMS(char *pSMS, char *pPhoneNumber)
197.        *功能         :   发送一条短信
198.        *参数         :   pSMS:短信内容缓冲区指针,内容为文本文档,并且字符串需要结束符
199.                            pPhoneNumber:目标电话号码
200.        *返回         :   TRUE:短信发送成功;FALSE:短信发送失败
201.        *依赖         :   底层
202.        *作者         :   H F Y-GU900
203.        *时间         :   2016-5-17
204.        *最后修改时间 :   2016-5-17
205.        *说明         :   需要先调用GU900E_SetSMSServeNumber()设置短信中心号码
206.                            需要使用全局的PDU数据缓冲区
207.                            一定要添加结束符
208.                            当短信长度超过单条短信长度限制后会发送多条短信
209.        ***************************************************************************

ITshao9 发表于 2016-5-31 11:10

**********************************************/
210.        #define SMS_MAX_LEN   2048                  //短信最大长度
211.        bool GSM_SendSMS(char *pSMS, char *pPhoneNumber)
212.        {
213.          char SMSBuff;    //短信最大160B,加上一个结束符
214.          u8 PDUBuff;      //短信PDU数据缓冲区
215.          u16 SMSLen;             //短信长度
216.          u16 SMSOffset;          //短信发送偏移位置,用于发送多条短信
217.          u16 i,j;
218.             
219.          SMSLen = strlen(pSMS);//获取要发送的短信长度
220.          if(SMSLen > SMS_MAX_LEN) SMSLen = SMS_MAX_LEN;   //限制短信最大长度,防止无限发送
221.             
222.          if(strlen(SMSServeNumber.PhoneNumBuff) == 0)
223.          {
224.                GU900E_debug("由于短信中心号码设置失败,导致短信无法发送!\r\n");
225.                return FALSE;
226.          }
227.             
228.          SMSOffset = 0;          //起始偏移为0
229.          while(1)
230.          {
231.                if((SMSLen-SMSOffset) > 160)
232.                    j = 160;
233.                else   
234.                    j = SMSLen-SMSOffset;
235.                for(i = 0;i < j;i ++)
236.                {
237.                    SMSBuff = pSMS;   //复制短信到发送缓冲区
238.                }
239.                SMSBuff = 0; //添加结束符
240.                
241.                if(GSM_CheckNotASCII(SMSBuff,j) == TRUE)    //分割的短信中含有非ASCII编码,那么只能使用U2S编码,只能发送70个字符(包括中英文)
242.                {
243.                    SMSOffset += GSM_GetU2SCharOffset(SMSBuff,70);//第一条短信限制70个字符,返回下一条分割的起始位置
244.                    SMSBuff = 0;
245.                }
246.                else
247.                {
248.                    SMSOffset += j; //下一条分割的起始位置
249.                    SMSBuff = 0;
250.                }
251.                
252.                //GU900E_WaitSleep(1000);   //等待上一个操作完成
253.                if(GSM_SendOneSMS(SMSBuff, PDUBuff, SMSServeNumber.PhoneNumBuff, pPhoneNumber) == TRUE)
254.                {
255.                    GU900E_debug("发送短信成功!\r\n");
256.                      
257.                      
258.                }
259.                else
260.                {
261.                    GU900E_debug("发送短信失败!\r\n");
262.                    return FALSE;
263.                }
264.                if(SMSOffset >= SMSLen) break;   //短信发送完成,退出
265.          }
266.             
267.          return TRUE;
268.             
269.        }
270.          
271.          
272.          
273.        /*************************************************************************************************************************
274.        * 函数            :   void GU900E_HardwareInit(void)
275.        * 功能            :   初始化GU900E相关的硬件
276.        * 参数            :   无
277.        * 返回            :   无
278.        * 依赖            :   无
279.        * 作者            :   H F Y-GU900
280.        * 时间            :   2016-5-16
281.        * 最后修改时间    :   2016-5-16
282.        * 说明            :   主要初始化与GU900E相关的STM32 IO 以及 UART
283.        *************************************************************************************************************************/
284.        void GU900E_HardwareInit(void)
285.        {
286.          GU900E_UartInit();                                  //初始化串口
287.          GU900E_SetRxBuff(GU900E_Buff, GU900E_BUFF_SIZE);    //设置通信缓冲区
288.          
289.          //初始化RI,用于指示新短信或者电话
290.          DeviceClockEnable(DEV_GPIOB,ENABLE);                //使能GPIOB时钟
291.          GPIOx_Init(GPIOB,BIT14, IN_IPU, IN_IN);             //上拉输入
292.          GPIOx_Init(GPIOB,BIT12|BIT13|BIT15, OUT_PP, SPEED_10M); //推挽输出
293.          GU900E_SetDTR(0);                                 //取消SLEEP
294.          GU900E_SetRESET(1);                                 //复位无效
295.          GU900E_SetPWR(1);                                 //上电无效
296.        }
297.          
298.          
299.          
300.          
301.        /*************************************************************************************************************************
302.        * 函数                :   void GU900E_HardwarePowerUP(void)
303.        * 功能                :   GU900E硬件开机
304.        * 参数                :   无
305.        * 返回                :   无
306.        * 依赖                :   无
307.        * 作者                :   H F Y-GU900
308.        * 时间                :   2016-5-18
309.        * 最后修改时间    :   2016-5-18
310.        * 说明                :   用于GU900E模块开机,拉低PWR
311.        *************************************************************************************************************************/
312.        void GU900E_HardwarePowerUP(void)
313.        {
314.          GU900E_SetPWR(1);   //恢复高电平
315.          GSM_DelayMS(200);
316.          GU900E_SetPWR(0);   //拉低750ms开机
317.          GSM_DelayMS(750);
318.          GSM_Delay100MS();
319.          GU900E_SetPWR(1);   //恢复高电平
320.          GSM_DelaySer(3);    //延时3S等待开机完毕                              
321.        }
322.          
323.          
324.          
325.        /*************************************************************************************************************************
326.        * 函数                :   void GU900E_HardwarePowerDOWN(void)
327.        * 功能                :   GU900E硬件关机
328.        * 参数                :   无
329.        * 返回                :   无
330.        * 依赖                :   无
331.        * 作者                :   H F Y-GU900
332.        * 时间                :   2016-5-18
333.        * 最后修改时间    :   2016-5-18
334.        * 说明                :   用于GU900E模块关机机,拉低PWR大于1S小于5S
335.        *************************************************************************************************************************/
336.        void GU900E_HardwarePowerDOWN(void)
337.        {
338.          GU900E_SetPWR(1);   //恢复高电平
339.          GSM_DelayMS(200);
340.          GU900E_SetPWR(0);   //拉低1500ms关机
341.          GSM_DelaySer(1);      
342.          GSM_DelayMS(500);
343.          GU900E_SetPWR(1);   //恢复高电平
344.          GSM_DelaySer(2);    //延时2S等待注销网络                     
345.        }
346.          
347.          
348.          
349.          
350.          
351.        /*************************************************************************************************************************
352.        * 函数                :   void GU900E_HardwareReset(void)
353.        * 功能                :   GU900E硬件复位
354.        * 参数                :   无
355.        * 返回                :   无
356.        * 依赖                :   无
357.        * 作者                :   H F Y-GU900
358.        * 时间                :   2016-5-18
359.        * 最后修改时间    :   2016-5-18
360.        * 说明                :   用于GU900E模块硬件复位
361.        *************************************************************************************************************************/
362.        void GU900E_HardwareReset(void)
363.        {
364.          GU900E_SetRESET(1); //恢复高电平
365.          GSM_Delay100MS();
366.          GU900E_SetRESET(0); //拉低100mS复位
367.          GSM_Delay100MS();
368.          GU900E_SetRESET(1); //恢复高电平
369.          GSM_DelaySer(2);    //延时2S                  
370.        }
371.          
372.          
373.        /*************************************************************************************************************************
374.        * 函数            :   bool GU900E_ModuleInit(void)
375.        * 功能            :   初始化GU900E模块
376.        * 参数            :   无
377.        * 返回            :   FALSE:初始化失败;TRUE:初始化成功
378.        * 依赖            :   底层
379.        * 作者            :   H F Y-GU900
380.        * 时间            :   2016-5-16
381.        * 最后修改时间    :   2016-5-16
382.        * 说明            :   主要初始化与GU900E配置,以及初始化网络
383.        *************************************************************************************************************************/
384.        bool GU900E_ModuleInit(void)
385.        {
386.          u32 cnt;
387.          u8 retry = 5;       //重试次数
388.             
389.          //检测模块存在
390.          retry = 5;      //重试次数
391.          do
392.          {
393.                GU900E_SendATcom("AT"); //发送"AT",同步波特率,并且等待应答
394.                if(AT_RETURN_OK == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 10))   //等待响应,超时100ms
395.                {
396.                    break;
397.                }
398.                retry --;
399.          }while(retry);
400.          if(retry == 0) return FALSE;
401.             
402.          //设置关闭回显
403.          retry = GU900E_RETRY;       //重试次数
404.          do
405.          {
406.                GU900E_SendATcom("ATE 0");//发送"ATE",关闭回显模式
407.                if(AT_RETURN_OK == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 10))   //等待响应,超时100ms
408.                {
409.                    GU900E_debug("\r\n关闭AT回显模式成功!\r\n");
410.                    break;
411.                }
412.                
413.                GU900E_Ready(); //等待就绪
414.                retry --;
415.          }while(retry);
416.          if(retry == 0)
417.          {
418.                GU900E_debug("\r\n关闭AT回显模式失败!\r\n");
419.                return FALSE;
420.          }
421.             
422.          //设置短消息格式为PDU格式
423.          retry = GU900E_RETRY;       //重试次数
424.          do
425.          {
426.                GU900E_SendATcom("AT+CMGF=0");//发送"AT+CMGF",设置短消息格式为PDU格式
427.                if(AT_RETURN_OK == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 10))   //等待响应,超时100ms
428.                {
429.                    GU900E_debug("\r\n设置短消息格式为PDU格式成功!\r\n");
430.                    break;
431.                }
432.                
433.                GU900E_Ready(); //等待就绪
434.                retry --;
435.          }while(retry);
436.          if(retry == 0)
437.          {
438.                GU900E_debug("\r\n设置短消息格式为PDU格式失败!\r\n");
439.                return FALSE;
440.          }
441.             
442.          //使能RI引脚提示
443.          retry = GU900E_RETRY;       //重试次数
444.          do
445.          {
446.                GU900E_SendATcom("AT+CFGRI=1"); //发送"AT+CFGRI",启动RI引脚提示
447.                if(AT_RETURN_OK == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 10))   //等待响应,超时100ms
448.                {
449.                    GU900E_debug("\r\n启动RI引脚提示成功!\r\n");
450.                    break;
451.                }
452.                GU900E_Ready(); //等待就绪
453.                retry --;
454.          }while(retry);
455.          if(retry == 0)
456.          {
457.                GU900E_debug("\r\n启动RI引脚提示失败!\r\n");
458.                return FALSE;
459.          }
460.             
461.          //设置模块sleep模式使能
462.          retry = GU900E_RETRY;       //重试次数
463.          do
464.          {
465.                GU900E_SendATcom("AT+CSCLK=1"); //发送"AT+CSCLK",启动SLEEP模式
466.                if(AT_RETURN_OK == GU900E_GetATResp(GU900E_Buff, &cnt, "OK", 10, 10))   //等待响应,超时100ms
467.                {
468.                    GU900E_debug("\r\n设置SLEEP成功!\r\n");
469.                    break;
470.                }
471.                
472.                GU900E_Ready(); //等待就绪
473.                retry --;
474.          }while(retry);
475.          if(retry == 0)
476.          {
477.                GU900E_debug("\r\n设置SLEEP失败!\r\n");
478.                return FALSE;
479.          }
480.             
481.          GU900E_SetDTR(1);   //使能SLEEP模式
482.          return TRUE;
483.        }
484.          
485.          
486.          
487.          
488.        /*************************************************************************************************************************
489.        * 函数            :   bool GU900E_TestAT(u32 retry)
490.        * 功能            :   GU900E AT 命令通信测试
491.        * 参数            :   retry:重试次数
492.        * 返回            :   FALSE:通信失败;TRUE:通信成功
493.        * 依赖            :   底层
494.        * 作者            :   H F Y-GU900
495.        * 时间            :   2016-5-18
496.        * 最后修改时间    :   2016-5-18
497.        * 说明            :   每隔20ms向GU900E发送一个"AT",等待响应返回
498.        ***************************************************************************

页: [1]
查看完整版本: GU900E模块实现收发短信,打电话