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编码
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. ***************************************************************************
**********************************************/
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]