LoRaWAN 网关的代码实现与解析
硬件准备
- 单通道网关硬件通常基于树莓派+LoRa模块(如SX1276/SX1278)或专用网关板(如RAK831)。
- 软件依赖:
wiringPi(GPIO控制)、lora_gateway(基础驱动)、post-processing(数据包处理)。
关键代码模块
- GPIO与射频初始化
// SX1278 初始化示例(SPI通信)
int sx1278_init() {
wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, HIGH);
delay(100);
// 设置LoRa模式、频率(如868MHz)
write_reg(REG_OP_MODE, MODE_LORA | MODE_SLEEP);
write_reg(REG_FRF_MSB, 0xD9); // 868.1 MHz
}
- 数据包接收处理
void receive_packet() {
while (digitalRead(DIO0_PIN) == LOW); // 等待中断
uint8_t payload[256];
size_t len = read_reg(REG_RX_NB_BYTES);
spi_read(REG_FIFO, payload, len);
// 转发到服务器(如通过MQTT)
mqtt_publish("gateway/uplink", payload, len);
}
- 下行链路发送
void send_downlink(uint8_t *data, size_t len) {
write_reg(REG_OP_MODE, MODE_LORA | MODE_STDBY);
write_reg(REG_FIFO_ADDR_PTR, 0x00);
spi_write(REG_FIFO, data, len);
write_reg(REG_OP_MODE, MODE_LORA | MODE_TX);
}
STM32L072+SX1262 节点代码实现
硬件连接
- STM32L072通过SPI连接SX1262,DIO1用于中断,NRESET为硬件复位。
关键步骤
- SX1262 初始化
void SX1262_Init() {
HAL_GPIO_WritePin(NRESET_GPIO_Port, NRESET_Pin, GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(NRESET_GPIO_Port, NRESET_Pin, GPIO_PIN_SET);
// 设置LoRa参数
SX1262_WriteCommand(RADIO_SET_PACKETTYPE, 0x01); // LoRa模式
SX1262_WriteRegister(REG_LR_SYNCWORD, 0x34); // LoRaWAN SyncWord
}
- 发送数据(OTAA入网)
void send_join_request() {
uint8_t devEui[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t joinEui[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t appKey[16] = {...};
// 构造JoinRequest
lorawan_mac_join_request(devEui, joinEui, appKey, buffer);
SX1262_SendBuffer(buffer, 23); // 发送23字节JoinRequest
}
- 接收下行数据
void handle_rx() {
if (HAL_GPIO_ReadPin(DIO1_GPIO_Port, DIO1_Pin)) {
uint8_t rx_len = SX1262_ReadRegister(REG_RX_PAYLOAD_LENGTH);
SX1262_ReadBuffer(rx_buffer, rx_len);
// 处理MAC命令(如JoinAccept)
lorawan_process_downlink(rx_buffer, rx_len);
}
}
LoRaWAN 网络搭建步骤
服务器配置
- 安装
ChirpStack或TTN服务器:
# ChirpStack 安装示例
docker-compose up -d postgresql redis chirpstack
- 配置网关:
- 在服务器界面添加网关,填写Gateway EUI(如从硬件读取)。
- 设置网关频率计划(如EU868)。
节点注册
- 创建应用(Application)并添加设备(Device)。
- 选择激活模式(OTAA或ABP),填写DevEUI、AppKey等参数。
频率与法律合规
- 根据地区选择频段(如CN470、EU868),需遵守当地无线电法规。
调试与优化
网关调试
- 使用
tcpdump监控网关与服务器的通信:
sudo tcpdump -i eth0 port 1700 -vv
节点功耗优化
- 配置STM32低功耗模式(STOP模式),SX1262进入休眠:
SX1262_WriteCommand(RADIO_SET_SLEEP, 0x01);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
通信可靠性
- 调整SX1262的发射功率(REG_PA_CONFIG)和扩频因子(SF)。
- 启用ADR(自适应速率)功能:
uint8_t adr_enable = 1;
lorawan_mac_command(LINK_ADR_REQ, &adr_enable, 1);
移植LoRaWAN节点代码到CH583芯片(基于RISC-V架构)需要结合CH583的硬件特性和LoRaWAN协议栈进行适配。以下是详细的移植步骤和关键代码实现:
硬件驱动层移植
SPI驱动适配
CH583的SPI控制器需配置为与LoRa射频模块(如SX1276/SX1262)通信。以下为SPI初始化代码示例:
void SPI_Init(void) {
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // 启用SPI1时钟
GPIO_Init(GPIOA, GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, GPIO_Mode_AF_PP); // SCK/MOSI/MISO
SPI1->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR; // 主模式,软件NSS
SPI1->CR1 |= SPI_CR1_SPE; // 使能SPI
}
射频模块控制引脚
需实现Reset、NSS、DIO0等引脚的控制:
#define RF_NSS_PIN GPIO_Pin_4
#define RF_RESET_PIN GPIO_Pin_3
void RF_GPIO_Init(void) {
GPIO_Init(GPIOB, RF_NSS_PIN, GPIO_Mode_Out_PP); // NSS引脚
GPIO_Init(GPIOA, RF_RESET_PIN, GPIO_Mode_Out_PP); // Reset引脚
GPIO_SetBits(GPIOB, RF_NSS_PIN); // 初始置高
}
定时器适配
LoRaWAN协议栈依赖精确计时
CH583的定时器需配置为毫秒级 tick:
void Timer_Init(void) {
SysTick_Config(SystemCoreClock / 1000); // 1ms中断
}
uint32_t HAL_GetTick(void) {
return systick_counter; // 全局变量记录tick
}
协议栈移植
Radio接口实现
需重写LoRaMAC层的Radio接口函数:
RadioEvents_t RadioEvents;
void Radio_Init(void) {
RadioEvents.TxDone = OnTxDone;
Radio.Init(&RadioEvents);
}
void OnTxDone(void) {
LoRaMacMcpsConfirm(); // 通知协议栈发送完成
}
低功耗管理
CH583支持低功耗模式,需适配LoRaWAN的休眠逻辑:
void BoardLowPowerHandler(void) {
__WFI(); // 进入待机模式
}
示例主循环
任务调度与事件处理
主循环需整合协议栈任务和硬件事件:
int main(void) {
HardwareInit();
LoRaMacInitialization();
while(1) {
LoRaMacProcess(); // 处理协议栈任务
HandleRadioIrq(); // 处理射频中断
if (IsJoinRequestNeeded()) {
LoRaMacMcpsRequest(&join_request);
}
}
}
注意事项
-
时钟配置
CH583需配置外部高速时钟(HSE)以确保SPI和定时器精度。 -
中断优先级
射频模块的DIO0中断需设置为较高优先级,避免丢包。 -
内存管理
LoRaWAN协议栈可能动态分配内存,需检查CH583的堆空间是否充足。 -
认证与加密
确保加密算法(如AES)在RISC-V架构上的运行效率,必要时使用硬件加速。
完整代码需结合具体LoRaWAN协议栈(如Semtech或LoRaMAC-node)的API实现。移植后需通过OTAA或ABP入网测试验证功能。
LoRaWAN 单通道网关架构概述
基于 CH583 MCU 和 SX1262 LoRa模块 的LoRaWAN单通道网关架构采用简化设计,适合低功耗、低成本场景。网关通过单频点接收节点数据,并通过以太网/WiFi转发至LoRaWAN服务器(如ChirpStack)。节点采用ABP(激活By Personalization)模式入网,直接与网关通信。
网关端实现
硬件连接
- SX1262 与 CH583 通过SPI通信,引脚配置如下:
SCK: GPIO_PIN_13MISO: GPIO_PIN_14MOSI: GPIO_PIN_15NSS: GPIO_PIN_16RESET: GPIO_PIN_17BUSY: GPIO_PIN_18
代码实现(基于Arduino库适配)
#include <SPI.h>
#include <LoRa.h> // 需适配SX1262驱动
#define LORA_FREQ 868000000 // 欧洲频段
void setup() {
Serial.begin(115200);
SPI.begin();
LoRa.setPins(16, 17, 18); // NSS, RESET, BUSY
if (!LoRa.begin(LORA_FREQ)) {
Serial.println("LoRa init failed!");
while (1);
}
LoRa.setSpreadingFactor(7); // SF7
LoRa.enableCrc();
}
void loop() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
char packet[256];
int i = 0;
while (LoRa.available()) {
packet[i++] = (char)LoRa.read();
}
packet[i] = '\0';
Serial.println("Received: " + String(packet));
// 转发至服务器(伪代码)
sendToServer(packet);
}
}
服务器通信
网关通过HTTP/MQTT将数据转发至LoRaWAN服务器。示例使用HTTP POST:
void sendToServer(String data) {
WiFiClient client;
HTTPClient http;
http.begin(client, "http://chirpstack.example.com/api/gateways/upload");
http.addHeader("Content-Type", "application/json");
String json = "{\"data\":\"" + data + "\"}";
int code = http.POST(json);
http.end();
}
节点端实现
硬件连接
节点硬件与网关类似,需额外配置 ABP参数(DevAddr/NwkSKey/AppSKey)。
代码实现
#include <LoRa.h>
// ABP参数
const uint32_t devAddr = 0x260BABCD;
const uint8_t nwkSKey[16] = {0x01, 0x02, ...};
const uint8_t appSKey[16] = {0x01, 0x02, ...};
void setup() {
LoRa.setPins(16, 17, 18);
if (!LoRa.begin(868E6)) {
Serial.println("LoRa init failed!");
while (1);
}
LoRa.setTxPower(20);
}
void loop() {
String message = "Hello, Gateway!";
LoRa.beginPacket();
LoRa.write((uint8_t*)&devAddr, 4); // 添加DevAddr
LoRa.print(message);
LoRa.endPacket();
delay(5000);
}
数据加密
节点需使用 LoRaMAC-Node 库实现完整LoRaWAN协议栈。关键加密函数:
void encryptPayload(uint8_t* payload, uint8_t size) {
AES_CMAC(nwkSKey, payload, size, encryptedPayload);
}
调试与优化
- 频谱扫描:使用
LoRa.scanNetworks()确认频段无冲突。 - 功耗测试:节点进入低功耗模式(
LoRa.sleep()),CH583配置为休眠模式。 - 服务器对接:验证ChirpStack的Gateway Profile配置为单通道模式。
注意事项
- 单通道网关仅支持 单一频点,需与服务器频段配置一致。
- ABP模式需手动管理 帧计数器(FCnt),避免重复攻击。
- 实际部署需通过 MIC校验(Message Integrity Code)确保数据安全。

被折叠的 条评论
为什么被折叠?



