美文网首页物联网loT从业者
STM32F103学习笔记(6)——4G模块EC200S使用

STM32F103学习笔记(6)——4G模块EC200S使用

作者: Leung_ManWah | 来源:发表于2020-09-28 17:10 被阅读0次

    一、简介

    EC200S-CN 是移远通信最近推出的 LTE Cat 1 无线通信模块,支持最大下行速率 10Mbps 和最大上行速率 5Mbps,具有超高的性价比;同时在封装上兼容移远通信多网络制式 LTE Standard EC2x(EC25、EC21、EC20 R2.0、EC20 R2.1)和 EC200T/EG25-G/EG21-G 模块以及 UMTS/HSPA+ UC20/UC200T 模块,实现了 3G 网络与 4G 网络之间的无缝切换。EC200S-CN 还支持标准的 Mini PCIe 封装,以满足不同行业产品应用需求。

    Quectel EC2x 模块具有嵌入式 TCP/IP堆栈,使主机可以通过 AT 命令直接上网。可以实现TCP客户端、UDP客户端、TCP服务器和UDP服务器。

    二、AT指令

    2.1 AT

    测试AT指令功能是否正常,等待模块返回 OK。

    AT
    
    OK
    

    2.2 AT + CPIN?

    查询 SIM 卡状态,返回 READY 则表示SIM卡正常,如果 20 秒后还无法识别 SIM 卡,重新启动模块。

    AT+CPIN?
    
    +CPIN: READY
    
    OK
    

    2.3 AT + CREG?

    查询模组是否注册上GSM网络,如果 90秒后未能在 CS 上注册域名服务,重新启动模块。
    如果返回 1 或 5 ,代表 CS 服务注册成功。
    +CREG:0,1 表示已注册上本地网,+CREG:0,5表示注册上漫游网。

    AT+CREG?
    
    +CREG: 0,1
    
    OK
    

    2.4 AT + CGREG?

    查询模组是否注册上GPRS网络,+CGREG:0,1 表示已注册上本地网,+CGREG:0,5表示注册上漫游网。

    AT+CGREG?
    
    +CGREG: 0,1
    
    OK
    

    2.5 AT + QICSGP=1,1,“CMNET”

    该命令可用于配置<APN>,<username>,<password>等TCP / IP上下文参数。QoS设置可以由AT + CGQMIN,AT + CGEQMIN,AT + CGQREQ和AT + CGEQREQ配置 。

    • AT+QICSGP=?:查询命令参数。
    • AT+QICSGP=<contextID>:查询 contextID的配置信息。
    • AT+QICSGP=<contextID>[,<context_type>,<APN>[,<username>,<password>)[,<authentication>]]]:配置 contextID信息。
      • <contextID>:整数类型。上下文ID。范围是1-16。
      • <context_type>:整数类型。协议类型。1(IPV4)、2(IPV4V6)。
      • <APN>:字符串类型。接入点名称。移动CMNET,联通UNINET
      • <username>:字符串类型。用户名。
      • <password>:字符串类型。密码。
      • <authentication>:整数类型。身份验证方法。0(没有)、1(PAP)、2(CHAP)、3(PAP或CHAP)。
      • 返回信息:OK 或 ERROR。
    AT+QICSGP=1,1,\"CMNET\",\"\",\"\",1
    
    OK
    

    2.6 AT + QIDEACT=1

    在激活GPRS场景之前先关闭GPRS场景,确保连接正确

    AT+QIDEACT=1
    
    OK
    

    2.7 AT + QIACT=1

    激活移动场景

    AT+QIACT=1
    
    OK
    

    2.8 AT+QIOPEN

    该命令用于打开套接字服务。

    • AT+QIOPEN=?:查询命令参数。
    • AT+QIOPEN=<contextID>,<connectID>,<service_type>,<IP_address>/<domain_name>,<remote_port>[,<local_po CONNECTrt>[,<access_mode>]] :打开 Socket 服务。
      • <contextID> :整数类型。上下文ID。范围是1-16。
      • <connectID> :整数类型。套接字服务索引。范围是0-11。
      • <SERVICE_TYPE>:字符串类型。套接字服务类型。
        • “ TCP ” :作为客户端启动TCP连接
        • “ UDP ”:作为客户端启动UDP连接
        • “TCP LISTENER” :启动TCP服务器以侦听TCP连接
        • “UDP SERVICE” :启动UDP服务
      • <IP_address>:字符串类型。
        • 如果<service_type>是TCP或UDP ,则表示远程服务器的IP地址,例如 “220.180.239.212”。
        • 如果<service_type>是TCP LISTENER或UDP SERVICE 地址,请输入“127.0.0.1”。
      • <domain_name>:字符串类型。远程服务器的域名地址。
      • <remote_port> :远程服务器的端口,仅在<service_type>为“TCP”或“UDP”时有效。范围是0-65535。
      • <LOCAL_PORT> :本地端口。范围是0-65535。
        • 如果<service_type>是“TCP LISTENER”或“UDP SERVICE”,则此参数必须指定。
        • 如果<service_type>是“TCP”或“UDP”。如果<local_port>为0,那么本地端口将是自动分配。否则,将按指定分配本地端口。
      • <access_mode> :整数类型。套接字服务的数据访问模式。
        • 0: 缓冲区访问模式
        • 1:直推模式
        • 2:透明访问模式
      • <err>:整数类型。操作的错误代码。请参阅第4章。
    AT+QIOPEN=1,0,\"TCP\",\"180.97.81.180\",53540,0,1
    
    OK
    
    +QIOPEN: 0,0
    

    Buffer模式,Push模式,透传模式。通过参数<access_mode>进行配置。





    2.9 AT + QISEND

    如果指定套接字服务的<access_mode>是缓冲区访问模式或直接推送模式,则数据可以是通过AT + QISEND发送。如果数据成功发送到模块,将返回“ SEND OK ” 。否则它将返回“ SEND FAIL ” 或“ ERROR ” 。“ SEND FAIL ” 表示发送缓冲区已满客户可以尝试重新发送数据。“ERROR”表示在发送过程中遇到错误 数据。客户应该延迟一段时间来发送数据。最大数据长度为1460字。“SEND OK”并不意味着数据已成功发送到服务器。客户可以查询数据是否通过AT + QISEND = <connectID>,0命令到达服务器。透传模式下不需要AT指令发送数据


    三、TCP/IP AT命令拨号流程

    四、移植文件

    4.1 board_ec200s.c

    /*********************************************************************
     * INCLUDES
     */
    #include "stdlib.h"
    #include "string.h"
    #include "stm32f10x.h"
    #include "FreeRTOS.h"
    #include "task.h" 
    
    #include "board_usart.h" 
    #include "board_ec200s.h" 
    
    uint8_t sendCmd(char *pCmd, char *pRes, uint32_t timeOut, uint8_t sendNum);
    void clearBuffer(void);
    void reset(void);
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */  
    uint8_t g_usart2RecvFinish = 0;                                                 // 串口2接收标志串口接收完成标志
    char g_ec200sBuf[1024] = {0};                                                   // 接收缓存
    uint32_t g_ec200sCnt = 0;                                                       // 接收计数                                   
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    /**
     @brief 初始化
     @param 无
     @return 无
    */
    void EC200S_Init(void)
    {       
        printf("EC200S_Init\r\n");
        uint8_t step = 0;
        switch(step)
        {
            case 0:
                if(sendCmd("AT\r\n","OK", 10, 5))                                   // 测试AT指令功能是否正常
                {
                    step++;
                }
                else
                {
                    printf("Err:AT\r\n");
                    reset();
                    break;
                } 
            case 1:
                if(sendCmd("AT+CPIN?\r\n","+CPIN: READY", 20, 2))                   // 查询SIM卡是否正常,返回ready则表示SIM卡正常
                {
                    step++;
                }
                else
                {
                    printf("Err:AT+CPIN?\r\n");                                     // 20秒内,无法识别SIM状态,重启模块
                    reset();
                    break;
                }
            case 2:
                if(sendCmd("AT+CREG?\r\n","+CREG: 0,1", 90, 2))                     // 查询模组是否注册上GSM网络
                {
                    step++;                                     
                }
                else
                {
                    printf("Err:AT+CREG?\r\n");                                     // 90秒内,没有注册上CS业务,重启模块 
                    reset();
                    break;
                }
            case 3:
                if(sendCmd("AT+CGREG?\r\n","+CGREG: 0,1", 60, 2))                   // 查询模组是否注册上GPRS网络
                {
                    step++;                                                 
                }
                else
                {
                    printf("Err:AT+CGREG?\r\n");                                    // 60秒内,没有注册上PS业务
                    reset();        
                    break;
                }
            case 4:
                if(sendCmd("AT+QICSGP=1,1,\"CMNET\",\"\",\"\",1\r\n", "OK", 40, 3)) // 查询模组是否注册上GPRS网络
                {
                    EC200S_NetConfig();                          
                }
                else
                {
                    printf("Err:AT+QICSGP=1,1\r\n");                                // 如果3次都没停止成功或超过40秒没有回应,则重启模块
                    reset();
                    break;
                }
        }
    }
    
    /**
     @brief 网络配置
     @param 无
     @return 无
    */
    void EC200S_GpioConfig(void)
    {
        GPIO_InitTypeDef gpioInitStructure;     
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                       // 使能GPIO
        gpioInitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_1;                         // 选择要初始化的GPIOB引脚PB1,PB8
        gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                             // 设置引脚工作模式为通用推挽输出      
        gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz;                            // 设置引脚输出最大速率为50MHz
        GPIO_Init(GPIOB, &gpioInitStructure);       
    }
    
    /**
     @brief 网络配置
     @param 无
     @return 无
    */
    void EC200S_NetConfig(void)
    {      
        if(sendCmd("AT+QIDEACT=1\r\n", "OK", 40, 1))                                // 在激活GPRS场景之前先关闭GPRS场景,确保连接正确
        {
            if(sendCmd("AT+QIACT=1\r\n", "OK", 40, 1))                              // 激活移动场景
            {
                EC200S_Connect();
            } 
            else
            {
                printf("Err:AT+QIACT=1\r\n");                                       // 重启模块
                reset();
            }
        }      
        else
        {
            printf("Err:AT+QIDEACT=1\r\n");                                         // 重启模块
            reset();
        }     
    }
    
    /**
     @brief 连接TCP服务器
     @param 无
     @return 无
    */
    void EC200S_Connect(void)
    {
        if(sendCmd("AT+QIOPEN=1,0,\"TCP\",\"180.97.81.180\",53540,0,1\r\n", "+QIOPEN:", 150, 5))    
        {
            printf("Connect Success\r\n");
        }      
        else
        {
            printf("Err:AT+QIOPEN=1,0\r\n");
        }       
    }
    
    /**
     @brief 发送数据到TCP服务器
     @param pString -[in] 发送数据
     @return 无
    */
    void EC200S_Send(char *pString)
    {
        if(sendCmd("AT+QISEND=0\r\n", ">", 5, 24)) 
        {
            char sendBuf[256] = {0};
            sprintf(sendBuf, "%s\x1A", pString);
            sendCmd(sendBuf, "SEND OK", 50, 1);
        }
        else
        {
            printf("Err:AT+QISEND=0\r\n");                                          // 重启连接
            if(sendCmd("AT+QICLOSE\r\n", "OK", 40, 2))
            {
                EC200S_Connect();
            }
        }
    }
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    /**
     @brief 发送AT命令
     @param pCmd -[in] 命令字符串
     @param pRes -[in] 需要检测的返回命令字符串
     @param timeOut -[in] 等待时间
     @param sendNum -[in] 命令发送次数
     @return 1 - 成功;0 - 失败
    */
    uint8_t sendCmd(char *pCmd, char *pRes, uint32_t timeOut, uint8_t sendNum)
    {
        uint8_t i = 0;
        uint32_t time;
        clearBuffer();                                                              // 清空缓存 
        for(i = 0; i < sendNum; i++)
        {
            time = timeOut;
            USART_SendString(USART2, pCmd);
            while(time--)
            {
                if(g_usart2RecvFinish)                                              // 如果串口接收完成
                {
                    if(strstr((const char *)g_ec200sBuf, pRes) != NULL)             // 如果检索到关键词
                    {
                        printf("%s", g_ec200sBuf);
                        return 1;
                    }
                }   
                vTaskDelay(1000);                                                   // 等待1秒
            }
            clearBuffer();
        }
        return 0;
    }
    
    /**
     @brief 清空缓存
     @param 无
     @return 无
    */
    void clearBuffer(void)
    {
        memset(g_ec200sBuf, 0, sizeof(g_ec200sBuf));
        g_ec200sCnt = 0;
    }
    
    /**
     @brief 重启模块
     @param 无
     @return 无
    */
    void reset(void)
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_8);
        vTaskDelay(2000);
        GPIO_SetBits(GPIOB, GPIO_Pin_8);
    }
    
    /****************************************************END OF FILE****************************************************/
    

    4.2 board_ec200s.h

    #ifndef _BOARD_EC200S_H_
    #define _BOARD_EC200S_H_
    
    /*********************************************************************
     * INCLUDES
     */
    #include "stm32f10x.h"
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */  
    extern uint8_t g_usart2RecvFinish;      // 串口2接收标志串口接收完成标志
    extern char g_ec200sBuf[1024];          // 接收缓存
    extern uint32_t g_ec200sCnt;            // 接收计数
    
    /*********************************************************************
     * API FUNCTIONS
     */
    void EC200S_Init(void);
    void EC200S_GpioConfig(void);
    void EC200S_NetConfig(void);
    void EC200S_Connect(void);
    void EC200S_Send(char *pString);
    
    #endif /* _BOARD_EC200S_H_ */
    

    五、使用方法

    vTaskDelay(3000);
    EC200S_Init();
    while(1)                                                            // 任务都是一个无限循环,不能返回
    {
        EC200S_Send("TES");
        vTaskDelay(10000);  
    }
    

    • 由 Leung 写于 2020 年 9 月 28 日

    • 参考:移远 EC200S 模组(4G Cat.1 通信模组)AT指令测试 TCP/UDP 通信过程
        移远EC20 R2.0 AT指令拨号流程
        Quectel EC20 R2.1 AT指令集(TCP/部分)

    相关文章

      网友评论

        本文标题:STM32F103学习笔记(6)——4G模块EC200S使用

        本文链接:https://www.haomeiwen.com/subject/tfgduktx.html