一、简介

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。

ATOK

2.2 AT + CPIN?

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

AT+CPIN?+CPIN: READYOK

2.3 AT + CREG?

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

AT+CREG?+CREG: 0,1OK

2.4 AT + CGREG?

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

AT+CGREG?+CGREG: 0,1OK

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

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

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

2.6 AT + QIDEACT=1

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

AT+QIDEACT=1OK

2.7 AT + QIACT=1

激活移动场景

AT+QIACT=1OK

2.8 AT+QIOPEN

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

  • AT+QIOPEN=?:查询命令参数。
  • AT+QIOPEN=,,<service_type>,<IP_address>/<domain_name>,<remote_port>[,<local_po CONNECTrt>[,<access_mode>]] :打开 Socket 服务。
    • :整数类型。上下文ID。范围是1-16。
    • :整数类型。套接字服务索引。范围是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:透明访问模式
    • :整数类型。操作的错误代码。请参阅第4章。
AT+QIOPEN=1,0,\"TCP\",\"180.97.81.180\",53540,0,1OK+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 = ,0命令到达服务器。透传模式下不需要AT指令发送数据

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

四、程序大致流程

主要开了三个定时器
sendCmdTimer:发送命令定时器
sendDataTimer:发送数据定时器(用于建立TCP连接后发送数据)
recvCmdTimer:统一接收命令定时器

五、移植文件

5.1 board_ec200s.c

