一、引言: NB-IoT技术与应用场景

NB-IoT( Narrow Band Internet of Things )作为低功耗广域网( LPWAN )的核心技术,以其广覆   盖、低功耗、大连接、低成本的特性,广泛应用于智能表计、环境监测、智能农业、资产追踪等场景。  本文基于STM32F103C8T6单片机与移远BC26 NB-IoT模块,通过HAL库实现设备与阿里云IoT平台的 通信,从硬件连接、软件配置到代码实现,全程图文并茂,助力开发者快速上手NB-IoT开发。

二、硬件准备: 模块选型与电路连接

2.1 核心硬件清单

设备名称

型号/规格

作用

 

单片机

STM32F103C8T6(最小系统 板)

主控单元,控制传感器与通信 模块

NB-IoT模块

移远BC26(含天线、SIM卡)

实现NB网络接入与数据传输

电源模块

5V/2A直流电源

为BC26和STM32供电

传感器(可选)

DHT11温湿度传感器

采集环境数据(示例用)

 

辅助工具

USB转TTL模块、杜邦线、面包 板

 

调试与接线

2.2 硬件连接详解

BC26模块与STM32通过UART串口通信,同时需注意电源隔离与信号完整性。

2.2.1 引脚连接表

STM32F103C8T6引脚

BC26模块引脚

功能说明

PA9(USART1_TX)

RXD

STM32发送数据到BC26

PA10(USART1_RX)

TXD

STM32接收BC26返回数据

5V

VIN

模块电源(BC26需5V供电)

STM32F103C8T6引脚

BC26模块引脚

功能说明

 

GND

 

GND

共地(必须连接,避免信号干 扰)

PB0(可选)

PWR

模块上电控制(低电平启动)

三、软件环境搭建: 开发工具与库配置

3.1 开发工具准备

STM32CubeMX:用于生成初始化代码(版本6.6.1+)

Keil MDK5:编译与下载代码(需安装STM32F1xx系列支持包)

串口调试助手:如SSCOM、XCOM(用于监控模块AT指令交互)

阿里云IoT平台:创建产品与设备,获取通信凭证

3.2 HAL库与工程配置

3.2.1 STM32CubeMX配置步骤

1. 新建工程:选择STM32F103C8T6,配置RCC为外部高速时钟(HSE)。

2. UART配置

◦ 打开USART1,模式选择“异步通信(Asynchronous)”,波特率115200,数据位8,停止位1,无校 验。

◦ 使能USART1中断(NVIC Settings → USART1 global interrupt → Enabled)。

3. GPIO配置:若使用PB0控制BC26上电,配置为推挽输出(GPIO_Output)。

4. 生成代码:选择“MDK-ARM”,勾选“Generate peripheral initialization as .c/.hfiles”,点击生成工程。

四、 NB-IoT模块核心原理:AT指令与网络附着

4.1 BC26 AT指令集概述

BC26通过AT指令控制,核心指令如下表:

指令功能说明示例响应
AT测试模块是否正常OK
AT+CIMI查询SIM卡IMSI号(确认卡是否识别)460041234567890
AT+CSQ查询信号质量(0-31,越大越好)+CSQ: 28,0
AT+CGATT?查询网络附着状态(1=附着,0=未附着)+CGATT: 1
AT+QMTCFG="aliauth",0,"PK","DN","DS"配置阿里云MQTT认证信息(PK/DN/DS为设备三元组)OK
AT+QMTOPEN=0,"iot-as-mqtt.cn-shanghai.aliyuncs.com",1883连接阿里云MQTT服务器+QMTOPEN: 0,0

4.2 NB-IoT网络附着流程

1. 模块上电初始化:BC26上电后需1-2秒稳定,发送  AT 指令确认响应。

2. SIM卡检测:发送  AT+CIMI,返回IMSI号表示SIM卡正常。

3. 信号质量检查:  AT+CSQ返回值需≥10(否则需调整天线位置)。

