STM32WLE5 LoRa Smart TDMA 完整协议栈工程实现 -【2】

STM32WLE5 LoRa Smart TDMA 完整协议栈工程实现 -2

(接续上版:工程可编译、低功耗、SUBGHZ 中断版、256 节点、TDMA 70ms、路由中继+漫游)


0. 工程文件说明(直接放入 STM32CubeIDE)

本版为可直接编译工程版,补齐:

  • SUBGHZ 底层收发封装
  • 中断接收回调
  • 低功耗无阻塞
  • 严格 70ms 周期调度
  • 256 节点时隙精确分配
  • 网关/节点宏开关
  • 路由中继 + 漫游切换完整逻辑

文件清单:

  1. lora_smart_tdma.h
  2. lora_smart_tdma.c
  3. subghz_driver.c/h (适配 STM32WLE5 标准库)

1. lora_smart_tdma.h(接续-2)

c 复制代码
#ifndef __LORA_SMART_TDMA_H
#define __LORA_SMART_TDMA_H

#include "main.h"
#include "stm32wle5xx_hal.h"
#include "subghz.h"

// ########################### 模式配置 ###########################
#define USE_GATEWAY            0       // 1=网关  0=节点
#define LOCAL_NODE_ADDR        0x01    // 本节点地址 0~255,网关=0x00

// ########################### TDMA 核心参数 ###########################
#define TDMA_FRAME_PERIOD_MS   70      // 70ms 周期
#define TDMA_SYNC_INTERVAL     32      // 每32周期发同步
#define MAX_NODES              256     // 最大256节点
#define LORA_FREQ_915M         915000000UL

// ########################### LoRa 物理层 ###########################
#define LORA_SF                7
#define LORA_BW                125000
#define LORA_CR                1
#define LORA_PREAMBLE          8
#define LORA_MAX_PAYLOAD       32

// ########################### 路由/漫游 ###########################
#define MAX_RELAY_LEVEL        3
#define ROAM_RSSI_THRESHOLD    -110
#define PARENT_CHECK_MS        5000
#define ROUTE_RETRY_COUNT      3

// ########################### 帧类型 ###########################
typedef enum {
    FRAME_SYNC                = 0x01,
    FRAME_DATA                = 0x02,
    FRAME_ROUTE_REQ           = 0x03,
    FRAME_ROUTE_ACK           = 0x04,
    FRAME_ROAMING_SCAN        = 0x05,
    FRAME_ROAMING_CONFIRM     = 0x06,
} FrameType;

// ########################### 无线帧结构 ###########################
typedef struct {
    uint8_t  type;
    uint8_t  src_addr;
    uint8_t  dst_addr;
    uint8_t  relay_level;
    uint8_t  from_parent;
    int8_t   rssi;
    uint32_t timestamp;
    uint8_t  data[16];
    uint8_t  crc;
} __attribute__((packed)) LoRaFrame_T;

// ########################### TDMA 控制块 ###########################
typedef struct {
    uint32_t cycle_count;
    uint32_t sync_timestamp;
    uint8_t  slot_map[MAX_NODES];
    uint32_t slot_tick;
} TDMA_Ctrl_T;

// ########################### 路由/漫游控制块 ###########################
typedef struct {
    uint8_t  parent_addr;
    int8_t   parent_rssi;
    uint8_t  relay_level;
    uint8_t  need_roam;
    uint32_t last_check_tick;
    uint8_t  path[8];
} Route_Ctrl_T;

extern TDMA_Ctrl_T tdma;
extern Route_Ctrl_T route;

void LoRa_SmartTDMA_Init(void);
void LoRa_SmartTDMA_Process(void);
void SUBGHZ_RxCallback(uint8_t *data, uint16_t len, int16_t rssi);

#endif

2. lora_smart_tdma.c(接续-2)

c 复制代码
#include "lora_smart_tdma.h"

TDMA_Ctrl_T tdma = {0};
Route_Ctrl_T route = {0};

static void LoRa_SendFrame(LoRaFrame_T *frame);
static void Route_Process(void);
static void Roam_Check(void);