/********************************************************************** INCLUDES*/
#include "stdlib.h"
#include "string.h"
#include "app_timer.h"
#include "nrf_log.h"#include "board_uart.h"
#include "board_ec200s.h"
#include "common.h"static void clearBuffer(void);
static void reset(void);
static void timer_sendCmdCallback(void *arg);
static void timer_sendDataCallback(void *arg);
static void timer_recvCmdCallback(void *arg);
static void timer_resetCallback(void *arg);
static void sendData(char *pCmd);/********************************************************************** GLOBAL VARIABLES*/
char g_ec200sBuf[MAX_RECV_BUF_SIZE] = {0};                                      // 接收缓存
uint32_t g_ec200sCnt = 0;                                                       // 接收计数
uint8_t g_isEc200sInit = 0;   /********************************************************************** LOCAL VARIABLES*/
APP_TIMER_DEF(s_sendCmdTimer);                                                  // 发送命令的定时器
APP_TIMER_DEF(s_sendDataTimer);                                                 // 发送数据的定时器
APP_TIMER_DEF(s_recvCmdTimer);                                                  // 接收命令的定时器
APP_TIMER_DEF(s_resetTimer);                                                    // 重启的定时器
static uint8_t s_sendCmdResult = 0;                                             // 发送命令结果
static uint32_t s_waitCmdTime = 0;                                              // 等待命令时间
static uint8_t s_waitCmdNum = 0;                                                // 等待命令次数
static bool s_sendCmdFlag = false;
static uint8_t s_sendCmdStep = 0;
static char s_waitCmdBuf[30] = {0};                                             // 等待比较命令
static bool s_sendDataFlag = false;
static uint8_t s_sendDataStep = 0;
static char s_sendDataBuf[MAX_RECV_BUF_SIZE] = {0};
static char s_recvDataBuf[MAX_RECV_BUF_SIZE] = {0};
static uint32_t s_recvDataLen = 0;
static uint8_t s_isReset = 0;/********************************************************************** PUBLIC FUNCTIONS*/
/**@brief 初始化@param 无@return 1 - 成功;0 - 失败
*/
uint8_t EC200S_Init(void)
{       if((s_sendCmdResult == 0) && (s_isReset == 0)){NRF_LOG_INFO("EC200S_Init");s_sendCmdStep = 0;  StartSendCmdTimer();StartRecvCmdTimer();s_sendCmdResult = 2;}if(s_sendCmdResult == 1){s_sendCmdResult = 0;return 1;}return 0;
}/**@brief 引脚配置@param 无@return 无
*/
void EC200S_GpioConfig(void)
{nrf_gpio_cfg_output(EC200S_GPIO_PIN);nrf_gpio_pin_write(EC200S_GPIO_PIN, 1);
}/**@brief 发送数据到TCP服务器@param pString -[in] 发送数据@return 无
*/
void EC200S_Send(char *pString)
{if(g_isEc200sInit == 1){   sprintf(s_sendDataBuf, "%s\x1A", pString);s_sendDataStep = 0;NRF_LOG_INFO("%s", pString); StartSendDataTimer();StartRecvCmdTimer();}
}/**@brief 从TCP服务器接收数据@param pRecvDataBuf -[out] 接收数据@return 接收数据长度
*/
uint32_t EC200S_Receive(char *pRecvDataBuf)
{uint32_t recvDataLen = 0;if(s_recvDataLen > 0){memcpy(pRecvDataBuf, s_recvDataBuf, s_recvDataLen);recvDataLen = s_recvDataLen;memset(s_recvDataBuf, 0, s_recvDataLen);s_recvDataLen = 0;}return recvDataLen;
}/**@brief 创建发送命令的定时器@param 无@return 无
*/
void CreateSendCmdTimer(void)
{app_timer_create(&s_sendCmdTimer, APP_TIMER_MODE_REPEATED, timer_sendCmdCallback);
}/**@brief 开启发送命令的定时器@param 无@return 无
*/
void StartSendCmdTimer(void)
{       app_timer_start(s_sendCmdTimer, SEND_CMD_PERIOD, NULL);
}/**@brief 关闭发送命令的定时器@param 无@return 无
*/
void StopSendCmdTimer(void)
{   app_timer_stop(s_sendCmdTimer);
}/**@brief 创建发送数据的定时器@param 无@return 无
*/
void CreateSendDataTimer(void)
{app_timer_create(&s_sendDataTimer, APP_TIMER_MODE_REPEATED, timer_sendDataCallback);
}/**@brief 开启发送数据的定时器@param 无@return 无
*/
void StartSendDataTimer(void)
{       app_timer_start(s_sendDataTimer, SEND_DATA_PERIOD, NULL);
}/**@brief 关闭发送数据的定时器@param 无@return 无
*/
void StopSendDataTimer(void)
{   app_timer_stop(s_sendDataTimer);
}/**@brief 创建接收命令的定时器@param 无@return 无
*/
void CreateRecvCmdTimer(void)
{app_timer_create(&s_recvCmdTimer, APP_TIMER_MODE_REPEATED, timer_recvCmdCallback);
}/**@brief 开启接收命令的定时器@param 无@return 无
*/
void StartRecvCmdTimer(void)
{       app_timer_start(s_recvCmdTimer, RECV_CMD_PERIOD, NULL);
}/**@brief 关闭接收命令的定时器@param 无@return 无
*/
void StopRecvCmdTimer(void)
{   app_timer_stop(s_recvCmdTimer);
}/**@brief 创建重启的定时器@param 无@return 无
*/
void CreateResetTimer(void)
{app_timer_create(&s_resetTimer, APP_TIMER_MODE_SINGLE_SHOT, timer_resetCallback);
}/**@brief 处理接收命令@param 无@return 1 - 成功;0 - 失败
*/
uint8_t ReceiveCommandHandler(void)
{  if(strstr((const char *)g_ec200sBuf, "SEND OK") != NULL)                    // 如果检索到关键词SEND OK{s_sendDataStep++;s_sendDataFlag = false;clearBuffer(); return 1;}else if(strstr((const char *)g_ec200sBuf, "+QISEND:") != NULL)              // 如果检索到关键词+QISEND:{s_sendDataStep++;s_sendDataFlag = false;clearBuffer();return 1;        }else if(strstr((const char *)g_ec200sBuf, "+CPIN: READY") != NULL)          // 如果检索到关键词+CPIN: READY{s_sendCmdStep++;s_sendCmdFlag = false;clearBuffer(); return 1;}else if(strstr((const char *)g_ec200sBuf, "+CREG: 0,1") != NULL)            // 如果检索到关键词+CREG: 0,1{s_sendCmdStep++;s_sendCmdFlag = false;clearBuffer(); return 1;}else if(strstr((const char *)g_ec200sBuf, "+CGREG: 0,1") != NULL)           // 如果检索到关键词+CGREG: 0,1{s_sendCmdStep++;s_sendCmdFlag = false;clearBuffer(); return 1;}else if(strstr((const char *)g_ec200sBuf, "OK") != NULL)                    // 如果检索到关键词OK{s_sendDataStep++;s_sendDataFlag = false;s_sendCmdStep++;s_sendCmdFlag = false;clearBuffer();return 1;}else if(strstr((const char *)g_ec200sBuf, "+QIOPEN:") != NULL)              // 如果检索到关键词+QIOPEN:{NRF_LOG_INFO("Connect Success");s_sendCmdResult = 1;s_sendCmdStep++;s_sendCmdFlag = false;clearBuffer(); StopSendCmdTimer();StopRecvCmdTimer();return 1;}   else if(strstr((const char *)g_ec200sBuf, "ERROR") != NULL)                 // 如果检索到关键词ERROR{NRF_LOG_INFO("connect error\n");reset();clearBuffer();return 1;}else if(strstr((const char *)g_ec200sBuf, "POWERED DOWN") != NULL)          // 如果检索到关键词POWERED DOWN{NRF_LOG_INFO("power down\n");}return 0;
}/**@brief 处理接收数据@param 无@return 1 - 成功;0 - 失败
*/
uint8_t ReceiveDataHandler(void)
{static bool s_isRecvData;if(strstr((const char *)g_ec200sBuf, "+QIURC: \"recv\",0,") != NULL)        // 如果检索到关键词+QIURC: \"recv\",0,{s_isRecvData = true;clearBuffer();return 1;}if(s_isRecvData){memcpy(s_recvDataBuf, g_ec200sBuf, g_ec200sCnt);s_recvDataLen = g_ec200sCnt;clearBuffer();s_isRecvData = false;return 1;}return 0;
}/********************************************************************** LOCAL FUNCTIONS*/
/**@brief 清空缓存@param 无@return 无
*/
static void clearBuffer(void)
{memset(g_ec200sBuf, 0, sizeof(g_ec200sBuf));memset(s_waitCmdBuf, 0, sizeof(s_waitCmdBuf));g_ec200sCnt = 0;
}/**@brief 重启模块@param 无@return 无
*/
static void reset(void)
{NRF_LOG_INFO("reset\n");s_isReset = 1;g_isEc200sInit = 0;s_sendCmdResult = 0;s_sendCmdFlag = false;s_sendDataFlag = false;StopSendCmdTimer();StopSendDataTimer();StopRecvCmdTimer();nrf_gpio_pin_write(EC200S_GPIO_PIN, 0);                                     // 拉低app_timer_start(s_resetTimer, RESET_PERIOD, NULL);                          // 等待2s,再拉高
}/**@brief 发送命令定时器的回调函数@param 无@return 无
*/
static void timer_sendCmdCallback(void *arg)
{if(s_sendCmdStep == 0 && s_sendCmdFlag == false)                            // 测试AT指令功能是否正常{sendData("AT\r\n");  s_waitCmdTime = 10 * 10;                                                // 10秒s_sendCmdFlag = true;        }else if(s_sendCmdStep == 1 && s_sendCmdFlag == false)                       // 查询SIM卡是否正常,返回ready则表示SIM卡正常{sendData("AT+CPIN?\r\n");s_waitCmdTime = 20 * 10;                                                // 20秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 3 && s_sendCmdFlag == false)                       // 查询模组是否注册上GSM网络{sendData("AT+CREG?\r\n");s_waitCmdTime = 90 * 10;                                                // 90秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 5 && s_sendCmdFlag == false)                       // 查询模组是否注册上GPRS网络{sendData("AT+CGREG?\r\n");s_waitCmdTime = 60 * 10;                                                // 60秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 7 && s_sendCmdFlag == false)                       // 配置PDP场景{sendData("AT+QICSGP=1,1,\"CMNET\",\"\",\"\",1\r\n");s_waitCmdTime = 40 * 10;                                                // 40秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 8 && s_sendCmdFlag == false)                       // 在激活GPRS场景之前先关闭GPRS场景,确保连接正确{sendData("AT+QIDEACT=1\r\n");s_waitCmdTime = 40 * 10;                                                // 40秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 9 && s_sendCmdFlag == false)                       // 在激活GPRS场景之前先关闭GPRS场景,确保连接正确{sendData("AT+QIACT=1\r\n");s_waitCmdTime = 150 * 10;                                               // 150秒s_sendCmdFlag = true;}else if(s_sendCmdStep == 10 && s_sendCmdFlag == false)                      // 连接服务器{                           sendData("AT+QIOPEN=1,0,\"TCP\",\"180.97.81.180\",59889,0,1\r\n");s_waitCmdTime = 150 * 10;                                               // 150秒s_sendCmdFlag = true;}if(s_waitCmdTime == 0)                                                      // 没有响应重启模块 {        reset();                                                        }
}/**@brief 发送数据定时器的回调函数@param 无@return 无
*/
static void timer_sendDataCallback(void *arg)
{if(s_sendDataStep == 0)                                                     // 发送长度可变数据格式{sendData("AT+QISEND=0\r\n");                                            // >会被断包,这里特殊处理s_waitCmdTime = 60 * 10;                                                // 60秒s_sendDataStep++;}else if(s_sendDataStep == 1 && s_sendDataFlag == false)                     // 发送实际数据{sendData(s_sendDataBuf);memset(s_sendDataBuf, 0, MAX_RECV_BUF_SIZE);s_waitCmdTime = 60 * 10;                                                // 60秒s_sendDataFlag = true;}else if(s_sendDataStep == 2 && s_sendDataFlag == false)                     // 查询数据是否达到服务器{sendData("AT+QISEND=0,0\r\n");s_waitCmdTime = 5 * 10;                                                 // 5秒s_waitCmdNum = 23;s_sendDataFlag = true;}else if(s_sendDataStep == 4)                                                // 完成发送{StopSendDataTimer();StopRecvCmdTimer();}if(s_waitCmdTime == 0)                                                      // 等待60秒,没有响应重启模块 {s_waitCmdNum--;if(s_waitCmdNum > 0)                                                    // 2分钟后(每5秒查询一次,共24次),没有响应重启模块 {sendData("AT+QISEND=0,0\r\n");s_waitCmdTime = 5 * 10;s_sendDataStep = 2;s_sendDataFlag = true;return;}reset();                                                        }
}/**@brief 接收命令定时器的回调函数@param 无@return 无
*/
static void timer_recvCmdCallback(void *arg)
{if(s_waitCmdTime == 0){StopRecvCmdTimer();return; }s_waitCmdTime--;
}/**@brief 重启定时器的回调函数@param 无@return 无
*/
static void timer_resetCallback(void *arg)
{nrf_gpio_pin_write(EC200S_GPIO_PIN, 1);s_isReset = 0;
}/**@brief 发送数据@param pCmd -[in] 命令字符串@return 无
*/
static void sendData(char *pCmd)
{  UART_WriteData((uint8_t *)pCmd, strlen(pCmd));
}

