STM32F1与LoRa通信:TX与RX收发实现指南

一、技术背景与核心价值

LoRa(Long Range)作为低功耗广域网(LPWAN)的核心技术,凭借其远距离传输(可达15公里)、低功耗(μA级待机电流)和抗干扰能力,广泛应用于物联网场景。结合STM32F1系列微控制器(基于ARM Cortex-M3内核,主频72MHz,成本低、资源丰富),开发者可快速构建高性价比的无线通信节点。本文聚焦STM32F1与LoRa模块的硬件连接、寄存器配置及通信流程,为工业监控、环境监测等场景提供可复用的技术方案。

二、硬件连接与关键参数配置

1. 接口与引脚定义

LoRa模块通常通过SPI接口与STM32F1通信,需连接以下引脚:

  • SCK:SPI时钟(如PA5)
  • MISO:主入从出数据(如PA6)
  • MOSI:主出从入数据(如PA7)
  • NSS:片选信号(如PA4,低电平激活)
  • RESET:复位引脚(如PB0)
  • DIO0:中断引脚(用于接收完成通知,如PB1)

示例配置

  1. // GPIO初始化(以PA4-NSS为例)
  2. GPIO_InitTypeDef GPIO_InitStruct = {0};
  3. __HAL_RCC_GPIOA_CLK_ENABLE();
  4. GPIO_InitStruct.Pin = GPIO_PIN_4;
  5. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  6. GPIO_InitStruct.Pull = GPIO_NOPULL;
  7. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  8. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

2. SPI参数配置

LoRa模块通常要求SPI模式0(CPOL=0, CPHA=0),时钟频率不超过10MHz。配置步骤如下:

  1. // SPI初始化(以SPI1为例)
  2. hspi1.Instance = SPI1;
  3. hspi1.Init.Mode = SPI_MODE_MASTER;
  4. hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  5. hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  6. hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  7. hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  8. hspi1.Init.NSS = SPI_NSS_SOFT;
  9. hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; // 约4.5MHz(72MHz/16)
  10. hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  11. hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  12. hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  13. HAL_SPI_Init(&hspi1);

三、LoRa模块寄存器配置

1. 工作模式设置

通过写入寄存器RegOpMode(地址0x01)配置模块为发送或接收模式:

  1. #define REG_OP_MODE 0x01
  2. void SetLoRaMode(uint8_t mode) {
  3. uint8_t reg_val;
  4. HAL_SPI_Receive(&hspi1, &reg_val, 1, HAL_MAX_DELAY); // 读取当前值
  5. reg_val = (reg_val & 0x7F) | (mode << 7); // 保留低7位,设置Mode位
  6. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 激活NSS
  7. HAL_SPI_Transmit(&hspi1, &REG_OP_MODE, 1, HAL_MAX_DELAY);
  8. HAL_SPI_Transmit(&hspi1, &reg_val, 1, HAL_MAX_DELAY);
  9. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // 释放NSS
  10. }
  11. // 模式定义:0x00=睡眠,0x01=待机,0x03=发送,0x05=接收

2. 关键参数配置

  • 频率设置:通过RegFrfMsb/Mid/Lsb(地址0x06-0x08)配置中心频率(如433MHz):
    1. #define FREQ_433MHZ 0x6C8000 // 433MHz对应值
    2. void SetFrequency(uint32_t freq) {
    3. uint8_t data[3];
    4. data[0] = (freq >> 16) & 0xFF;
    5. data[1] = (freq >> 8) & 0xFF;
    6. data[2] = freq & 0xFF;
    7. // 写入寄存器(需分三次传输)
    8. }
  • 扩频因子(SF):通过RegModemConfig1(地址0x1D)设置(7-12):
    1. #define REG_MODEM_CONFIG1 0x1D
    2. void SetSpreadingFactor(uint8_t sf) {
    3. uint8_t reg_val;
    4. HAL_SPI_Receive(&hspi1, &reg_val, 1, HAL_MAX_DELAY);
    5. reg_val = (reg_val & 0x0F) | ((sf - 7) << 4); // 保留低4位
    6. // 写入寄存器(同上)
    7. }

四、发送与接收流程实现

1. 数据发送(TX)

步骤:配置为发送模式→写入数据→等待完成→切换回待机模式。

  1. #define REG_FIFO 0x00
  2. void LoRa_TX(uint8_t *data, uint8_t length) {
  3. SetLoRaMode(0x03); // 发送模式
  4. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  5. HAL_SPI_Transmit(&hspi1, &REG_FIFO, 1, HAL_MAX_DELAY); // 指向FIFO
  6. for (uint8_t i = 0; i < length; i++) {
  7. HAL_SPI_Transmit(&hspi1, &data[i], 1, HAL_MAX_DELAY);
  8. }
  9. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  10. // 等待DIO0引脚置高(需外部中断或轮询)
  11. while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == GPIO_PIN_RESET);
  12. SetLoRaMode(0x01); // 切换回待机模式
  13. }

2. 数据接收(RX)

步骤:配置为连续接收模式→等待DIO0中断→读取FIFO数据。

  1. void LoRa_RX(uint8_t *buffer, uint8_t *length) {
  2. SetLoRaMode(0x05); // 接收模式
  3. // 等待DIO0中断(需配置外部中断)
  4. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
  5. while (1) {
  6. if (__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_1)) {
  7. uint8_t fifo_ptr;
  8. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  9. HAL_SPI_Transmit(&hspi1, &REG_FIFO_RX_CURRENT_ADDR, 1, HAL_MAX_DELAY);
  10. HAL_SPI_Receive(&hspi1, &fifo_ptr, 1, HAL_MAX_DELAY);
  11. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  12. // 读取FIFO数据(需先获取数据长度)
  13. *length = GetRxPacketLength(); // 自定义函数
  14. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  15. HAL_SPI_Transmit(&hspi1, &REG_FIFO, 1, HAL_MAX_DELAY);
  16. HAL_SPI_Receive(&hspi1, buffer, *length, HAL_MAX_DELAY);
  17. HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  18. break;
  19. }
  20. }
  21. SetLoRaMode(0x01); // 切换回待机模式
  22. }

五、优化建议与注意事项

  1. 功耗优化:在空闲时将模块切换至睡眠模式(SetLoRaMode(0x00)),并通过RTC定时唤醒。
  2. 抗干扰设计:动态调整信道(通过RegFrfMsb/Mid/Lsb)或扩频因子(SF7→SF12)以避开干扰频段。
  3. 数据完整性:启用CRC校验(RegModemConfig20x04位)并实现重传机制。
  4. 调试技巧:使用逻辑分析仪捕获SPI波形,验证寄存器写入是否正确;通过串口打印调试信息。

六、典型应用场景

  1. 环境监测:STM32F1采集温湿度数据,通过LoRa发送至网关。
  2. 工业控制:远程控制设备开关,接收设备状态反馈。
  3. 农业物联网:土壤湿度传感器数据上报,支持大规模节点部署。

通过本文的配置与代码示例,开发者可快速实现STM32F1与LoRa模块的稳定通信,为低功耗广域网应用提供可靠的技术支撑。