4. 网络附着:  AT+CGATT=1 附着网络,  AT+CGATT? 返回1表示成功。

5. PDP上下文激活:  AT+CGACT=1,1激活数据业务,获取IP地址(   AT+CGPADDR=1 )。

五、驱动代码实现: UART通信到阿里云对接

5.1 UART底层驱动(基于HAL库)

5.1.1 UART初始化代码(stm32f1xx_hal_msp.c

void HAL_UART_MspInit(UART_HandleTypeDef* huart) {GPIO_InitTypeDef GPIO_InitStruct = {0};if (huart->Instance == USART1) {__HAL_RCC_USART1_CLK_ENABLE();    // 使能USART1时钟__HAL_RCC_GPIOA_CLK_ENABLE();     // 使能GPIOA时钟// PA9(TX)配置为复用推挽输出GPIO_InitStruct.Pin = GPIO_PIN_9;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// PA10(RX)配置为浮空输入GPIO_InitStruct.Pin = GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置USART1中断优先级HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);HAL_NVIC_EnableIRQ(USART1_IRQn);}
}

5.1.2 UART中断接收与AT指令解析( usart.c

uint8_t uart_rx_buf[256];  // 接收缓冲区
uint16_t uart_rx_len = 0;   // 接收长度// USART1中断服务函数
void USART1_IRQHandler(void) {uint8_t ch;if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE)) {HAL_UART_Receive(&huart1, &ch, 1, 0x01);  // 读取接收数据uart_rx_buf[uart_rx_len++] = ch;           // 存入缓冲区if (ch == '\n' || uart_rx_len >= 255) {    // 换行符或缓冲区满时结束uart_rx_buf[uart_rx_len] = '\0';          // 添加字符串结束符uart_rx_len = 0;                         // 重置接收长度// 解析AT指令响应(此处可添加状态机处理逻辑)}}HAL_UART_IRQHandler(&huart1);
}// 发送AT指令函数
HAL_StatusTypeDef AT_SendCmd(char *cmd, uint32_t timeout) {HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), timeout);  // 发送指令HAL_Delay(100);  // 等待模块响应return HAL_OK;
}

5.2 BC26模块初始化与阿里云连接