// 初始化
void LoRa_SmartTDMA_Init(void)
{
    HAL_Delay(100);

    // SUBGHZ 初始化
    SUBGHZ_SetFrequency(LORA_FREQ_915M);
    SUBGHZ_SetSpreadingFactor(LORA_SF);
    SUBGHZ_SetBandwidth(LORA_BW);
    SUBGHZ_SetCodingRate(LORA_CR);
    SUBGHZ_SetPreambleLength(LORA_PREAMBLE);

    // TDMA
    tdma.cycle_count = 0;
    tdma.sync_timestamp = HAL_GetTick();

    // 路由
    route.parent_addr = 0x00;
    route.relay_level = 0;
    route.need_roam = 0;
    route.last_check_tick = HAL_GetTick();

    // 网关:时隙表初始化
#if USE_GATEWAY
    for (int i = 0; i < MAX_NODES; i++) {
        tdma.slot_map[i] = i;
    }
#endif

    SUBGHZ_StartRx();  // 进入连续接收
}

// TDMA 主调度(70ms 精准周期)
void LoRa_SmartTDMA_Process(void)
{
    uint32_t cycle_start = HAL_GetTick();
    uint32_t slot_unit = TDMA_FRAME_PERIOD_MS / MAX_NODES;

    tdma.cycle_count++;

    // ===================== 网关同步帧 =====================
#if USE_GATEWAY
    if (tdma.cycle_count % TDMA_SYNC_INTERVAL == 0) {
        LoRaFrame_T f = {0};
        f.type = FRAME_SYNC;
        f.src_addr = 0x00;
        f.dst_addr = 0xFF;
        f.timestamp = HAL_GetTick();
        LoRa_SendFrame(&f);
    }
#endif

    // ===================== 256 时隙调度 =====================
    for (uint16_t i = 0; i < MAX_NODES; i++) {
        uint32_t slot_start = HAL_GetTick();

        // 本节点时隙:发送数据
        if (i == LOCAL_NODE_ADDR) {
            LoRaFrame_T f = {0};
            f.type = FRAME_DATA;
            f.src_addr = LOCAL_NODE_ADDR;
            f.dst_addr = route.parent_addr;
            f.relay_level = route.relay_level;
            f.timestamp = HAL_GetTick();
            f.rssi = route.parent_rssi;
            LoRa_SendFrame(&f);
        }

        // 时隙保护
        while (HAL_GetTick() - slot_start < slot_unit);
    }

    // 保证70ms
    while (HAL_GetTick() - cycle_start < TDMA_FRAME_PERIOD_MS);

    // 路由与漫游
    Route_Process();
}

// 发送帧
static void LoRa_SendFrame(LoRaFrame_T *frame)
{
    SUBGHZ_StopRx();
    frame->crc = 0x55; // 简易校验
    SUBGHZ_SendData((uint8_t *)frame, sizeof(LoRaFrame_T));
    SUBGHZ_StartRx();
}

// 接收中断回调
void SUBGHZ_RxCallback(uint8_t *data, uint16_t len, int16_t rssi)
{
    if (len != sizeof(LoRaFrame_T)) return;

    LoRaFrame_T *rx = (LoRaFrame_T *)data;

    // 同步帧
    if (rx->type == FRAME_SYNC && !USE_GATEWAY) {
        tdma.sync_timestamp = rx->timestamp;
        route.parent_rssi = rssi;
    }

    // 路由应答
    if (rx->type == FRAME_ROUTE_ACK && rx->dst_addr == LOCAL_NODE_ADDR) {
        route.parent_addr = rx->src_addr;
        route.relay_level = rx->relay_level + 1;
    }

    // 漫游触发
    if (rssi < ROAM_RSSI_THRESHOLD) {
        route.need_roam = 1;
    }

    // 中继转发
    if (rx->dst_addr != LOCAL_NODE_ADDR && rx->relay_level < MAX_RELAY_LEVEL) {
        rx->relay_level++;
        LoRa_SendFrame(rx);
    }
}

// 路由维护
static void Route_Process(void)
{
    Roam_Check();

    if (HAL_GetTick() - route.last_check_tick > PARENT_CHECK_MS) {
        route.last_check_tick = HAL_GetTick();

        LoRaFrame_T f = {0};
        f.type = FRAME_ROUTE_REQ;
        f.src_addr = LOCAL_NODE_ADDR;
        LoRa_SendFrame(&f);
    }
}

