MC20 模块是一款集成了高性能GNSS 引擎和四频段GSM/GPRS 引擎的多功能无线模块,本次在项目中使用MC20作为通信网关,开发其与服务器通信的功能以及定位功能,稍微学习了一下。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

  1.硬件部分

  GSM/GPRS 部分主要特性:

  基于STM32的MC20模块GPRS+GPS的C语言驱动程序 随笔 第1张

  基于STM32的MC20模块GPRS+GPS的C语言驱动程序 随笔 第2张

 

 

  MC20模块本身集成度较高,如果仅仅是使用的话其实非常简单,只需要了解模块内部的AT指令便可。

  MC20和STM32的接口采用UART,MC20上面有3个串口,分别用不同的功能,但我们项目的硬件设计把GPRS和GPS的串口都设计在了一起,因此只使用一个串口便可以实现通信与定位的功能。

  基于STM32的MC20模块GPRS+GPS的C语言驱动程序 随笔 第3张

    

  硬件不多讲,直接下载官方的手册参照设计即可,如果自己找不到手册,可以联系留下邮箱

  2.驱动部分

   初始化:

  MC20的初始化总体而言分为两个大部分:1.GRRS初始化 2.GPS初始化

  首先解释GPRS初始化:

  GPRS的初始化分为以下6个步骤:

  1.模块硬件检查

  2.SIM状态检查

  3.网络状态检查

  4.GPRS信号强度检查

  5.TCPIP传送模式选择

  6.建立TCP链接

 

  所谓硬件检查,按照手册上描述,其实就是检查一下硬件有没有正常启动,在已经给电,并且通过脉冲激活了MC20的情况下,使用串口向MC20发送一个字符串“AT\r”

  发送字符串以后,会存在3种状态,1.什么也没收到 2.收到“OK” 3.收到其他字符串。

  有且只有在第二种的情况下才代表通信正常,由于STM32与MC20的通信几乎都是这种一问一答的模式,因此特地做一个函数来进行这个工作的处理。

  函数功能:使用串口发送一个字符串:AT_CMD,然后等待,在wait_time_ms时间内如果串口有信息返回,那么就进行判断,判断返回信息中是否包含自己需要的字符串:return_value,如果有返回TRUE,如果没有返回FALSE。

 1 uint8_t MC20_SendAtCmd(char *AT_CMD, char *return_value, uint32_t wait_time_ms)
 2 { 4     uint32_t time;
 5     uint8_t res;
 6 
 7     if(NULL == AT_CMD)
 8     {
 9         return 0;
10     }
11 
12     MC20_ClearFlag();
13     /* 发送命令 */
14     MC20_SendData((uint8_t *)AT_CMD, strlen(AT_CMD));
15     if(NULL == return_value)
16     {
17         return 1;
18     }
19 
20     time = u32SysTime;
21     /* 延时溢出 */
22     while(u32SysTime-time < wait_time_ms)
23     {
24         /* 收到模块返回信息 */
25         if(1 == sMC20Rev.flag)
26         {   /* 比较接收到的字符串 */
29             res = Search_Str((uint8_t *)&sMC20Rev.buf[sMC20Rev.read], sMC20Rev.len,(uint8_t *)return_value, strlen(return_value));
30             MC20_ClearFlag();
31             if(1 == res)
32             {
33                 return 1;
34             }
35         }
36 
37     }
38 
39     return 0;
40 }

  

参数AT_CMD:STM32向MC20发送的命令(字符串)
参数return_value:如果一切正常,那么MC20应该返回的命令(字符串)

参数
wait_time_ms:延时时间(毫秒级别,使用系统滴答时钟)

函数功能:使用串口向MC20发送一个指令,然后等待MC20返回应答,在规定的时间内如果接收到了希望的命令,那么返回TURE,否则返回FALSE。

函数MC20_ClearFlag的功能是清空一些flag,等MC20的串口中断收到数据以后,会置位这些flag。
函数MC20_SendData的功能仅仅是包装了一下串口发送的函数。
函数Search_Str的功能仅仅是检查第一个字符串中是否包含第二个字符串的内容,可以简单的理解为比较,这样做是因为MC20返回的信息有时并不单纯,很多时候我们需要的信息并不是第一个字符,比如当他返回字符串“OK”的时候,也许会在前后各添加一个换行符号,如果直接进行两个字符串比较,结果肯定不同。
变量u32SysTime由系统滴答时钟控制,我的是每毫秒增加,根据系统的负荷,可以自己调整。

----------------------------------------------------------------------------
初始化过程如下:
 1     /* 检查模块状态 */
 2      for(i=0;i<5;i++)
 3      {
 4          res = MC20_SendAtCmd("AT", "OK", 500);
 5          if(1 == res)
 6          {
 7              return 1;
 8          }
 9          delay_ms(100);
10      }
11 
12     /* 检查SIM卡状态 */
13     time = u32SysTime;
14     while(1)
15     {
16         res = MC20_SendAtCmd("AT+CPIN?\r", "+CPIN: READY", 400);
17         if(1 == res)
18         {
19             break;
20         }
21         if(u32SysTime - time > 5000)
22         {
23             return ;
24         }
25         delay_ms(400);
26     }
27 
28     /* 检查网络状态 */
29     time = u32SysTime;
30     while(1)
31     {
32         /* 检查网络状态 本地网络 */
33         res = MC20_SendAtCmd("AT+CREG?\r", "+CREG: 0,1", 400);
34         if(1 == res)
35         {
36             break;
37         }
38          /* 检查网络状态 漫游 */
39         res = MC20_SendAtCmd("AT+CREG?\r", "+CREG: 0,5", 400);
40         if(1 == res)
41         {
42             break;
43         }
44         if(u32SysTime - time > 5000)
45         {
46             return ;
47         }
48         delay_ms(400);
49     }
50 
51     /* 检查GPRS信号强度 */
52     time = u32SysTime;
53     while(1)
54     {
55         res = MC20_SendAtCmd("AT+CGATT?\r", "+CGATT: 1", 400);
56         if(1 == res)
57         {
58             break;
59         }
60         res = MC20_SendAtCmd("AT+CGATT?\r", "+CGATT: 5", 400);
61         if(1 == res)
62         {
63             break;
64         }
65         if(u32SysTime - time > 120000)
66         {
67             return ;
68         }
69         delay_ms(500);
70     }
71 
72     /* 选择TCPIP传送模式 */
73     res = MC20_SendAtCmd("AT+QIMODE=1\r", "OK", 600);
74     if(0 == res)
75     {
76         return ;
77     }

  当一切准备就绪之后,开始建立TCP连接。

  

 1     res = MC20_SendAtCmd("AT+QIOPEN=\"TCP\",\"114.55.114.201\",9088\r", "CONNECT\r", 60000);  // 具体数据格式请参考手册
 2     if(1 == res)
 3     { 5         return 1;
 6     }
 7     else
 8     {10         return 0;
11     }

    如果连接建立成功,接下来就可以往服务器发送数据了,例如:MC20_SendData("Test", 5);发送一个测试命令。

 

 

 

 

 


  

 

 

  

  

 

  

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