5.2 board_ec200s.h

#ifndef _BOARD_EC200S_H_
#define _BOARD_EC200S_H_/********************************************************************** INCLUDES*//********************************************************************** DEFINITIONS*/
#define EC200S_GPIO_PIN             7#define MAX_RECV_BUF_SIZE           256#define SEND_CMD_PERIOD             APP_TIMER_TICKS(98)      // 98ms
#define SEND_DATA_PERIOD            APP_TIMER_TICKS(98)      // 98ms
#define RECV_CMD_PERIOD             APP_TIMER_TICKS(100)     // 100ms
#define RESET_PERIOD                APP_TIMER_TICKS(3000)    // 3s/********************************************************************** GLOBAL VARIABLES*/
extern char g_ec200sBuf[MAX_RECV_BUF_SIZE];     // 接收缓存
extern uint32_t g_ec200sCnt;                    // 接收计数
extern uint8_t g_isEc200sInit;/********************************************************************** API FUNCTIONS*/
uint8_t EC200S_Init(void);
void EC200S_GpioConfig(void);
void EC200S_Send(char *pString);
uint32_t EC200S_Receive(char *pRecvDataBuf);
void CreateSendCmdTimer(void);
void StartSendCmdTimer(void);
void StopSendCmdTimer(void);
void CreateSendDataTimer(void);
void StartSendDataTimer(void);
void StopSendDataTimer(void);
void CreateRecvCmdTimer(void);
void StartRecvCmdTimer(void);
void StopRecvCmdTimer(void);
void CreateResetTimer(void);
uint8_t ReceiveCommandHandler(void);
uint8_t ReceiveDataHandler(void);#endif /* _BOARD_EC200S_H_ */