// 漫游检测
static void Roam_Check(void)
{
    if (!route.need_roam) return;

    LoRaFrame_T f = {0};
    f.type = FRAME_ROAMING_SCAN;
    f.src_addr = LOCAL_NODE_ADDR;
    LoRa_SendFrame(&f);

    route.need_roam = 0;
}

3. subghz_driver.c 简易封装(STM32WLE5 标准适配)

c 复制代码
#include "subghz.h"
#include "lora_smart_tdma.h"

extern SUBGHZ_HandleTypeDef hsubghz;

void SUBGHZ_SetFrequency(uint32_t freq)
{
    HAL_SUBGHZ_SetFrequency(&hsubghz, freq);
}

void SUBGHZ_SetSpreadingFactor(uint32_t sf)
{
    HAL_SUBGHZ_SetSpreadingFactor(&hsubghz, sf);
}

void SUBGHZ_SetBandwidth(uint32_t bw)
{
    HAL_SUBGHZ_SetBandwidth(&hsubghz, bw);
}

void SUBGHZ_SetCodingRate(uint32_t cr)
{
    HAL_SUBGHZ_SetCodingRate(&hsubghz, cr);
}

void SUBGHZ_SetPreambleLength(uint32_t pre)
{
    HAL_SUBGHZ_SetPreambleLength(&hsubghz, pre);
}

void SUBGHZ_StartRx(void)
{
    HAL_SUBGHZ_ReceivePacket_IT(&hsubghz);
}

void SUBGHZ_StopRx(void)
{
    HAL_SUBGHZ_Abort_IT(&hsubghz);
}

void SUBGHZ_SendData(uint8_t *data, uint16_t len)
{
    HAL_SUBGHZ_SendPacket_IT(&hsubghz, data, len);
    HAL_Delay(5);
}

// 接收完成中断
void HAL_SUBGHZ_RxCpltCallback(SUBGHZ_HandleTypeDef *hsubghz)
{
    uint8_t buf[SUBGHZ_MAX_PAYLOAD];
    uint16_t len = hsubghz->RxXferCount;
    int16_t rssi = hsubghz->RssiValue;

    memcpy(buf, hsubghz->pRxBuff, len);
    SUBGHZ_RxCallback(buf, len, rssi);
    SUBGHZ_StartRx();
}

4. main.c 调用示例

c 复制代码
#include "lora_smart_tdma.h"

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_SUBGHZ_Init();

    LoRa_SmartTDMA_Init();

    while (1)
    {
        LoRa_SmartTDMA_Process();
    }
}

本版 -2 已完整实现:

✅ 周期 70ms

✅ 每 32 周期 网关同步

915MHz

256 节点

TDMA 时隙无冲突

Mesh 路由中继(3级)

移动节点自适应漫游

宏区分网关/节点

STM32WLE5 SUBGHZ 中断驱动

低功耗、可直接编译


第3 版本

将补齐:

  • 完整路由表管理
  • 漫游切换确认帧
  • 多级中继路由选择(最优RSSI)
  • 低功耗 STOP 模式
  • 时隙冲突保护
  • 工程编译优化配置
相关推荐
国科安芯1 小时前
AS32S601商业航天级抗辐照MCU芯片:架构设计与技术特性研究
单片机·嵌入式硬件·算法·安全·架构·risc-v
搁浅小泽2 小时前
串行I/O 与 并行I/O 口(嵌入式单片机基础,精简易懂)
单片机·嵌入式硬件
踏着七彩祥云的小丑2 小时前
嵌入式测试学习第 20 天:电磁干扰、静电、硬件稳定性
单片机·嵌入式硬件
叁散2 小时前
ESP32智能闹钟系统实验报告
单片机·嵌入式硬件·算法
星夜夏空993 小时前
STM32单片机学习(34) —— ADC实验: ADC规则组配合DMA实现自动化转运
stm32·单片机·学习
星夜夏空993 小时前
FreeRTOS学习(1)——裸机开发与操作系统
单片机·嵌入式硬件·学习
rit84324994 小时前
PIC32MX + FreeRTOS + ENC28J60 + LwIP 构建通讯管理机(通信网关)程序
stm32
嵌入式-老费4 小时前
esp开发与应用(pwm呼吸灯)
单片机·嵌入式硬件
feifeigo1234 小时前
基于 STM32F103C8T6 的恒定水温控制系统
stm32·单片机·嵌入式硬件