目录
- LoRa简介
- 硬件设备
- 源码分析
- `Sender`
- 两种调制方式
LoRa简介
详细的LoRaWAN协议解析在这里
本文主要介绍LoRa在Arduino上的实现过程,从而学习LoRa协议的实现。
硬件设备
包括传统的GFSK调制技术以及LoRa(远程)扩频技术
这里说一下啥叫LoRa扩频技术
扩频通信的基本思想:根据香农公式**C = W * log2(1 + S / N)
**,为了提高信号的传输速率C,可以增加带宽W或者提高信噪比S/N,即当传输速率一定时,带宽与信噪比可以互换。扩频通信就是用带宽换信噪比。
LoRa目前主要在ISM频段运行,包括433、868、915MHz等。LoRa的优势在于长距离能力,单个网关或基站可以覆盖数百平方公里范围
管脚定义
PIN | 描述 |
---|---|
GND | 信号地 |
DIO(1/2/3/4/5/6) | 数字IO,可自定义 |
VCC | 电源(1.8V~3.6V) |
MISO | SPI数据输出 |
MOSI | SPI数据输入 |
SCK | SPI时钟输入 |
NSS | SPI片选 |
ANT | 天线接口 |
源码分析
Sender
void setup() {Serial.begin(9600);while (!Serial);Serial.println("LoRa Sender");if (!LoRa.begin(915E6)) {Serial.println("Starting LoRa failed!");while (1);}
}
核心初始化设置为:LoRa.begin
函数声明:
int begin(long frequency);
接收的参数为频率,也就是说上述发送的频率为915E6
,595430(十进制)
具体操作在这里:
int LoRaClass::begin(long frequency)
{
#if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310)pinMode(LORA_IRQ_DUMB, OUTPUT);digitalWrite(LORA_IRQ_DUMB, LOW);// Hardware resetpinMode(LORA_BOOT0, OUTPUT);digitalWrite(LORA_BOOT0, LOW);pinMode(LORA_RESET, OUTPUT);digitalWrite(LORA_RESET, HIGH);delay(200);digitalWrite(LORA_RESET, LOW);delay(200);digitalWrite(LORA_RESET, HIGH);delay(50);
#endif// setup pinspinMode(_ss, OUTPUT);// set SS highdigitalWrite(_ss, HIGH);if (_reset != -1) {pinMode(_reset, OUTPUT);// perform resetdigitalWrite(_reset, LOW);delay(10);digitalWrite(_reset, HIGH);delay(10);}// start SPI_spi->begin();// check versionuint8_t version = readRegister(REG_VERSION);if (version != 0x12) {return 0;}// put in sleep modesleep();// set frequencysetFrequency(frequency);// set base addresseswriteRegister(REG_FIFO_TX_BASE_ADDR, 0);writeRegister(REG_FIFO_RX_BASE_ADDR, 0);// set LNA boostwriteRegister(REG_LNA, readRegister(REG_LNA) | 0x03);// set auto AGCwriteRegister(REG_MODEM_CONFIG_3, 0x04);// set output power to 17 dBmsetTxPower(17);// put in standby modeidle();return 1;
}
下面逐步分析这个初始化函数都干了些神马
-
检测是否定义了
ARDUINO_SAMD_MKRWAN1300
:
这是一个内置了LoRa功能的Arduino开发板 -
管脚设置
第一步:将_ss
设置为输出,找到这个变量定义的是
_ss(LORA_DEFAULT_SS_PIN)
...
#define LORA_DEFAULT_SS_PIN LORA_IRQ_DUMB
也就是用作LoRa的中断引脚
下一步将这个_ss
管脚置高,也就是输出高电平
第二步:如果复位引脚不等于-1,就将复位引脚置为输出,并且输出一个10us的脉冲
#define LORA_DEFAULT_RESET_PIN -1
......
_reset(LORA_DEFAULT_RESET_PIN)
第三步:开启SPI
#define LORA_DEFAULT_SPI SPI
.......
_spi(&LORA_DEFAULT_SPI)
第四步:读取版本信息
uint8_t LoRaClass::readRegister(uint8_t address){return singleTransfer(address & 0x7f, 0x00);
}
这个函数只是简单的调用了一下singleTransfer()
这个函数,该函数的定义就在下面
uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value)
{uint8_t response;digitalWrite(_ss, LOW); // 使能从机_spi->beginTransaction(_spiSettings);_spi->transfer(address);response = _spi->transfer(value);_spi->endTransaction();digitalWrite(_ss, HIGH); // 复位从机return response;
}
首先_spiSettings
是配置
_spiSettings(LORA_DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0),
默认的SPI频率为:
#define LORA_DEFAULT_SPI_FREQUENCY 8E6 // 2278
第二个参数MSBFIRST
表示dataOrder,只有两种选项,另一种是LSBFIRST
,分别是Most Significant Bit(ADDR[31:0]
),和Lest Significant Bit(ADDR[0:31]
)
第三个参数SPI_MODE0
表示dataMode,可选SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3
除了频率,SPI传输需要设置Clock polarity and phase(CPOL & CPHA)
CPOL=0
:时钟空闲时候电平为低电平(SCLK有效为高)
CPOL=1
:时钟空闲时候电平为高电平(SCLK有效为低)
CPHA=0
:第一个边沿采样
CPHA=1
:第二个边沿采样
_spi->transfer(address);
SPI传输基于同时发送与接收,主机传送字节,并返回从从机接收的字节
而version的信息位于:
也就是判断所用的LoRa模块必须是SX12系列的
第五步:设置睡眠模式
void LoRaClass::sleep()
{writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
}
用到的参数:
#define REG_OP_MODE 0x01
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
void LoRaClass::writeRegister(uint8_t address, uint8_t value)
{singleTransfer(address | 0x80, value);
}
注意读取寄存器,用的是address & 0x7f
,而写寄存器用的是address | 0x80
。
第六步:设置频率
void LoRaClass::setFrequency(long frequency)
{_frequency = frequency;uint64_t frf = ((uint64_t)frequency << 19) / 32000000;writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16));writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8));writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
}
首先为什么要左移19位
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
第七步:写TX与RX FIFO
SX12系列配备了一个256字节的RAM作为数据缓存区,仅在LoRa模式下可用,对其的所用访问都要都过SPI接口完成,可以在除睡眠模式之外的所有模式下访问FIFO,会自动清除旧的内容。
第八步:设置前端的低噪放
这里是读取原来LNA寄存器中的值,将此值与'b00000011
做或运算,然后再写回去。可以看到一定取得最后两位表示LnaBoostHf
SX1276/77/78 feature three distinct RF power amplifiers. Two of those, connected to RFO_LF and RFO_HF, can deliver up to +14 dBm, are unregulated for high power efficiency and can be connected directly to their respective RF receiver inputs via a pair of passive components to form a single antenna port high efficiency transceiver. The third PA, connected to the PA_BOOST pin and can deliver up to +20 dBm via a dedicated matching network. Unlike the high efficiency PAs, this high-stability PA covers all frequency bands that the frequency synthesizer addresses.
SX12系列包括三个不同的RF功率放大器,其中两个连接到RFO_LF and RFO_HF,可以提供高达+14dBm的功率,并且无需调节,第三个连接到PA_BOOST 引脚,可以通过专用匹配网络,获得高达+20dBm的功率
第九步:设置自动增益放大器
#define REG_MODEM_CONFIG_3 0x26
第十步:设置发射功率
void LoRaClass::setTxPower(int level, int outputPin)
{if (PA_OUTPUT_RFO_PIN == outputPin) {// RFOif (level < 0) {level = 0;} else if (level > 14) {level = 14;}writeRegister(REG_PA_CONFIG, 0x70 | level);} else {// PA BOOSTif (level > 17) {if (level > 20) {level = 20;}// subtract 3 from level, so 18 - 20 maps to 15 - 17level -= 3;// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)writeRegister(REG_PA_DAC, 0x87);setOCP(140);} else {if (level < 2) {level = 2;}//Default value PA_HF/LF or +17dBmwriteRegister(REG_PA_DAC, 0x84);setOCP(100);}writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));}
}
最后一步:设置为空闲模式,等待发送操作
#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1
void LoRaClass::idle()
{writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
}
两种调制方式
- LoRa
呼~写累啦,下一篇再具体介绍LoRa调制的具体方式
加油!ヾ(◍°∇°◍)ノ゙