tags: [source-summary] type: source source: "尚硅谷嵌入式技术之STM32单片机(高级篇)V2.0.1 — LoRa章节 + 配套代码13~14" author: "尚硅谷研究院" date: 2026-07-15
用生活理解:LoRa 就像"对讲机里的长跑冠军"——说话速度很慢(50bps),但声音能传出几公里,而且电池用几年不换。适合田野里的温度传感器每隔一小时报一次数。LoRa 是在水下吹气泡——气泡(信号)虽然升得慢,但能飘很远。
LPWAN = Low Power Wide Area Network(低功耗广域网),是 IoT 中连接远距离、低功耗设备的无线技术。
| 技术 | 频段 | 速率 | 优点 | 缺点 |
|---|---|---|---|---|
| LoRa | 470~510MHz(CN) / 868MHz(EU) / 915MHz(US) | 0.3~50Kbps | 私有化部署、成本低 | 速率低 |
| NB-IoT | 运营商授权频段 | ~250Kbps | 覆盖广、运营商维护 | 需 SIM 卡、有月费 |
| Sigfox | 868/915MHz | ~100bps | 超低功耗 | 速率极低、依赖 Sigfox 网络 |
| LTE-M | 运营商授权频段 | ~1Mbps | 速率较高 | 模组贵、功耗较高 |
LoRa 使用CSS(Chirp Spread Spectrum,啁啾扩频)调制。普通无线信号像"喊话"(功率集中在一小段频率),LoRa 像"吹口哨从低到高再从高到低"(信号散布在宽频带上)。
| 参数 | 可取值范围 | 说明 | 对性能的影响 |
|---|---|---|---|
| SF (扩频因子) | 6~12 | 每个 Chirp 符号代表的位数 | SF↑ → 灵敏度↑ → 速率↓ |
| BW (带宽) | 125 / 250 / 500 KHz | 调制信号的频率宽度 | BW↑ → 速率↑ → 灵敏度↓ |
| CR (编码率) | 4/5 ~ 4/8 | 前向纠错(FEC)冗余度 | CR↑ → 抗干扰↑ → 冗余↑ |
典型参数速查表:
| SF | BW(KHz) | 速率(bps) | 灵敏度(dBm) | 参考距离 |
|---|---|---|---|---|
| 7 | 125 | ~5470 | -123 | ~2km |
| 9 | 125 | ~1460 | -129 | ~3km |
| 12 | 125 | ~290 | -137 | ~5km |
| 12 | 250 | ~580 | -134 | ~3.5km |
SF12 + BW125 是最常见的高灵敏度配置,适合需要最远距离但数据量很少的场景。
CAD 是 LoRa 的一个特殊功能——在极低功耗下周期性监听空中是否有 LoRa 信号。如果检测到信号,唤醒 MCU 接收;无信号则快速返回休眠。
CAD 的意义:普通 LoRa 接收模式下,接收机须持续打开(功耗 ~10mA),而 CAD 的监听功耗极低(~5μA)。
LoRa 网络采用星型拓扑:
┌─→ 节点1 (SF12, 上报温度)
│
┌──────┐ ├─→ 节点2 (SF9, 上报湿度) ┌──────────┐
│ 网关 │←┼─→ 节点3 (SF7, 上报位移) ───→│ 云服务器 │
│(接收) │ └─→ ... │(数据存储)│
└──────┘ └──────────┘
↓
STM32(处理数据)
项目路径:stm32/13_lora_node_hal(节点)、stm32/14_lora_gateway_hal(网关)
节点通过串口配置 LoRa 模块参数,定时发送传感器数据。
文件:stm32/13_lora_node_hal(节点发送端)
// LoRa 模块初始化 AT 配置
void LoRa_Node_Init(void)
{
// 1. 设置模块工作模式
AT_SendCmd("AT+MODE=0\r\n", "OK", 1000);
// MODE: 0=透明传输(透传), 1=定点传输(指定地址)
// 2. 设置本机地址(不同类型设备用不同地址区分)
AT_SendCmd("AT+ADDR=1\r\n", "OK", 1000); // 节点地址=1
// 3. 设置射频参数
AT_SendCmd("AT+BAND=470000000\r\n", "OK", 1000); // 频率 470MHz
AT_SendCmd("AT+SF=12\r\n", "OK", 1000); // 扩频因子 12
AT_SendCmd("AT+BW=125\r\n", "OK", 1000); // 带宽 125KHz
AT_SendCmd("AT+CR=1\r\n", "OK", 1000); // 编码率 4/5
// 4. 设置发射功率(0~20dBm,默认 20dBm)
AT_SendCmd("AT+POWER=20\r\n", "OK", 1000);
}
// 发送数据到网关(地址=0, 因为网关是透明接收模式)
void LoRa_Node_Send(uint8_t *data, uint16_t len)
{
char cmd[256];
// 透明传输模式: AT+SEND=dest_addr,len,data
// dest_addr=0 表示所有设备都能收
sprintf(cmd, "AT+SEND=0,%d,", len);
AT_SendCmd(cmd, "OK", 2000);
// 发送实际数据
HAL_UART_Transmit(&huart2, data, len, 1000);
}
// 应用程序:每 60 秒上报一次温度值
void Node_Application(void)
{
LoRa_Node_Init();
while (1)
{
uint16_t adc_val = ADC1_Read(); // 读取 ADC(温度传感器)
float temp = adc_val * 3.3f / 4095 * 100; // 温度转换
char buf[64];
sprintf(buf, "TEMP:%.1f\r\n", temp);
LoRa_Node_Send((uint8_t *)buf, strlen(buf));
HAL_Delay(60000); // 60s 发送一次(超低功耗场景)
}
}
文件:stm32/14_lora_gateway_hal(网关接收端)
// 网关初始化(使用与节点相同的射频参数)
void LoRa_Gateway_Init(void)
{
// 与节点相同:470MHz, SF12, BW125
AT_SendCmd("AT+MODE=0\r\n", "OK", 1000);
AT_SendCmd("AT+ADDR=0\r\n", "OK", 1000); // 网关地址=0
AT_SendCmd("AT+BAND=470000000\r\n", "OK", 1000);
AT_SendCmd("AT+SF=12\r\n", "OK", 1000);
AT_SendCmd("AT+BW=125\r\n", "OK", 1000);
}
// 数据接收中断(串口主动上报)
// LoRa 模块收到数据后通过串口打印:
// +RCV=src_addr,len,RSSI,SNR,data
void Process_LoRa_RxData(uint8_t *buffer)
{
if (strstr((char *)buffer, "+RCV="))
{
// 解析 RSSI(接收信号强度)和 SNR(信噪比)
// e.g., +RCV=1,6,-115,5,HELLO
// ↑地址 ↑RSSI ↑SNR
int src_addr, len, rssi, snr;
char data[64];
sscanf((char *)buffer, "+RCV=%d,%d,%d,%d,%s",
&src_addr, &len, &rssi, &snr, data);
printf("Node %d: %s (RSSI=%d, SNR=%d)\r\n",
src_addr, data, rssi, snr);
}
}
| 参数 | AT 指令 | 说明 |
|---|---|---|
| 工作模式 | AT+MODE=0 |
0=透传, 1=定点传 |
| 本机地址 | AT+ADDR=1 |
1~65535 |
| 目标地址 | AT+SEND=addr,len,data |
定点模式时指定 |
| 中心频率 | AT+BAND=470000000 |
单位 Hz(470~510MHz) |
| 扩频因子 | AT+SF=12 |
6~12 |
| 带宽 | AT+BW=125 |
125/250/500 KHz |
| 编码率 | AT+CR=1 |
1=4/5, 2=4/6, 3=4/7, 4=4/8 |
| 发射功率 | AT+POWER=20 |
0~20dBm |
| CAD 使能 | AT+CAD=1 |
0=关, 1=开(低功耗监听) |