第2章 LoRa射频芯片SX1278详解
好,咱们直接进入正题。SX1278这颗芯片,可以说是LoRa技术的灵魂。我做了这么多年物联网项目,用过的射频芯片少说也有十几款,但SX1278给我的印象最深。为什么?因为它把「远距离」和「低功耗」这对矛盾体,硬是给揉到了一起。
今天我就带你把这颗芯片扒开看看。从引脚功能到内部寄存器,从工作模式到SPI通信,咱们一个一个过。
2.1 芯片引脚功能
先看引脚。SX1278是QFN28封装,28个脚,不算多。但每个脚都有讲究。我刚开始用的时候,就因为在DIO2上少接了个上拉电阻,折腾了两天。嗯,这种坑咱们后面再说。
我把关键引脚分成几类,你记一下:
电源与地
- VDD:主电源,1.8V~3.7V。我习惯用3.3V,稳定。
- VBAT:电池供电引脚,如果你用电池供电就走这里。
- VREG:内部稳压器输出,接个1μF电容到地就行。
- GND:地。别小看它,铺地没铺好,灵敏度直接掉3dB。
射频接口
- RFI_P / RFI_N:接收差分输入。我建议走差分线,抗干扰好。
- RFO_LF:低频段发射输出,137MHz~525MHz。
- RFO_HF:高频段发射输出,862MHz~1020MHz。
数字控制接口
- NSS:片选,低电平有效。SPI通信时拉低。
- SCK:SPI时钟,最高10MHz。我一般跑5MHz,稳。
- MOSI / MISO:数据线,标准SPI四线制。
- DIO0~DIO5:数字IO,用来输出中断信号。DIO0最常用,映射到TxDone或RxDone。
- RESET:复位,低电平有效。上电后必须复位一次,否则芯片不干活。
2.2 内部寄存器映射
SX1278内部有上百个寄存器,地址从0x00到0x7F。说实话,你不需要全记住。但有几个关键寄存器,你必须烂熟于心。
我整理了一张表,你直接收藏:
| 地址 | 寄存器名 | 功能 |
|---|---|---|
| 0x01 | RegOpMode | 工作模式选择,最常用的寄存器 |
| 0x0D | RegFrfMsb | 频率设置高位 |
| 0x0E | RegFrfMid | 频率设置中位 |
| 0x0F | RegFrfLsb | 频率设置低位 |
| 0x1D | RegModemConfig1 | 调制解调配置1,含带宽和编码率 |
| 0x1E | RegModemConfig2 | 调制解调配置2,含扩频因子 |
| 0x40 | RegDioMapping1 | DIO引脚功能映射 |
| 0x4C | RegHopPeriod | 跳频周期设置 |
频率怎么算?公式很简单:
RF频率 = (RegFrfMsb << 16 | RegFrfMid << 8 | RegFrfLsb) * Fstep
其中 Fstep = 61.035 Hz(晶振32MHz时)
举个例子,我想设到490MHz:
频率值 = 490000000 / 61.035 ≈ 8028160 = 0x7A8000
所以 RegFrfMsb = 0x7A, RegFrfMid = 0x80, RegFrfLsb = 0x00
2.3 工作模式配置
SX1278有6种工作模式,通过RegOpMode寄存器控制。说白了,就是让芯片在不同状态下干活。
- Sleep(睡眠):功耗最低,~0.2μA。配置寄存器前必须进这个模式。
- Standby(待机):晶振工作,但射频关闭。~1.6mA。我一般在这里做初始化。
- FS_TX(频率合成发射):PLL锁定发射频率。很少单独用。
- FS_RX(频率合成接收):PLL锁定接收频率。也很少单独用。
- TX(发射):发射数据。电流最大,~120mA@20dBm。
- RX(接收):接收数据。~12mA。连续接收模式最常用。
模式切换的代码,我习惯这么写:
void SX1278_SetMode(uint8_t mode) {
uint8_t reg = ReadRegister(REG_OPMODE);
reg = (reg & 0xF8) | mode; // 保留高5位,设置低3位
WriteRegister(REG_OPMODE, reg);
}
你想想看,为什么切换模式时要保留高5位?因为高5位里包含了LoRa/Fsk模式选择位。你要是直接写0,就把LoRa模式给清了。嗯,细节决定成败。
2.4 SPI通信协议
SX1278的SPI协议,说简单也简单,说复杂也复杂。标准四线制:NSS、SCK、MOSI、MISO。但有个坑——地址格式。
SPI读写命令是一个字节:
- 写操作:地址 + 0x00(最高位为0)
- 读操作:地址 + 0x80(最高位为1)
举个例子,读RegOpMode(地址0x01):
// 伪代码
NSS = 0; // 拉低片选
SPI_Write(0x01 | 0x80); // 发送读命令,0x81
uint8_t val = SPI_Read(); // 读取数据
NSS = 1; // 拉高片选
写操作类似:
NSS = 0;
SPI_Write(0x01); // 写命令,0x01
SPI_Write(0x08); // 写入数据,比如切到Standby模式
NSS = 1;
还有一个技巧——突发读写。如果你要连续读写多个寄存器,可以保持NSS为低,连续发地址和数据。比如初始化时,我经常用突发写来批量配置:
void SX1278_BurstWrite(uint8_t addr, uint8_t *buf, uint8_t len) {
NSS = 0;
SPI_Write(addr); // 起始地址
for(uint8_t i = 0; i < len; i++) {
SPI_Write(buf[i]); // 连续写数据
}
NSS = 1;
}
这样做的好处是快。你想想看,如果每个寄存器都单独拉一次NSS,光片选切换的时间就够你受的。尤其是在实时性要求高的场景,比如跳频通信,突发读写能省下不少时间。
小结
这一章的内容,说白了就是SX1278的「使用说明书」。引脚怎么接,寄存器怎么配,模式怎么切,SPI怎么通信。你把这些搞懂了,后面写驱动就是水到渠成的事。
我个人建议,拿到芯片后先别急着写代码。拿示波器看看SPI波形,确认通信正常。再用逻辑分析仪抓一下DIO中断,看看时序对不对。硬件调通了,软件才有意义。
下一章,咱们开始写LoRa驱动。到时候我会把初始化流程、发送接收的代码,一行一行给你讲清楚。准备好了吗?