3372|4

13

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

一个关于GPRS通信的代码求详细注解 [复制链接]

我是菜鸟,代码中的AT命令不需要什么封装就直接放在函数里么,直接就能被识别了?



  1. #include
  2. #include

  3. #include "def.h"
  4. #include "option.h"
  5. #include "2410addr.h"
  6. #include "2410lib.h"
  7. //#include "2410slib.h"
  8. //#include "mmu.h"
  9. #include "gprs.h"

  10. #define USE_TICK
  11. //#define USE_TIMERTEST

  12. struct MenuItem
  13. {
  14. char *name;
  15. void (*func)(void);
  16. };


  17. #ifdef USE_TICK
  18. static volatile unsigned int TickCount = 0;
  19. static void InitTick(void);
  20. #ifdef USE_TIMERTEST
  21. static void TimerTest(void);
  22. #endif
  23. #endif

  24. #ifdef USE_TICK
  25. #define GETTICKCOUNT() (TickCount)
  26. #define SLEEP(time) { \
  27. unsigned int t = GETTICKCOUNT(); \
  28. while(GETTICKCOUNT()-t < (time)) \
  29. { \
  30. IDLEPROCESS(GETDEFAULTCOMMBUF()); \
  31. } \
  32. }
  33. #else
  34. #define GETTICKCOUNT() 0
  35. #endif

  36. /*************************************
  37. *缓冲区管理
  38. *************************************/
  39. #define COMMBUFSIZE 1024
  40. struct CommBuf
  41. {
  42. char buf[COMMBUFSIZE+1];
  43. unsigned int size;
  44. char *rptr;
  45. char *wptr;
  46. };

  47. #define COMMBUF_ISEMPTY(obj) ((obj)->size == 0)
  48. #define COMMBUF_ISFULL(obj) ((obj)->size == COMMBUFSIZE)
  49. #define COMMBUF_DATASIZE(obj) ((obj)->size)
  50. #define COMMBUF_EMPTYSIZE(obj) (COMMBUFSIZE - COMMBUF_DATASIZE(obj))
  51. #define INCRPTR(obj) { \
  52. (obj)->rptr++; \
  53. (obj)->size--; \
  54. if((obj)->rptr >= (obj)->buf + COMMBUFSIZE) \
  55. (obj)->rptr = (obj)->buf; \
  56. }

  57. #define INCWPTR(obj) { \
  58. (obj)->wptr++; \
  59. (obj)->size++; \
  60. if((obj)->wptr >= (obj)->buf + COMMBUFSIZE) \
  61. (obj)->wptr = (obj)->buf; \
  62. }

  63. #define IDLEPROCESS(obj) { \
  64. while(rUFSTAT1 & 0x0f) \
  65. { \
  66. if(COMMBUF_ISFULL(obj)) \
  67. break; \
  68. *((obj)->wptr) = RdURXH1(); \
  69. /*Uart_SendByte(*((obj)->wptr));*/ \
  70. INCWPTR(obj); \
  71. } \
  72. }

  73. static struct CommBuf RecvBuf;
  74. #define GETDEFAULTCOMMBUF() (&RecvBuf)

  75. void InitCommBuf(struct CommBuf *obj)
  76. {
  77. if(obj == NULL)
  78. return;
  79. memset(obj->buf, 0, sizeof(obj->buf));
  80. obj->size = 0;
  81. obj->rptr = obj->wptr = obj->buf;
  82. }

  83. void CommBuf_Clean(struct CommBuf *obj)
  84. {
  85. if(obj == NULL)
  86. return;
  87. obj->size = 0;
  88. obj->rptr = obj->wptr;
  89. }

  90. void CommBuf_Dump(struct CommBuf *obj)
  91. {
  92. SLEEP(1000);
  93. //Uart_Printf("\n----------log----------\n");
  94. //Uart_Printf(RecvBuf.buf);
  95. //Uart_Printf("\n----------end----------\n");
  96. }

  97. //从缓冲区读一个字符
  98. char CommBuf_ReadChar(struct CommBuf *obj, int timeout, int *err)
  99. {
  100. char c;
  101. unsigned int t = GETTICKCOUNT();
  102. while(COMMBUF_ISEMPTY(obj))
  103. {
  104. if(GETTICKCOUNT()-t > timeout)
  105. {
  106. if(err != NULL)
  107. *err = -1;
  108. return '\0';
  109. }
  110. IDLEPROCESS(obj);
  111. }
  112. c = *obj->rptr;
  113. INCRPTR(obj);
  114. if(err != NULL)
  115. *err = 0;
  116. return c;
  117. }

  118. //等待字符串,成功返回0,否则返回-1。
  119. int CommBuf_WaitString(struct CommBuf *obj, char *str, int timeout)
  120. {
  121. int err;
  122. char c;
  123. char *p = str;
  124. while(1)
  125. {
  126. if(*p == '\0')
  127. return 0;
  128. c = CommBuf_ReadChar(obj, timeout, &err);
  129. if(err)
  130. break;
  131. if(*p == c)
  132. p++;
  133. else
  134. {
  135. p = str;
  136. if(*p == c)
  137. p++;
  138. }
  139. }
  140. return -1;
  141. }

  142. //读缓冲区
  143. int ReadCommBuf(struct CommBuf *obj, void *pBuf, size_t sizebuf, unsigned int timeout)
  144. {
  145. int i;
  146. char *buf = pBuf;
  147. unsigned int t;
  148. if(obj == NULL)
  149. return -2;
  150. t = GETTICKCOUNT();
  151. while(COMMBUF_ISEMPTY(obj))
  152. {
  153. if(GETTICKCOUNT()-t > timeout)
  154. return -1;
  155. IDLEPROCESS(obj);
  156. }

  157. for(i=0; i
  158. {
  159. while(COMMBUF_ISEMPTY(obj))
  160. {
  161. if(GETTICKCOUNT()-t > timeout/*100*/)
  162. return i;
  163. IDLEPROCESS(obj);
  164. }
  165. *buf = *obj->rptr;
  166. INCRPTR(obj);
  167. IDLEPROCESS(obj);
  168. }
  169. return i;
  170. }

  171. #if 0
  172. int WriteCommBuf(struct CommBuf *obj, void *pBuf, size_t size)
  173. {
  174. int i;
  175. char *buf = pBuf;
  176. if(obj == NULL)
  177. return 0;
  178. if(size > COMMBUF_EMPTYSIZE(obj))
  179. {
  180. return 0;
  181. }

  182. for(i=0; i < size; i++)
  183. {
  184. *(obj->wptr) = *buf;
  185. INCWPTR(obj);
  186. }
  187. return i;
  188. }
  189. #endif


  190. /********************************************/
  191. //GPRS 初始化和通信处理

  192. static void InitUart1(int baud)
  193. {
  194. int i;
  195. rGPHCON = 0x2afaaa;
  196. rGPHUP = 0x7ff;

  197. rULCON1 = 0x03;
  198. rUFCON1 = 0x07;//(3<<6) | (3<<4) | (1<<2) | (1<<1) | (1<<0);//0x07;
  199. rUCON1 = 0x005;//0x245;
  200. rUBRDIV1=((int)(PCLK/(16*baud))-1);
  201. for(i=0;i<5000;i++);
  202. rUMCON1 = 0x10;
  203. }

  204. //GPRS 初始化
  205. static void InitGPRS(void)
  206. {
  207. InitUart1(9600);//初使化串口1
  208. #ifdef USE_TICK
  209. InitTick();
  210. #ifdef USE_TIMERTEST
  211. TimerTest();
  212. #endif//USE_TIMERTEST
  213. #endif//USE_TICK
  214. }


  215. void GPRS_SendChar(char c)
  216. {
  217. while(rUFSTAT1 & 0x200)
  218. {
  219. IDLEPROCESS(GETDEFAULTCOMMBUF());
  220. }
  221. WrUTXH1(c);
  222. }

  223. void GPRS_SendString(char *str)
  224. {
  225. for(; *str; str++)
  226. {
  227. GPRS_SendChar(*str);
  228. }
  229. }

  230. //用“AT”命令测试GPRS模块,成功返回1,否则返回0
  231. int GPRS_TestGPRS(void)
  232. {
  233. char log[32];
  234. int len;
  235. InitCommBuf(GETDEFAULTCOMMBUF());
  236. GPRS_SendString("at\r");
  237. if((len=ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000)) > 0)
  238. {
  239. log[len] = '\0';
  240. if(strstr(log, "OK"))
  241. return 1;
  242. }
  243. return 0;
  244. }


  245. /***********************************************/
  246. //短信功能

  247. //发送短消息,成功返回0,否则返回 -1:GPRS模块没有应答、-2:操作被拒绝、-3:发送失败
  248. int GPRS_SendTextSMS(char *phone, char *text)
  249. {
  250. char log[64];
  251. int len;

  252. InitCommBuf(GETDEFAULTCOMMBUF());
  253. //初使化CommBuf
  254. GPRS_SendString("at+csca="+8613800571500"\r"); //by cx 设置短消息中心
  255. SLEEP(1000);
  256. // 延时
  257. GPRS_SendString("at+cmgf=1\r"); //by cx 设置短消息格式
  258. SLEEP(1000);
  259. CommBuf_Clean(GETDEFAULTCOMMBUF());

  260. //清空CommBuf

  261. GPRS_SendString("at+cmgs="");
  262. GPRS_SendString(phone);
  263. GPRS_SendString(""\r");
  264. len = ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000);
  265. if(len > 0)
  266. {
  267. log[len] = '\0';
  268. Uart_Printf(log);
  269. if(strstr(log, "> ") && !strstr(log, "ERROR"))
  270. {
  271. GPRS_SendString(text);
  272. GPRS_SendString("\x1a\r");
  273. if(!CommBuf_WaitString(GETDEFAULTCOMMBUF(), "OK", 10000))
  274. return 0;//发送成功
  275. else
  276. return -3;//发送失败
  277. }

  278. return -2;//操作被拒绝
  279. }
  280. return -1;//GPRS模块没有应答
  281. }

  282. //发送短信UI
  283. void GPRS_SendSmsUI(void)
  284. {
  285. char tel[32];
  286. char smstext[512];

  287. Uart_Printf("\n\n[发送短信息]");
  288. Uart_Printf("\n电话号码:");
  289. Uart_GetString(tel);
  290. //从串口读出电话号码
  291. Uart_Printf("\n短信内容:\n");
  292. Uart_GetString(smstext);
  293. // 从串口读出短信息
  294. Uart_Printf("\n正在发送...");



  295. switch(GPRS_SendTextSMS(tel, smstext))
  296. {
  297. case -1:
  298. Uart_Printf("\n***GPRS模块没有应答");
  299. break;
  300. case -2:
  301. Uart_Printf("\n***操作被拒绝");
  302. break;
  303. case -3:
  304. Uart_Printf("\n***发送失败");
  305. break;
  306. case 0:
  307. Uart_Printf("\n发送成功");
  308. break;
  309. }
  310. CommBuf_Dump(GETDEFAULTCOMMBUF());
  311. }


  312. /***********************************/
  313. //电话功能

  314. //设置来电显示
  315. int GPRS_InitCall(void)
  316. {
  317. char log[32];
  318. int len;
  319. InitCommBuf(GETDEFAULTCOMMBUF());
  320. GPRS_SendString("AT+CR=1\r");
  321. len = ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000);
  322. if(len > 0)
  323. {
  324. log[len] = '\0';
  325. if(strstr(log, "OK"))
  326. {
  327. CommBuf_Clean(GETDEFAULTCOMMBUF());
  328. GPRS_SendString("AT+CLIP=1\r");
  329. len = ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000);
  330. if(len > 0)
  331. {
  332. log[len] = '\0';
  333. if(strstr(log, "OK"))
  334. return 0;//成功
  335. }
  336. }
  337. }
  338. return -1;//失败
  339. }

  340. //电话呼叫
  341. int GPRS_Call(char *phone, volatile int *stop)
  342. {
  343. char log[128];
  344. unsigned int t;
  345. int len, ret;
  346. InitCommBuf(GETDEFAULTCOMMBUF());
  347. GPRS_SendString("atd");
  348. GPRS_SendString(phone);
  349. GPRS_SendString(";\r");
  350. Uart_Printf("\n正在呼叫...");
  351. SLEEP(1000);
  352. CommBuf_Clean(GETDEFAULTCOMMBUF());
  353. t = GETTICKCOUNT();
  354. len = 0;
  355. do
  356. {
  357. ret = ReadCommBuf(GETDEFAULTCOMMBUF(), &log[len], sizeof(log)-1-len, 1000);
  358. if(ret > 0)
  359. {
  360. len += ret;
  361. log[len] = '\0';
  362. //Uart_Printf(log);
  363. if(strstr(log, "OK"))
  364. {
  365. Uart_Printf("\n已经接通。");
  366. SLEEP(5000);
  367. }
  368. else if(strstr(log, "BUSY"))
  369. {
  370. Uart_Printf("\nBUSY");
  371. }
  372. else if(strstr(log, "NO ANSWER"))
  373. {
  374. Uart_Printf("\nNO ANSWER");
  375. }
  376. else if(strstr(log, "NO CARRIER"))
  377. {
  378. Uart_Printf("\nNO CARRIER");
  379. }
  380. else
  381. {
  382. continue;
  383. }
  384. ret = 0;
  385. break;
  386. }
  387. ret = -1;
  388. }while(GETTICKCOUNT()-t < 120000);
  389. GPRS_SendString("ath\r");
  390. if(ret == -1)
  391. Uart_Printf("\n无应答。");
  392. SLEEP(1000);
  393. return ret;
  394. }

  395. void GPRS_CallUI(void)
  396. {
  397. char phone[32];
  398. Uart_Printf("\n[电话呼叫]\n电话号码:");
  399. Uart_GetString(phone);
  400. GPRS_Call(phone, NULL);
  401. CommBuf_Dump(GETDEFAULTCOMMBUF());
  402. }

  403. /***********************************/
  404. //AT命令行接口
  405. static void GPRS_CommandLine(void)
  406. {
  407. char key=0;
  408. Uart_Printf("\n[GPRS AT命令]\n");
  409. while(1)
  410. {
  411. if(rUFSTAT0 & 0x0f)
  412. {
  413. key = RdURXH0();//串口0读出数据
  414. if(key == 0x1b)
  415. break;
  416. while(rUFSTAT1 & 0x200);
  417. WrUTXH1(key);//串口1写数据
  418. }

  419. if(rUFSTAT1 & 0x0f)
  420. {
  421. while(rUFSTAT0 & 0x200);
  422. //WrUTXH0(RdURXH1());
  423. key = RdURXH1();
  424. if(rUERSTAT1 & 0x0f);
  425. //Uart_Printf("");
  426. WrUTXH0(key);
  427. }
  428. }
  429. }


  430. /***********************************/
  431. //菜单处理

  432. const struct MenuItem menu[] = {
  433. {"AT命令行", GPRS_CommandLine},
  434. {"发送短信", GPRS_SendSmsUI},
  435. {"电话呼叫", GPRS_CallUI}
  436. };//数组变量
  437. #define MENUITEMCOUNT (sizeof(menu)/sizeof(menu[0]))

  438. static int ShowMenu(void)
  439. {
  440. int i;
  441. Uart_Printf("\n\n\n--------= GPRS MENU =--------\n");
  442. for(i=0; i
  443. {
  444. Uart_Printf(" [%d] %s\n", i, menu[i].name);
  445. }
  446. Uart_Printf("选择:");
  447. do//输入所选的菜单
  448. {
  449. i = Uart_Getch() - '0';//字符变成数字
  450. }while(i<0 || i>=MENUITEMCOUNT);//对输入的数字是否有效
  451. Uart_Printf("%d\n", i);
  452. return i;
  453. }

  454. void GPRS_Test(void)
  455. {
  456. int i;
  457. InitGPRS();//初使化GPRS
  458. InitCommBuf(GETDEFAULTCOMMBUF());
  459. if(!GPRS_TestGPRS())
  460. {
  461. Uart_Printf("\n没有检测到GPRS模块。");
  462. return;
  463. }
  464. while(1)
  465. {
  466. i = ShowMenu();//打印菜单
  467. if(menu[i].func)
  468. menu[i].func();
  469. }
  470. }


  471. /*****************************************/
  472. #ifdef USE_TICK
  473. #ifdef USE_TIMERTEST
  474. static void TimerTest(void)
  475. {
  476. unsigned int t;
  477. char h,m,s;
  478. Uart_Printf("\n[Timer Test]\n");
  479. Uart_Printf("\nHour:");
  480. h = Uart_GetIntNum();
  481. Uart_Printf("\nMin:");
  482. m = Uart_GetIntNum();
  483. Uart_Printf("\nSec:");
  484. s = Uart_GetIntNum();
  485. Uart_Printf("\n\n%02d:%02d:%02d", h, m, s);
  486. t = GETTICKCOUNT();
  487. while(1)
  488. {
  489. if(GETTICKCOUNT() - t > 1000)
  490. {
  491. t = GETTICKCOUNT();
  492. if(s < 59)
  493. s++;
  494. else if(m < 59)
  495. {
  496. s = 0;
  497. m++;
  498. }
  499. else if(h < 23)
  500. {
  501. s = m = 0;
  502. h++;
  503. }
  504. else
  505. {
  506. s = m = h = 0;
  507. }
  508. Uart_Printf("\b\b\b\b\b\b\b\b%02d:%02d:%02d", h, m, s);
  509. }
  510. }
  511. }
  512. #endif //USE_TIMERTEST

  513. static void __irq TickCountInt(void)
  514. {
  515. rSRCPND = BIT_TIMER4;
  516. rINTPND = BIT_TIMER4;
  517. if(rINTPND);
  518. TickCount++;
  519. }

  520. static void InitTick(void)
  521. {
  522. pISR_TIMER4 = (unsigned)TickCountInt;
  523. rTCFG0 = 0x00fc00; //Dead zone=0,Prescaler1=15(0x0f),Prescaler0=15(0x0f)
  524. rTCFG1 = 0x000000; //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/16
  525. rTCNTB4 = 0x64;
  526. rTCON = 0x600000; //Auto reload, Inverter off, Manual update, Dead zone disable, Stop
  527. rTCON = 0x500000; //Auto reload(T0=One-shot),Inverter off,No operation,Dead zone disable,Start
  528. //
  529. rINTMSK &= ~BIT_TIMER4;
  530. }
  531. #endif //USE_TICK
复制代码

gprs.rar

3.48 KB, 下载次数: 21

最新回复

是的,2410直接发送的是AT命令,为什么 要识别AT命令呢? GSM模块内部识别,并对AT解析!  详情 回复 发表于 2010-6-8 12:59
点赞 关注

回复
举报

2131

帖子

0

TA的资源

至上芯片

沙发
 

回复 楼主 nicmax 的帖子

程序很长
我看了一下程序注释很详细啊,我简单分析两个如果不明白咱们在讨论
比如:
1:GSM是串口操作的所在首先初始化一个串口给GSM
//GPRS 初始化
static void InitGPRS(void)
{
  InitUart1(9600);//初使化串口1
  #ifdef USE_TICK
   InitTick();
  #ifdef USE_TIMERTEST
   TimerTest();
  #endif//USE_TIMERTEST
  #endif//USE_TICK
}
用串口发送给GSM模块 一个字符
void GPRS_SendChar(char c)
{
  while(rUFSTAT1 & 0x200)
  {
    IDLEPROCESS(GETDEFAULTCOMMBUF());
  }
  WrUTXH1(c);
}
用串口发送给GSM模块 字符串
void GPRS_SendString(char *str)
{
   for(; *str; str++)
   {
     GPRS_SendChar(*str);
   }
}
2:操作模块
//用“AT”命令测试GPRS模块,成功返回1,否则返回0
int GPRS_TestGPRS(void)
{
    char log[32];
    int len;
    //初始化串口缓冲
    InitCommBuf(GETDEFAULTCOMMBUF());
    //发送AT
    GPRS_SendString("at\r");
    //读串口 判断是否有数据  正确是应该回复OK
    if((len=ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000)) > 0)
    {
       log[len] = '\0';
       if(strstr(log, "OK"))
       return 1;
    }
  return 0;
}
主要功能就是你发送GSM模块一个 AT字符串 返回一个OK 判断是否成功
3:拿短信功能举例
短信有两种方式
  1:字符方式 下面的代码就是
    基本内容为 at+cmgf=1设置字符模式 如果使用PDU at+cmgf=0
    返回OK
    at+cmgs="手机号"
    >发送内容 +01A
    返回OK
