STM32F103学习笔记(9)

您所在的位置:网站首页 NB-IoT通信频段设置 STM32F103学习笔记(9)

STM32F103学习笔记(9)

2024-07-13 18:52| 来源: 网络整理| 查看: 265

一、简介

BC26 是一款高性能、低功耗、多频段 LTE Cat NB1/Cat NB2*无线通信模块。其尺寸仅为 17.7 mm × 15.8 mm × 2.0 mm,能最大限度地满足终端设备对小尺寸模块产品的需求,同时有效帮助客户减小产品尺寸并优化产品成本.BC26 在封装设计上兼容移远通信 GSM/GPRS 系列 M26 模块以及 NB-IoT 系列 BC28/BC25/BC260Y-CN 模块,方便客户快速、灵活的进行产品设计和升级。BC26 提供丰富的外部接口和协议栈,同时可支持中国移动 OneNET/Andlink、中国电信 IoT/ AEP以及阿里云IoT等物联网云平台,为客户的应用提供极大的便利。

BC26 采用更易于焊接的 LCC 封装,可通过标准 SMT 设备实现模块的快速生产,为客户提供可靠的连接方式,并满足复杂环境下的应用需求。

凭借紧凑的尺寸、超低功耗和超宽工作温度范围,BC26 成为 IoT 应用领域的理想选择,常被用于烟感、无线抄表、共享单车、智能停车、智慧城市、安防、资产追踪、智能家电、可穿戴设备、农业和环境监测以及其它诸多行业,以提供完善的短信和数据传输服务。

BC26资料:链接:https://pan.baidu.com/s/1n8rcRCna8wnMPFwikY3l0g?pwd=vgcm 提取码:vgcm

二、AT指令

发送数据时务必勾选:“加回车换行符”。否则模块不会响应。在本文中,仅显示响应,省略回车换行符。

2.1 AT

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

AT OK 2.2 AT+CIMI

该命令用于查询(U)SIM 卡的国际移动用户识别码(IMSI,无双引号的字符串)。IMSI 允许 TE 识别连 接到 MT 的 USIM。

AT+CIMI 460001357924680 OK 2.3 AT+CGATT=1

设置命令用于将 MT 附着于 PS 域。命令完成后,MT 保持在 V.250 命令状态。如果 MT 已经处于请求状态,则忽略该命令,并且仍将响应 OK。如果 MT 无法实现请求状态,将响应 ERROR 或+CME ERROR。

AT+CGATT=1 OK 2.4 AT+CGATT?

查询命令返回当前 PS 域服务状态。

AT+CGATT=? +CGATT: 如:+CGATT: 1 OK

整型。PDP 上下文激活状态。

0 去附着1 附着 2.5 AT+CEREG? AT+CEREG? +CEREG: , 如:+CEREG: 0,1 如:+CEREG: 1,1 OK

整型。禁止或允许上报网络注册状态等信息。

