4. LoRa模块初识:SX1278/SX126x芯片介绍、LoRa调制原理、SPI通信协议详解

好,咱们进入第四章节。前面几章我们把物联网网关的骨架搭起来了,也聊了GPS怎么拿位置。但网关的核心——无线通信,还没真正碰。这一章,我们就来啃这块硬骨头:LoRa模块。

说到LoRa,市面上主流的芯片方案就两家:Semtech的SX1278和SX126x系列。我最早接触LoRa时用的是SX1278,后来项目要求低功耗,才切到SX1262。这两兄弟有什么区别?LoRa调制到底是个什么魔法?单片机又是怎么通过SPI跟它们对话的?咱们一个一个拆开看。

4.1 SX1278与SX126x:两代LoRa芯片的对比

先看一张对比表,心里有个底。

特性 SX1278 SX126x (SX1261/62/68)
频率范围 137 ~ 525 MHz 150 ~ 960 MHz
最大发射功率 +20 dBm (100 mW) +22 dBm (SX1262, 约158 mW)
接收电流 约 12 mA 约 4.6 mA (超低功耗模式)
调制方式 LoRa + (G)FSK + OOK LoRa + (G)FSK + MSK
接口 SPI SPI + 可选DIO中断
内部稳压器 LDO LDO + DC-DC (效率更高)
典型应用 早期LoRa节点、网关 低功耗传感器、新一代网关

从表里能看出来,SX126x系列在功耗和集成度上明显更优。我个人习惯是:如果做电池供电的节点,优先选SX1262;如果是网关或者对成本敏感的项目,SX1278依然能打。

我的经验: 有一次做农业大棚监测,节点用SX1278,电池半年就得换。后来换成SX1262,配合DC-DC模式,同样的电池撑了一年半。省下来的换电池人工费,够买好几片芯片了。

4.2 LoRa调制原理:为什么能传那么远?

LoRa这个名字,全称是Long Range,长距离。它凭什么能传几公里甚至十几公里?核心秘密在调制方式上。

传统的FSK(频移键控)调制,是把数据比特直接映射到频率变化上。LoRa不一样,它用的是扩频调制。具体来说,是把一个比特的信息,扩展到多个「啁啾」符号(Chirp)里传输。

你想想看,一个比特本来只需要一个符号就能传完。LoRa把它拆成128个、256个甚至更多的符号。接收端收到这些符号后,通过相关运算把它们「拼」回来。哪怕信号被噪声淹没了,只要符号之间的相关性还在,就能解调出来。

这就是LoRa的杀手锏:扩频增益。

扩频增益的大小,由扩频因子(Spreading Factor, SF)决定。SF值越高,扩得越狠,传输距离越远,但数据速率也越慢。

扩频因子 (SF) 符号速率 (chip/s) 数据速率 (bps, BW=125kHz) 接收灵敏度 (典型)
SF7 125000 约 5470 -123 dBm
SF9 125000 约 1760 -129 dBm
SF12 125000 约 293 -137 dBm

从SF7到SF12,灵敏度提升了14 dBm。这是什么概念?发射功率每增加3 dBm,距离大约翻一倍。14 dBm的灵敏度提升,相当于把发射功率提高了20多倍。这就是LoRa能传几公里的物理基础。

核心公式(理解即可):
数据速率 (bps) = SF * (BW / 2^SF) * (4 / (4 + CR))
其中BW是带宽,CR是编码率。SF越大,速率越慢,距离越远。

除了SF,还有两个参数影响通信质量:带宽(BW)和编码率(CR)。带宽越宽,速率越快,但抗干扰能力下降。编码率越高,冗余越多,纠错能力越强,但有效数据变少。

实际项目中,我一般这样配:

  • 远距离、低速率场景:SF12, BW=125kHz, CR=4/8
  • 中等距离、平衡场景:SF9, BW=250kHz, CR=4/6
  • 近距离、高速率场景:SF7, BW=500kHz, CR=4/5
注意: 同一网络内的所有节点,必须使用相同的SF、BW和CR才能互相通信。我曾经在调试时,网关设了SF9,节点设了SF12,结果死活收不到数据。查了半天才发现是扩频因子没对齐。

