LoRa协议在Arduino上的应用——原理及代码分析(一)

Halona ·
更新时间:2024-09-21
· 884 次阅读

目录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 reset pinMode(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 pins pinMode(_ss, OUTPUT); // set SS high digitalWrite(_ss, HIGH); if (_reset != -1) { pinMode(_reset, OUTPUT); // perform reset digitalWrite(_reset, LOW); delay(10); digitalWrite(_reset, HIGH); delay(10); } // start SPI _spi->begin(); // check version uint8_t version = readRegister(REG_VERSION); if (version != 0x12) { return 0; } // put in sleep mode sleep(); // set frequency setFrequency(frequency); // set base addresses writeRegister(REG_FIFO_TX_BASE_ADDR, 0); writeRegister(REG_FIFO_RX_BASE_ADDR, 0); // set LNA boost writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03); // set auto AGC writeRegister(REG_MODEM_CONFIG_3, 0x04); // set output power to 17 dBm setTxPower(17); // put in standby mode idle(); 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 <> 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) { // RFO if (level 14) { level = 14; } writeRegister(REG_PA_CONFIG, 0x70 | level); } else { // PA BOOST if (level > 17) { if (level > 20) { level = 20; } // subtract 3 from level, so 18 - 20 maps to 15 - 17 level -= 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 +17dBm writeRegister(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调制的具体方式
加油!ヾ(◍°∇°◍)ノ゙
作者:球球今天也要加油鸭



lora 代码分析 arduino

需要 登录 后方可回复, 如果你还没有账号请 注册新账号