5.2.1 BC26初始化流程( bc26.c

// 模块初始化状态枚举
typedef enum {BC26_STATE_INIT,       // 初始状态BC26_STATE_CHECK_SIM,  // 检查SIM卡BC26_STATE_ATTACH_NET, // 网络附着BC26_STATE_MQTT_CONN,  // MQTT连接BC26_STATE_READY       // 就绪状态
} BC26_StateTypeDef;BC26_StateTypeDef bc26_state = BC26_STATE_INIT;// BC26初始化函数
void BC26_Init(void) {switch (bc26_state) {case BC26_STATE_INIT:AT_SendCmd("AT\r\n", 1000);  // 测试模块if (strstr((char*)uart_rx_buf, "OK")) {bc26_state = BC26_STATE_CHECK_SIM;memset(uart_rx_buf, 0, sizeof(uart_rx_buf));}break;case BC26_STATE_CHECK_SIM:AT_SendCmd("AT+CIMI\r\n", 1000);  // 查询IMSIif (strstr((char*)uart_rx_buf, "460")) {  // 中国运营商IMSI以460开头bc26_state = BC26_STATE_ATTACH_NET;memset(uart_rx_buf, 0, sizeof(uart_rx_buf));}break;// 后续状态(网络附着、MQTT连接)代码省略,完整代码见工程文件}
}

5.2.2 阿里云MQTT连接关键代码

// 配置阿里云三元组(需替换为实际值)
#define PRODUCT_KEY     "a1b2c3d4e5f6g7h8i9j0k"
#define DEVICE_NAME     "NB_IoT_Device"
#define DEVICE_SECRET   "abcdef1234567890abcdef1234567890"// 连接阿里云MQTT服务器
void BC26_MQTT_Connect(void) {char cmd[256];// 配置阿里云认证sprintf(cmd, "AT+QMTCFG=\"aliauth\",0,\"%s\",\"%s\",\"%s\"\r\n", PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET);AT_SendCmd(cmd, 1000);// 连接阿里云MQTT服务器(地址:iot-as-mqtt.cn-shanghai.aliyuncs.com,端口1883)AT_SendCmd("AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883\r\n", 2000);if (strstr((char*)uart_rx_buf, "+QMTOPEN: 0,0")) {  // 连接成功// 订阅主题(示例:/sys/a1b2c3d4e5f6g7h8i9j0k/NB_IoT_Device/user/get)sprintf(cmd, "AT+QMTSUB=0,1,\"/sys/%s/%s/user/get\",0\r\n", PRODUCT_KEY, DEVICE_NAME);AT_SendCmd(cmd, 1000);}
}

5.3 数据上报与接收示例

5.3.1 温湿度数据上报(main.c)

// 假设通过DHT11获取温湿度(代码省略,可参考SHT20驱动) float temp = 25.5, humi = 60.0; char data_buf[128];  // 上报数据到阿里云 void Aliyun_ReportData(float temp, float humi) {  char cmd[512];  // 构建JSON格式数据(阿里云物模型格式)  sprintf(data_buf, "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"CurrentTemperature\":{\"value\":%.1f},\"CurrentHumidity\":{\"value\":%.1f}},\"method\":\"thing.event.property.post\"}", temp, humi);   // 发布主题(示例:/sys/a1b2c3d4e5f6g7h8i9j0k/NB_IoT_Device/thing/event/property/post)  sprintf(cmd, "AT+QMTPUB=0,0,0,0,\"/sys/%s/%s/thing/event/property/post\",\"%s\"\r\n",  PRODUCT_KEY, DEVICE_NAME, data_buf);  AT_SendCmd(cmd, 2000); }  // 主循环 int main(void) {  HAL_Init();  SystemClock_Config();  MX_GPIO_Init();  MX_USART1_UART_Init();   while (1) {  BC26_Init(); // 模块初始化  if (bc26_state == BC26_STATE_READY) {  Aliyun_ReportData(temp, humi); // 上报数据  HAL_Delay(10000); // 每10秒上报一次  }  HAL_Delay(100);  } }

六、调试与测试:从指令交互到平台验证

6.1 AT指令调试(串口助手)

通过USB转TTL连接BC26的TX/RX引脚,使用串口助手发送AT指令,验证模块功能:

AT // 测试模块 OK AT+CIMI // 查询IMSI 460041234567890 OK AT+CSQ // 信号质量 +CSQ: 28,0 OK AT+CGATT? // 网络附着 +CGATT: 1 OK

6.2 阿里云平台数据查看

  1. 登录阿里云IoT平台:进入“设备管理 → 设备”,查看设备状态为“在线”。
  2. 物模型数据:在设备详情页“物模型数据”中,可实时查看上报的温湿度数据。
  3. 日志服务:通过“监控运维 → 日志服务”查看设备上下线记录和数据传输日志。

七、进阶应用:低功耗优化与多场景扩展

7.1 BC26低功耗模式(PSM)配置

BC26支持PSM(Power Saving Mode),可通过AT指令配置:

// 使能PSM模式(TAU=3600秒,Active Time=60秒) AT+CSCON=0 // 进入Idle状态 AT+CPWROFF // 模块断电(实际进入PSM)

7.2 STM32低功耗配合(Stop模式)

STM32进入Stop模式,通过LPTIM定时器唤醒:

void EnterStopMode(void) {  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 进入Stop模式  // 唤醒后需重新配置系统时钟  SystemClock_Config(); }

八、总结与扩展

本文详细介绍了STM32F103C8T6与BC26模块的硬件连接、软件配置、AT指令交互及阿里云对接流程,提供了完整的代码框架和调试方法。读者可进一步扩展:

  • 多传感器数据采集:添加光照、气压等传感器,丰富上报数据。
  • OTA远程升级:通过BC26实现设备固件远程更新。
  • 多平台对接:适配中国移动OneNET、华为OceanConnect等平台。

技术交流:欢迎在评论区留言提问,或关注博主获取更多物联网开发教程!

创作声明:本文为原创内容,转载请注明出处。文中代码经过实际测试,可直接移植使用。如有错误,欢迎指正!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88510.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88510.shtml
英文地址,请注明出处:http://en.pswp.cn/web/88510.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS 性能测试工具全流程:主流工具实战对比与适用场景

在iOS开发中,性能优化往往被安排到开发后期,甚至上线前才临时补救。但性能瓶颈通常是架构设计、资源加载、动画机制等多方面共同作用的结果,仅凭肉眼感知和log输出,难以精准定位。 一套合适的性能测试工具组合,不仅能帮…

目标检测:视觉系统中的CNN-Transformer融合网络

一、背景 无人机(UAVs)在城市自动巡逻中发挥着重要作用,但它们在图像识别方面面临挑战,尤其是小目标检测和目标遮挡问题。此外,无人机的高速飞行要求检测系统具备实时处理能力。 为解决这些问题,我们提出了…

揭示宇宙的隐藏对称性:群论-AI云计算拓展核心内容

通过利用云计算,借助群论对宇宙对称性的探索,从离散群和李群等基础概念,逐步深入到量子力学和更高自旋系统中的高级应用。 对称性远不止是美学上的吸引力;它是编织在宇宙结构中的一个基本原则。从雪花的复杂图案到控制粒子的基本定…

前端项目vue3项目集成eslint@9.x跟prettier

tips: 这些涉及编辑器的修改不一定能及时生效,如果没有生效,可以试试重启编辑器窗口 编辑器集成 我的编辑器是vscode,需要安装这两个编辑器插件eslint prettier我这个配置主要是通过eslint提供的配置cli命令生成,在里面加入了对pr…

登录超时问题的排查方法与预防经验分享

​​一、排查方法​​​​检查网络连接​​确保网络稳定,尝试重启路由器或切换网络(如从WiFi切换到移动数据)。使用命令(如 ping 或 traceroute)测试网络连通性,排查是否存在丢包或高延迟。​​验证服务端状…

uniapp,Anroid10+版本如何保存图片并删除

Android 10系统开始 进一步增强了平台功能,为外部存储设备上的应用和用户数据提供了更好的保护。作为这项工作的一部分,平台引入了进一步的改进,以简化向分区存储的转换。 为了让用户更好地控制自己的文件,保护用户隐私数据&#…

Jenkins Pipeline 语法

Pipeline 简介 Jenkins2.x 的核心是使用 pipeline 来构建项目,也就是流水线,将 Jenkins1.0 版本中基于表单的配置信息比如 JDK/SVN 以及参数的配置都转变成了代码,即 pipeline as Code。 传统的表单方式有以下缺点: 需要大量的 web 表单交互,有时候需要进行很多次的切换…

搭建渗透测试环境

一、基于docker搭建靶场 #此步骤需要科学上网 #从软件源中下载 docker.io 和 docker -compose 软件包及其依赖项。 sudo apt-get install docker.io docker-compose #查看docker版本 docker -v #查看docker信息 docker info #重启docker服务 sudo systemctl daemon-reload sudo…

(一)OpenCV——噪声去除(降噪)

高斯滤波器(针对高斯噪声) 高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。常见的高斯噪声包括起伏噪声、宇宙噪声、热噪声和散粒噪声等等。 高斯滤波(Gaussian filter) 包含许多种,包括低通、带…

百度开源文心 4.5 系列开源大模型 GitCode 本地化部署,硅基流动:文心 vs. DeepSeek vs. Qwen 3.0 深度测评

百度开源文心 4.5 系列开源大模型 GitCode 本地化部署,硅基流动:文心 vs. DeepSeek vs. Qwen 3.0 深度测评 文章目录百度开源文心 4.5 系列开源大模型 GitCode 本地化部署,硅基流动:文心 vs. DeepSeek vs. Qwen 3.0 深度测评背景百…

「日拱一码」022 机器学习——数据划分

目录 基于单次随机划分的方法 普通单次随机划分(train_test_split) 分层单次随机划分(使用 train_test_split 的 stratify 参数) 基于多次随机划分的方法 普通多次随机划分(ShuffleSplit) 分层多次随机划分(StratifiedShuffleSplit…

lora网关

所需配置的引脚,SPI传输,PG13复位(输出引脚,推挽输出),PE2忙碌(输入引脚,浮空输入)PE6PE5输出。若利用延时处理按键消抖,hal库里用systick中断实现延时&#…

5G IMS注册关键一步:UE如何通过ePCO获取P-CSCF地址

看似简单的P-CSCF地址传递,背后是5G核心网控制面与用户面的精密协作。ePCO作为高效的信令载体,承载着IMS业务触达的第一把钥匙。 在5G网络中建立IMS PDN连接时,UE(用户设备)获取P-CSCF(Proxy-Call Session Control Function)地址是IMS业务(如VoLTE、VoNR)成功注册和运…

JVM方法区的运行时常量区到底存储哪些数据?

JDK8以后,运行时常量池逻辑上属于方法区;但: 其中的字符串常量池实际位置移至到了java堆;其中一些符号引用也存储到了元空间;字符串常量池,元空间,运行时常量区的具体关系请看这篇博客&#xf…

Go defer(二):从汇编的角度理解延迟调用的实现

Go的延迟调用机制会在当前函数返回前执行传入的函数,它会经常被用于关闭文件描述符、关闭数据库连接以及解锁资源。之前的文章( Go defer(一):延迟调用的使用及其底层实现原理详解 )详细介绍了defer的使用以…

Android 12系统源码_分屏模式(一)从最近任务触发分屏模式

前言 打开MainActivity,然后进入最近任务触发分屏,可以成功进入分屏模式。 本篇文章我们来具体梳理一下这个过程的源码调用流程。 一 launcher3阶段 1.1 源码 //packages/apps/Launcher3/quickstep/src/com/android/quickstep/views/TaskView.java publi…

Flask 入门教程:用 Python 快速搭建你的第一个 Web 应用

文章目录前言一、什么是 Flask?📌 Flask 的优势1. 轻量灵活2. 易于上手3. 可扩展性强4. 自由度高5. 社区活跃,资料丰富Flask 主要用来做什么?二、Flask快速入门1.创建一个Flask项目2.开启debug,修改host,端…

实习第一个小需求样式问题总结

Vue2 vxe-table Element UI 表头下拉详情实现总结一、核心功能实现表头下拉按钮交互初始尝试 expand-change 事件无法满足需求&#xff0c;改用 vxe-table 的 toggle-row-expand 事件&#xff1a;<vxe-table toggle-row-expand"handleExpandChange"><temp…

Linux中LVM逻辑卷扩容

在Linux系统中对根目录所在的LVM逻辑卷进行扩容&#xff0c;需要依次完成 物理卷扩容 ➔ 卷组扩容 ➔ 逻辑卷扩容 ➔ 文件系统扩容 四个步骤。以下是详细操作流程&#xff1a;一、确认当前磁盘和LVM状态# 1. 查看磁盘空间使用情况 df -h /# 2. 查看块设备及LVM层级关系 lsblk# …

微软365 PDF导出功能存在本地文件包含漏洞,可泄露敏感服务器数据

微软365的"导出为PDF"功能近期被发现存在严重的本地文件包含(Local File Inclusion, LFI)漏洞&#xff0c;攻击者可利用该漏洞获取服务器端的敏感数据&#xff0c;包括配置文件、数据库凭证和应用程序源代码。该漏洞由安全研究员Gianluca Baldi发现并报告给微软&…