4.3 SPI通信协议详解:单片机怎么跟LoRa模块说话?

LoRa芯片内部有几十个寄存器,控制着频率、功率、调制参数、FIFO缓冲区等。单片机要读写这些寄存器,就得通过SPI接口。

SPI,全称Serial Peripheral Interface,串行外设接口。它用四根线搞定通信:

  • SCLK:时钟线,由主机(单片机)产生
  • MOSI:主机输出,从机输入
  • MISO:主机输入,从机输出
  • NSS:片选线,低电平有效

LoRa模块的SPI时序,跟标准SPI略有不同。它要求:

  • 时钟极性(CPOL)= 0:空闲时时钟为低电平
  • 时钟相位(CPHA)= 0:在第一个时钟沿采样数据
  • 数据位序:MSB(最高位)先传输
  • 最大时钟频率:SX1278约10 MHz,SX126x约16 MHz

读写寄存器的流程很简单:

  1. 拉低NSS,选中模块
  2. 发送一个字节的地址+读写标志位(写操作:地址 | 0x80;读操作:地址 & 0x7F)
  3. 如果是写操作,紧接着发送数据字节;如果是读操作,接收数据字节
  4. 拉高NSS,结束通信

看一个实际的写寄存器代码示例:

// 写LoRa寄存器函数
void LoRa_WriteRegister(uint8_t addr, uint8_t data) {
    // 拉低片选
    HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);
    
    // 发送地址(写标志:地址 | 0x80)
    SPI_TransmitByte(addr | 0x80);
    
    // 发送数据
    SPI_TransmitByte(data);
    
    // 拉高片选
    HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);
}

// 读LoRa寄存器函数
uint8_t LoRa_ReadRegister(uint8_t addr) {
    uint8_t data;
    
    // 拉低片选
    HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);
    
    // 发送地址(读标志:地址 & 0x7F)
    SPI_TransmitByte(addr & 0x7F);
    
    // 接收数据(发送0xFF作为时钟)
    data = SPI_TransmitReceiveByte(0xFF);
    
    // 拉高片选
    HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);
    
    return data;
}

这段代码看起来简单,但有几个坑要注意:

  • 片选时序:两次SPI操作之间,NSS必须拉高至少一个时钟周期。我见过有人连续读写时忘了拉高,导致数据错位。
  • 读操作时的填充字节:读寄存器时,主机必须发送一个字节(通常是0xFF)来产生时钟,从机才会在MISO上返回数据。
  • FIFO操作:LoRa模块内部有个256字节的FIFO缓冲区。读写FIFO时,地址是固定的(SX1278的0x00),连续读写时地址会自动递增。
避坑指南: 我曾经在调试SX1262时,发现读回来的寄存器值全是0xFF。查了半天,发现是SPI时钟频率设成了20 MHz,超过了芯片的16 MHz上限。降频到10 MHz后,一切正常。所以,SPI时钟别一味求快,稳定第一。

4.4 知识体系总览:一张图看懂本章核心

下面这张SVG图,把本章的三个核心知识点串起来了。你可以把它当作一个思维导图,快速回顾。

第4章知识体系:LoRa模块初识 LoRa模块初识 SX1278 vs SX126x 频率范围 发射功率 接收电流 内部稳压器 LoRa调制原理 扩频调制 (Chirp) 扩频因子 (SF7~SF12) 带宽 (BW) 编码率 (CR) SPI通信协议 SCLK / MOSI / MISO / NSS CPOL=0, CPHA=0 读写寄存器流程 FIFO操作 核心:理解扩频增益与SPI时序 这是后续配置LoRa模块、实现通信的基础

4.5 小结:这一章你该带走什么?

嗯,内容不少,咱们捋一捋重点:

  • SX1278和SX126x:两代芯片,选型看功耗和成本。SX126x是未来趋势,但SX1278依然广泛。
  • LoRa调制:扩频调制是远距离通信的基石。SF、BW、CR三个参数决定了距离和速率,需要根据场景权衡。
  • SPI通信:四根线,时序固定。读写寄存器是基本功,FIFO操作是进阶。时钟频率别超限,片选时序别马虎。