int GPRS_SendTextSMS(char *phone, char *text)
{
   char log[64];
   int len;

   InitCommBuf(GETDEFAULTCOMMBUF());
   //初使化CommBuf
   GPRS_SendString("at+csca=\"+8613800571500\"\r"); //by cx 设置短消息中心
   SLEEP(1000);
   // 延时
   GPRS_SendString("at+cmgf=1\r"); //by cx 设置短消息格式
   SLEEP(1000);
   CommBuf_Clean(GETDEFAULTCOMMBUF());
   //清空CommBuf
   //at+cmgs= "手机号"
   GPRS_SendString("at+cmgs=\"");
   GPRS_SendString(phone);
   GPRS_SendString("\"\r");
  如果接收到数据 发送数据
   len = ReadCommBuf(GETDEFAULTCOMMBUF(), log, sizeof(log)-1, 1000);
   if(len > 0)
   {
     log[len] = '\0';
     Uart_Printf(log);
     if(strstr(log, "> ") && !strstr(log, "ERROR"))
     {
       GPRS_SendString(text);
       GPRS_SendString("\x1a\r");
       if(!CommBuf_WaitString(GETDEFAULTCOMMBUF(), "OK", 10000))
         return 0;//发送成功
       else
         return -3;//发送失败
     }

     return -2;//操作被拒绝
   }
  return -1;//GPRS模块没有应答
}
  2:pDU编码
  首先你应该看PDU编码方式下面的代码你就能看明白了

  PDU中包括 中心号  目标地址手机号  时间 响应参数  数据长度 内容 PDU的号码是需要转换的

[ 本帖最后由 daicheng 于 2010-6-8 11:07 编辑 ]

赞赏

1

查看全部赞赏

 
个人签名处处留心皆学问!
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
恩 那2410是怎么识别AT命令的 我看了代码也没看到 难道2410直接能读出AT+CMGF=1是AT命令吗
 
 
 

回复

2131

帖子

0

TA的资源

至上芯片

4
 

回复 板凳 nicmax 的帖子

是的,2410直接发送的是AT命令,为什么 要识别AT命令呢?
GSM模块内部识别,并对AT解析!
 
个人签名处处留心皆学问!
 
 

回复

13

帖子

0

TA的资源

一粒金砂(初级)

5
 
我以为是要把AT命令转换成一个格式MC55或者2410才能识别
AT命令也就是他们两者之间的通信规则咯
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表