0 禁止上报网络注册状态 URC1 允许上报网络注册状态 URC +CEREG: 2 允许上报网络注册状态和位置信息 URC +CEREG: [,[],[],[]]3 允许上报网络注册状态、位置信息和 EMM 原因值 URC +CEREG: [,[],[],[][,,]]4 对于请求 PSM 的 UE,允许上报网络注册状态和位置信息 URC +CEREG: [,[],[],[][,[,[],[]]]]5 对于请求 PSM 的 UE,允许上报网络注册状态、位置信息和 EMM 原因值 URC +CEREG: [,[],[],[][,[],[][,[, []]]]

整型。EPS 注册状态。

0 未注册,MT 当前未搜索网络1 已注册,归属网络2 未注册,但 MT 当前正在尝试附着或搜索网络以进行注册3 注册被拒绝4 未知(例如:超出 E-UTRAN 覆盖范围)5 已注册,漫游状态 2.6 AT+QIPADDR

查询 UE 的 IP 地址

AT+QIPADDR +QIPADDR: fe80:0:0:0:3c:ffb8:f4c9:1207 +QIPADDR: 2001:14bb:170:4c91:3c: ffh8:f4c9:1207 +QIPADDR: 178.55.211.180 +QIPADDR: 127.0.0.1 OK 2.7 AT+QIOPEN

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

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

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

2.8 AT + QISEND

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

三、TCP应用时序图

四、复位模块

通过拉低 RESET 引脚至少 50ms 可以使模块复位。

五、移植文件 5.1 board_bc26.c /********************************************************************* * INCLUDES */ #include "stdlib.h" #include "string.h" #include "stm32f10x.h" #include "FreeRTOS.h" #include "task.h" #include "board_bc26.h" static uint8_t sendCmd(char *pCmd, char *pRes, char *pRes2, uint32_t timeOut, uint8_t sendNum); static void clearBuffer(void); static void reset(void); /********************************************************************* * GLOBAL VARIABLES */ uint8_t g_usart2RecvFinish = 0; // 串口2接收标志串口接收完成标志 char g_bc26Buf[1024] = {0}; // 接收缓存 volatile uint32_t g_bc26Cnt; // 接收计数 /********************************************************************* * PUBLIC FUNCTIONS */ /** @brief 初始化 @param 无 @return 1 - 成功;0 - 失败 */ uint8_t BC26_Init(void) { printf("BC26_Init\r\n"); uint8_t result = 0; uint8_t step = 0; switch(step) { case 0: if(sendCmd("AT\r\n", "OK", NULL, 10, 6)) // 测试AT指令功能是否正常 { step++; } else { printf("Err:AT\r\n"); reset(); break; } case 1: if(sendCmd("AT+CIMI\r\n", "OK", NULL, 20, 1)) // 查询SIM卡是否正常,返回OK则表示SIM卡正常 { step++; } else { printf("Err:AT+CIMI\r\n"); // 20秒内,无法识别SIM状态,重启模块 reset(); break; } case 2: if(sendCmd("AT+CGATT=1\r\n", "OK", "+IP:", 60, 1)) // 激活PDP场景 { step++; } else { printf("Err:AT+CGATT=1\r\n"); step++; } case 3: if(sendCmd("AT+CEREG?\r\n", "+CEREG: 0,1", "+CEREG: 1,1", 60, 3)) // 查询模组是否注册上EPS网络 { step++; } else { printf("Err:AT+CEREG?\r\n"); step++; } case 4: if(sendCmd("AT+CGATT?\r\n", "+CGATT: 1", NULL, 85, 3)) // 查询当前PS域服务状态 { step++; } else { printf("Err:AT+CGATT?\r\n"); // 如果3次都没停止成功或超过85秒没有回应,则重启模块 reset(); break; } case 5: if(sendCmd("AT+QIPADDR\r\n", "+QIPADDR:", NULL, 60, 3)) // 查询本机IP地址 { BC26_Connect(); result = 1; } else { printf("Err:AT+QIPADDR\r\n"); // 如果3次都没停止成功或超过60秒没有回应,则重启模块 reset(); break; } } return result; } /** @brief 复位引脚配置 @param 无 @return 无 */ void BC26_GpioConfig(void) { GPIO_InitTypeDef gpioInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIO gpioInitStructure.GPIO_Pin = GPIO_Pin_8; // 选择要初始化的GPIOB引脚PB8 gpioInitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置引脚工作模式为通用推挽输出 gpioInitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置引脚输出最大速率为50MHz GPIO_Init(GPIOB, &gpioInitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_8); } /** @brief 连接TCP服务器 @param 无 @return 无 */ void BC26_Connect(void) { if(sendCmd("AT+QICLOSE=0\r\n", "OK", NULL, 20, 1)) // 关闭TCP连接 { 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"); reset(); // 没有响应重启模块 } } } /** @brief 发送数据到TCP服务器 @param pString -[in] 发送数据 @return 无 */ void BC26_Send(char *pString) { if(sendCmd("AT+QISEND=0\r\n", ">", NULL, 30, 2)) // 等待60秒,没有响应重启模块 { vTaskDelay(500); // 等待500ms char sendBuf[1024] = {0}; sprintf(sendBuf, "%s\r\n\x1A", pString); if(sendCmd(sendBuf, "SEND OK", "OK", 30, 2)) { if(sendCmd("AT+QISEND=0,0\r\n", "+QISEND:", NULL, 5, 24)) // 2分钟后(每5秒查询一次,共24次) { /* 发送数据成功,对方收到数据 */ } else { printf("Err:AT+QISEND=0\r\n"); if(sendCmd("AT+QICLOSE=0\r\n", "OK", NULL, 20, 1)) // TCP连接出现异常,关闭TCP连接 { printf("AT+QICLOSE\r\n"); BC26_Connect(); } } } else { BC26_Reset(); // 等待60秒,没有响应重启模块 } } else { BC26_Reset(); // 等待60秒,没有响应重启模块 } } /** @brief 从TCP服务器接收数据 @param pRecvDataBuf -[out] 接收数据 @return 接收数据长度 */ uint32_t EC200S_Receive(char *pRecvDataBuf) { uint32_t recvDataLen = 0; if(g_isUsart2RecvFinish) // 如果串口接收完成 { if(strstr((const char *)g_bc26Buf, "+QIURC: \"recv\",0,") != NULL) // 如果检索到关键词 { memcpy(pRecvDataBuf, g_bc26Buf, g_bc26Cnt); recvDataLen = g_bc26Cnt; } else if(strstr((const char *)g_bc26Buf, "+QIURC: \"closed\",0,") != NULL) { BC26_Reset(); } clearBuffer(); } return recvDataLen; } /** @brief 重启模块 @param 无 @return 无 */ void BC26_Reset(void) { reset(); } /********************************************************************* * LOCAL FUNCTIONS */ /** @brief 发送AT命令 @param pCmd -[in] 命令字符串 @param pRes -[in] 需要检测的返回命令字符串 @param pRes2 -[in] 需要检测的返回命令字符串 @param timeOut -[in] 等待时间 @param sendNum -[in] 命令发送次数 @return 1 - 成功;0 - 失败 */ static uint8_t sendCmd(char *pCmd, char *pRes, char *pRes2, uint32_t timeOut, uint8_t sendNum) { uint8_t i = 0; uint32_t time; clearBuffer(); // 清空缓存 for(i = 0; i = sizeof(g_bc26Buf)) { g_bc26Cnt = 0; // 防止串口被刷爆 } g_bc26sBuf[g_bc26Cnt++] = USART2->DR; USART_ClearFlag(USART2, USART_FLAG_RXNE); } }

• 由 Leung 写于 2022 年 8 月 26 日

• 参考:移远BC35-G模组(NB-IoT 通信模组)AT指令测试 UDP 通信过程     NB-IOT(BC26)相关AT指令——UDP/TCP传输     NB260软件设计手册



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3