菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
187
0

GSM/GPRS/3G/4G

原创
05/13 14:22
阅读数 50469

1、状态机机制的gprs拨号

像GPRS/3G模块之类的应用,需要连接,登陆,初始化等步骤完成后才能传输数据,而这些步骤又比较耗时。

所以用 状态机 + 超时 的机制来实现比较合理。

如下代码片段来描述数据透传 : 状态机 + 超时 这种机制(代码片段,仅用来描述一种思路)

以下程序是在没有操作系统调度机制下调试的,所以超时用的心跳,如果是linux下,有sleep更方便。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SERVER_IP "115.29.140.xxx"
#define SERVER_PORT   "8082"

#define BUFF_LEN 64
char aUart5RxBuffer[BUFF_LEN];

static int gprs_init_ok= 0;
static int ppp_config_ok = 0;

void gprs_init(void)
{      
    if((strstr(aUart5RxBuffer, "command ready") == NULL)
        /*||(strstr(aUart5RxBuffer, "+SIM READY") == NULL)*/) 
    {
         gprs_init_ok = 0;            
    }
    else
    {
         gprs_init_ok = 1;   
    } 

}

void reset_gprs(void)
{
    memset(aUart5RxBuffer, 0, BUFF_LEN);
    gprs_init_ok= 0;
    ppp_config_ok = 0;
    //reset 3g module;
}

void ppp_config(void)
{  
    static uint32_t ppp_config_step = 0; 
    static uint32_t gprs_tick = 0;
        
    switch (ppp_config_step)
    {
        case 0:
            gprs_puts("AT+GTSET=\"LPMMODE\",0\r\n");
            gprs_tick = msTicks;            
            ppp_config_step = 1; 
            break;
        case 1:
            if((msTicks - gprs_tick) > 500)
            {        
                if(strstr(aUart5RxBuffer, "OK") == NULL)                   
                {
                    ppp_config_step = 0;                    
                }
                else
                {
                    ppp_config_step = 2; 
                                   
                }
                memset(aUart5RxBuffer, 0, BUFF_LEN);                          
            }                
            break;
                            
        case 2:
            gprs_puts("AT+CPIN?\r\n");
            ppp_config_step = 3;
            gprs_tick = msTicks;
            break;        
        case 3:
            if((msTicks - gprs_tick) > 500)
            {
                if((strstr(aUart5RxBuffer, "OK") == NULL) || (strstr(aUart5RxBuffer, "+CPIN: READY") == NULL))
                {
                    ppp_config_step = 2;
                }
                else
               {
                ppp_config_step = 4;
                                                                      
               }
               memset(aUart5RxBuffer, 0, BUFF_LEN);
            }            
            break;          
            
        case 4:
            gprs_puts("AT+CSQ\r\n");
            ppp_config_step = 5;
            gprs_tick = msTicks;
            break;
        case 5:
            if((msTicks - gprs_tick) > 500)
            {
                if(strstr(aUart5RxBuffer, "OK") == NULL)
                {
                    ppp_config_step = 4;
                }
                else
                {
                    ppp_config_step = 6;                           
                }
                memset(aUart5RxBuffer, 0, BUFF_LEN);
            }            
            break;
                         
        case 6:
            gprs_puts("AT+CREG?\r\n");
            ppp_config_step = 7;
            gprs_tick = msTicks;
            break;
        case 7:
            if((msTicks - gprs_tick) > 500)
            {
                if(strstr(aUart5RxBuffer, "+CREG: 0,0") == NULL)
                {
                    ppp_config_step = 8;
                }
                else
                {
                    ppp_config_step = 6;                   
                }
                memset(aUart5RxBuffer, 0, BUFF_LEN);
            }            
            break;
            
        case 8:
            //gprs_puts("AT+MIPCALL=1,\"3GNET\"\r\n");
            gprs_puts("AT+MIPCALL=1,\"xagfzqx.ydoa.snapn\"\r\n");
            ppp_config_step = 9;
            gprs_tick = msTicks;
            break;
        case 9:
            if((msTicks - gprs_tick) > 3000)
            {
                if(strstr(aUart5RxBuffer, "+MIPCALL: 0") == NULL)
                {
                    ppp_config_step = 0;
                    ppp_config_ok = 1;                    
                }
                else
                {
                    ppp_config_step = 8;                                     
                }
                memset(aUart5RxBuffer, 0, BUFF_LEN);
            }            
            break;             
                   
        default:
            break;
    }    
       
}

void http_Send_test(char *data)
{
    static unsigned char http_send_step = 0;
    static int send_err_cnt = 0;
    
    switch (http_send_step)
    {                       
    case 0: 
        memset(data_tx_buf, 0, sizeof(data_tx_buf)); 
        strcat(data_tx_buf, data);        
        gprs_puts("GET /app/pulse-wave/commit?");
        gprs_puts("%s",data_tx_buf);                   
        gprs_puts("\r\n");    
                             
        http_send_step = 1;
        gprs_tick = msTicks;
        
        break;
    
    case 1:

        if((strstr(aUart5RxBuffer, "{\"msg\":\"commit pulse-wave data success.\",\"result\":true}") != NULL)
            &&(strstr(aUart5RxBuffer, "+MIPSTAT: 1,1") != NULL)
            &&((msTicks - gprs_tick) < 1000))                   
        { 
                       
        }
        else
        { 
            if(++send_err_cnt > 3) {
                reset_gprs();
                send_err_cnt = 0;
            } 
                                                                                                      
        }
     
     memset(aUart5RxBuffer, 0, BUFF_LEN);   
        http_send_step = 0;              
            
        break;                                              
   
    default:
        break;
               
    }            
}
    

void main(void)
{  
    while(1)
    {  
       if(!gprs_init_ok)                        { gprs_init(); }
       
       if((gprs_init_ok)&&(!ppp_config_ok))     { ppp_config(); } 
         
       if(ppp_config_ok)                        { http_Send_test("hello,world"); }  
    }                                      
}


初始化成功了就可以传输数据了,数据发送和接收都跟串口一样。主要工作都在初始化 ,和异常修复机制的实现。因为网络传输每一步都可能会失败,而且外部因素太多,所以异常修复机制尤其重要。

 

2、用开源的ppp/pppoe指令拨号也一样

ppp

https://download.samba.org/pub/ppp/

pppoe

https://www.roaringpenguin.com/products/pppoe

eg:

https://blog.csdn.net/a746742897/article/details/52421461

 

1) 3g

https://blog.csdn.net/qq_21792169/article/details/51271833

https://blog.csdn.net/yangzheng_yz/article/details/9315287

2) 4g

https://www.cnblogs.com/cryhuang/p/5649372.html

http://blog.sina.com.cn/s/blog_7880d3350102wb92.html

 

3g/4g一样的

ppp

https://download.samba.org/pub/ppp/

pppoe

https://www.roaringpenguin.com/products/pppoe

eg:

https://blog.csdn.net/a746742897/article/details/52421461

 

1) 3g

https://blog.csdn.net/qq_21792169/article/details/51271833

https://blog.csdn.net/yangzheng_yz/article/details/9315287

2) 4g

https://www.cnblogs.com/cryhuang/p/5649372.html

http://blog.sina.com.cn/s/blog_7880d3350102wb92.html

 

3g/4g一样的

end

 

发表评论

0/200
187 点赞
0 评论
收藏
为你推荐 换一批