GSM_func.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include "main.h"
  2. //// C lib
  3. //#include <stdlib.h>
  4. //#include <string.h>
  5. //#include <stdio.h>
  6. //// system
  7. //#include "delay.h"
  8. // GSM
  9. #include "GSM_config.h"
  10. static char* GSM_check_cmd(char *str);
  11. static void GSM_sendData(char* fmt,...);
  12. // GSM信息
  13. const char* GSM_phoneNum = "19198022169";
  14. const char* GSM_head = "send:";
  15. /**
  16. * @brief 向GSM串口发送数据
  17. * @param fmt: 类似printf的数据格式
  18. * @retval None
  19. * @note None
  20. */
  21. void GSM_sendData(char* fmt,...)
  22. {
  23. uint16_t i,j;
  24. va_list ap;
  25. va_start(ap,fmt);
  26. vsprintf((char*)GSM_USART_TX_BUF,fmt,ap);
  27. va_end(ap);
  28. i = strlen((const char*)GSM_USART_TX_BUF);
  29. for(j=0; j<i; j++)
  30. {
  31. while(USART_GetFlagStatus(GSM_USARTx,USART_FLAG_TC)==RESET);
  32. USART_SendData(GSM_USARTx,GSM_USART_TX_BUF[j]);
  33. }
  34. }
  35. /**
  36. * @brief 检测应答
  37. * @param str: 期待的应答结果
  38. * @retval 0: 没有接收到期待应答
  39. * @retval !0: 其他值代表期待应答结果的位置
  40. * @note None
  41. */
  42. static char* GSM_check_cmd(char *str)
  43. {
  44. char *strx=0;
  45. // 接收到一次数据了
  46. if(GSM_USART_RX_STA&0X8000)
  47. {
  48. // 添加结束符
  49. GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
  50. // 检索字符串
  51. strx=strstr(GSM_USART_RX_BUF,str);
  52. #ifdef DEBUG_printf
  53. printf("rec data: %s\n",GSM_USART_RX_BUF);
  54. #endif
  55. }
  56. return strx;
  57. }
  58. /**
  59. * @brief 向GSM发送命令
  60. * @param cmd: 发送的命令字符串
  61. * @param ack: 期待的应答结果,如果为空,则表示不需要等待应答
  62. * @param waittime: 等待时间(单位:10ms)
  63. * @retval 0: 发送成功(得到了期待的应答结果),
  64. * @retval 1: 发送失败
  65. * @note None
  66. */
  67. char GSM_send_cmd(char *cmd,char *ack,uint16_t waittime)
  68. {
  69. char res=0;
  70. GSM_USART_RX_STA=0;
  71. //发送命令
  72. GSM_sendData("%s",cmd);
  73. if(ack&&waittime) //需要等待应答
  74. {
  75. while(--waittime) //等待倒计时
  76. {
  77. DELAYClass.DelayMs(10);
  78. if(GSM_USART_RX_STA&0X8000)//接收到期待的应答结果
  79. {
  80. if(GSM_check_cmd(ack) != ((void *)0))
  81. {
  82. break; // 得到有效数据
  83. }
  84. GSM_USART_RX_STA=0;
  85. }
  86. }
  87. if(waittime==0)res=1;
  88. }
  89. return res;
  90. }
  91. /**
  92. * @brief string转换int
  93. * @param *str:字符串地址
  94. * @retval 返回int型
  95. * @note None
  96. */
  97. int stringToInt(char *str)
  98. {
  99. char *p = str;
  100. int nNUM = 0;
  101. while (*p >= '0' && *p <= '9')
  102. {
  103. nNUM = nNUM * 10 + (*p - '0');
  104. p++;
  105. }
  106. return nNUM;
  107. }
  108. /**
  109. * @brief 发送短信
  110. * @param None
  111. * @retval None
  112. */
  113. void GSM_sendMessage(char *message)
  114. {
  115. char p[40];
  116. #ifdef DEBUG_printf
  117. printf("0. AT+CPIN?\n");
  118. #endif
  119. while(GSM_send_cmd("AT+CPIN?\r\n","OK",100)); // 查询卡状态
  120. #ifdef DEBUG_printf
  121. printf("1. AT+CMGF=1\n");
  122. #endif
  123. while(GSM_send_cmd("AT+CMGF=1\r\n","OK",100)); // 设置TXT模式
  124. #ifdef DEBUG_printf
  125. printf("2. AT+CMGS=\n");
  126. #endif
  127. sprintf((char*)p,"AT+CMGS=\"%s\"\r\n",GSM_phoneNum); // 设置目标手机号
  128. while(GSM_send_cmd(p,">",100));
  129. DELAYClass.DelayMs(50);
  130. #ifdef DEBUG_printf
  131. printf("3. %s\n",message);
  132. #endif
  133. sprintf((char*)p,"%s\r\n",message); // 设置发送内容
  134. GSM_send_cmd(p,">",100);
  135. DELAYClass.DelayMs(50);
  136. #ifdef DEBUG_printf
  137. printf("4. %x\n", 0x1A);
  138. #endif
  139. USART_SendData(USART2, 0x1A); // 确认发送
  140. }
  141. /**
  142. * @brief 等待接收短信
  143. * @param None
  144. * @retval 0:无短信,!0:接收到的短信的存放地址
  145. */
  146. uint8_t GSM_waitMessage(void)
  147. {
  148. // 接收到一次数据了
  149. if(GSM_USART_RX_STA&0X8000)
  150. {
  151. GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0; // 添加结束符
  152. #ifdef DEBUG_printf
  153. printf("(waitMes)%s\n", GSM_USART_RX_BUF);
  154. #endif
  155. char *strx = 0;
  156. // 检索字符串 含有"SM",则代表接收到短信
  157. strx=strstr(GSM_USART_RX_BUF,"\"SM\",");
  158. // 返回不为空则检索到指定字符串
  159. if(strx != ((void *)0))
  160. {
  161. #ifdef DEBUG_printf
  162. printf("message rec success, addr : %d\n", stringToInt(strx+5));
  163. #endif
  164. uint8_t addrNum = stringToInt(strx+5); // 将地址号保存
  165. GSM_USART_RX_STA = 0; // 清除接收标记
  166. return addrNum;
  167. }
  168. GSM_USART_RX_STA = 0;
  169. }
  170. return 0;
  171. }
  172. /**
  173. * @brief 查看短信
  174. * @param None
  175. * @retval 返回帧头后的一个字节数据
  176. */
  177. char GSM_readMessage(uint8_t addrNum)
  178. {
  179. char pp[40];
  180. uint8_t i = 0;
  181. sprintf((char*)pp,"AT+CMGR=%d\r\n",addrNum); // 查看该地址下的短信
  182. GSM_USART_RX_STA = 0;
  183. // 等待2s
  184. for(i = 0; i <= 200; i++)
  185. {
  186. if(i % 50 == 0) // 每0.5s重发一次
  187. {
  188. #ifdef DEBUG_printf
  189. printf("i = %d\n", i);
  190. #endif
  191. GSM_sendData("%s", pp);
  192. }
  193. DELAYClass.DelayMs(10);
  194. if(GSM_USART_RX_STA&0X8000)
  195. {
  196. // 添加结束符
  197. GSM_USART_RX_BUF[GSM_USART_RX_STA&0X7FFF]=0;
  198. #ifdef DEBUG_printf
  199. printf("(readMes)%s\n", GSM_USART_RX_BUF);
  200. #endif
  201. char *strx = 0;
  202. // 检索字符串 含有"send:",则代表查看短信成功
  203. strx=strstr(GSM_USART_RX_BUF,GSM_head);
  204. // 返回不为空则检索到指定字符串
  205. if(strx != ((void *)0))
  206. {
  207. #ifdef DEBUG_printf
  208. printf("message read success, cmd : %c\n", strx[5]);
  209. #endif
  210. char cmd = 0;
  211. cmd = strx[5]; // 此处可根据需求修改 当前是返回的send:后的一个字节
  212. GSM_USART_RX_STA = 0; // 清除接收标记
  213. DELAYClass.DelayMs(10);
  214. sprintf((char*)pp,"AT+CMGD=%d\r\n",addrNum); // 删除该地址下的短信
  215. GSM_sendData("%s", pp);
  216. return cmd;
  217. }
  218. GSM_USART_RX_STA = 0;
  219. }
  220. }
  221. GSM_USART_RX_STA = 0;
  222. return 0;
  223. }
  224. /**
  225. * @brief GSM初始化
  226. * @param None
  227. * @retval None
  228. * @note None
  229. */
  230. void GSM_Init(void)
  231. {
  232. GSM_USART_Init(9600);
  233. GSM_TIM3_Init();
  234. }