5.3 board_uart.c

查看 NRF52832学习笔记(12)——UART接口使用

/********************************************************************** INCLUDES*/
#include "nrf_uart.h"
#include "app_uart.h"#include "board_ec200s.h"
#include "board_uart.h"
#include "user_uart.h"#include "nrf_log.h"static void uart_handleEvent(app_uart_evt_t *pEvent);/********************************************************************** LOCAL VARIABLES*/
static uint8_t s_uartReadDataBuffer[UART_RX_BUF_SIZE] = {0};
static uint8_t s_index = 0;
static bool s_begin = false;/********************************************************************** PUBLIC FUNCTIONS*/
/**@brief 串口驱动初始化@param 无@return 无
*/
void UART_Init(void)
{uint32_t errCode;app_uart_comm_params_t const commParams ={.rx_pin_no    = BOARD_UART_RX_IO,.tx_pin_no    = BOARD_UART_TX_IO,.rts_pin_no   = BOARD_UART_RTS_IO,.cts_pin_no   = BOARD_UART_CTS_IO,                     .flow_control = APP_UART_FLOW_CONTROL_DISABLED,     // 关掉流控.use_parity   = false,
#if defined (UART_PRESENT).baud_rate    = NRF_UART_BAUDRATE_115200            // 波特率
#else.baud_rate    = NRF_UARTE_BAUDRATE_115200
#endif};APP_UART_FIFO_INIT(&commParams, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE,uart_handleEvent, APP_IRQ_PRIORITY_LOWEST, errCode);APP_ERROR_CHECK(errCode);
}
/**@brief 串口写数据函数@param pData -[in] 写入数据@param dataLen -[in] 写入数据长度@return 无
*/
void UART_WriteData(uint8_t *pData, uint8_t dataLen)
{uint8_t i;for(i = 0; i < dataLen; i++){app_uart_put(pData[i]);}
}/********************************************************************** LOCAL FUNCTIONS*/
/**@brief 串口读取数据处理函数@param pEvent -[in] 串口事件@return 无
*/
static void uart_handleEvent(app_uart_evt_t *pEvent)
{uint8_t dataChar = 0;switch(pEvent->evt_type){// 已接收到UART数据case APP_UART_DATA_READY:{UNUSED_VARIABLE(app_uart_get(&dataChar));// 不是回车符或换行符则开始   if(dataChar != '\n' && dataChar != '\r'){s_begin = true;}if(s_begin){s_uartReadDataBuffer[s_index] = dataChar;s_index++;}// 遇到回车符或换行符结束      if((s_uartReadDataBuffer[s_index - 1] == '\n') ||(s_uartReadDataBuffer[s_index - 1] == '\r') ||(s_index >= MAX_RECV_BUF_SIZE)){//                NRF_LOG_HEXDUMP_INFO(s_uartReadDataBuffer, s_index);  memcpy(g_ec200sBuf, s_uartReadDataBuffer, s_index); // 接收缓存g_ec200sCnt = s_index;                              // 接收计数   if(!ReceiveCommandHandler()){ReceiveDataHandler();}memset(s_uartReadDataBuffer, 0, s_index); s_index = 0;s_begin = false;                }} break;// 接收过程中发生通信错误case APP_UART_COMMUNICATION_ERROR:APP_ERROR_HANDLER(pEvent->data.error_communication);break;// app_uart模块使用的FIFO模块中出现错误case APP_UART_FIFO_ERROR:APP_ERROR_HANDLER(pEvent->data.error_code);break;default:break;}
}/****************************************************END OF FILE****************************************************/

5.4 board_uart.h

#ifndef _BOARD_UART_H_
#define _BOARD_UART_H_/********************************************************************** INCLUDES*//********************************************************************** DEFINITIONS*/
#define UART_TX_BUF_SIZE                256     // UART TX buffer size
#define UART_RX_BUF_SIZE                256     // UART RX buffer size#define BOARD_UART_TX_IO                6       // 发送引脚
#define BOARD_UART_RX_IO                8       // 接收引脚
#define BOARD_UART_CTS_IO               7       // 流量控制发送清除、低有效
#define BOARD_UART_RTS_IO               9       // 流量控制发送请求、低有效/********************************************************************** API FUNCTIONS*/
void UART_Init(void);
void UART_WriteData(uint8_t *pData, uint8_t dataLen);#endif /* _BOARD_UART_H_ */

五、使用方法

#include "board_ec200s.h"
#include "board_uart.h"int main(void)
{log_init();timers_init();EC200S_GpioConfig();                                                        // 4G模块PWK引脚初始化                       UART_Init();                                                                // 串口驱动初始化power_management_init();ble_stack_init();                                                           // 协议栈初始化gap_params_init();gatt_init();                                                                services_init();                                                            // 服务初始化advertising_init();                                                         // 广播初始化conn_params_init();                                                         // 连接参数初始化advertising_start();                                                        // 开启广播application_timers_start();                                                 // 定时器应用开启// Enter main loop.for(;;){idle_state_handle();}
}

创建一个定时器每200毫秒进入一次回调函数

/**@brief 检查网络定时器的回调函数@param 无@return 无
*/
static void timer_checkNetworkCallback(void *arg)
{UNUSED_PARAMETER(arg);if(g_isEc200sInit == 0){g_isEc200sInit = EC200S_Init();                                 // 初始化4G模块if(g_isEc200sInit == 1){EC200S_Send("hello");     }}else if(g_isEc200sInit == 1){char recvDataBuf[256] = {0};int recvDataLen = EC200S_Receive(recvDataBuf);                  // 接收服务器数据if(recvDataLen > 0){// 进入处理}}
}

• 由 Leung 写于 2020 年 12 月 4 日

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

NRF52832学习笔记(35)——4G模块EC200S使用相关推荐

  1. nrf52832 学习笔记(七)蓝牙协议层级理解

    nrf52832 学习笔记(七)蓝牙协议层级理解 本文主要由一下几篇文档摘录汇总而成 ,如有错误欢迎斧正 da14531 蓝牙协议文档 深入浅出低功耗蓝牙(BLE)协议栈 低功耗蓝牙ATT/GATT/ ...

  2. NRF52832学习笔记(40)——RFID RC522使用

    一.简介 MF RC522 是应用于 13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员.是 NXP 公司针对"三表"应用推出的一款低电压.低成本.体积小的非接触式读写 ...

  3. 好程序员web前端分享Nodejs学习笔记之Stream模块

    好程序员web前端分享Nodejs学习笔记之Stream模块 一,开篇分析 流是一个抽象接口,被 Node 中的很多对象所实现.比如对一个 HTTP 服务器的请求是一个流,stdout 也是一个流.流 ...

  4. node.js学习笔记5——核心模块1

    node.js学习笔记5--核心模块1 Node.js核心模块主要内容包括:(1)全局对象 (2)常用工具 (3)事件机制 (4)文件系统访问 (5)HTTP服务器与客户端 一: 全局对象 Node. ...

  5. nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新

    nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新 主机连接 nrf52832 SDK中主机连接从机需要使用 sd_ble_gap_connect(ble_gap_addr_t const ...

  6. nrf52832 学习笔记(三)蓝牙从机广播

    nrf52832 学习笔记(三)蓝牙从机广播 蓝牙从机要想被主机连接,首先需要发送广播信息,周围主机通过扫描广播信号,根据从机的广播信息,判断是否连接. 蓝牙协议栈初始化 不管是主机还是从机,要想使用 ...

  7. nrf52832 学习笔记(六)配对和绑定

    nrf52832 学习笔记(六)配对和绑定 配对绑定推荐博客低功耗蓝牙配对绑定解读和实践 蓝牙在配对之前都是明文通信的,也就是说主从机之间传输的数据包可以被第三方抓取分析逆向,而且如果没有配对,谁都可 ...

  8. python学习笔记4(模块

    python学习笔记4(模块) 一.模块 1.1 import语句 1.2 __name__属性 1.3 dir()函数 1.4 包 2.1 导入特定模块: 二.输入与输出 2.1 format使用 ...

  9. STM32F407学习笔记——MG90S舵机模块(基本控制)

    STM32F407学习笔记--MG90S舵机模块(基本控制) 一.基本原理: 通过改变PWM占空比来实现舵机进行不同角度转动,下面给出旋转角度与脉冲时间及对应占空比的关系(时基脉冲=20ms). 旋转 ...

最新文章

  1. R卡方独立性检验(Chi-Square Test of Independence)
  2. 理论经典:TCP协议的3次握手与4次挥手过程详解
  3. 转转服务器无响应,【转】服务器无响应(或者本地MySQL服务器的套接字没有正确配置)的问题...
  4. JAVA之JVM垃圾回收(GC)机制详解
  5. 学习java应该如何理解反射?
  6. VTK:Utilities之ZBuffer
  7. [snmp++]读取cisco路由交换机信息[一] - 环境搭建
  8. STM32F7xx —— 输入
  9. Exchange Server 2013多域名证书申请
  10. 事务隔离级别和传播行为_.spring的事务有几种方式?spring事务的隔离级别和传播行为是什么?...
  11. 【Spark】Spark是什么
  12. Vue : Expected the Promise rejection reason to be an Error
  13. 去阿里面试,被一道 Spring 面试题难倒了
  14. 重新复习数据结构-------ArrayList
  15. NISP一级2023年最新题库
  16. 风一更,雪一更,聒碎乡心梦不成,故园无此声。
  17. 《人机交互技术》 第五章 界面设计
  18. 支持向量机_4:Outliers
  19. 邮件客户端如何配置阿里云企业邮箱
  20. Linux系统轻量级监控工具Linux dash的安装方法

热门文章

  1. 一张网络拓扑图的简单分析
  2. [noip模拟]种花快速幂+结论
  3. 倍福TwinCAT(贝福Beckhoff)基础教程 松下驱动器如何执行绝对值清零
  4. WPF特效-鱼游动动画
  5. 大众集团未来五年「砸」1800亿欧元,智能电动再「加码」
  6. ps-增加光影效果质感
  7. 海信ULED超高清电视全网首发
  8. 主题黑板.html,开学主题黑板报内容
  9. 空间自回归模型-OLS、SLM、SEM理解
  10. python100天从新手到大师 pdf_GitHub - DaiJiabin/Python-100-Days: Python - 100天从新手到大师...