一、引言: 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 阿里云平台数据查看
- 登录阿里云IoT平台:进入“设备管理 → 设备”,查看设备状态为“在线”。
- 物模型数据:在设备详情页“物模型数据”中,可实时查看上报的温湿度数据。
- 日志服务:通过“监控运维 → 日志服务”查看设备上下线记录和数据传输日志。
七、进阶应用:低功耗优化与多场景扩展
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等平台。
技术交流:欢迎在评论区留言提问,或关注博主获取更多物联网开发教程!
创作声明:本文为原创内容,转载请注明出处。文中代码经过实际测试,可直接移植使用。如有错误,欢迎指正!