蓝桥杯物联网设计与开发基础模块7-Lora

目录

一、Lora

(1)资源介绍

        🔅Lora 特点:

       🔅SX1278 介绍:

        🔅SX1278 工作方式:

        🔅原理图:

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

二、踩坑日记

(1)引脚配置


一、Lora

(1)资源介绍

        Lora 是属于线性调制扩频技术的一种,用于创建长距离通信连接的物理层无线调制技术,它在保留传统无线系统所使用的频移键控(FSK)调制的低功耗特性的基础上,增加了通信的距离。Lora 扩频技术就是通过注入一个更高频信号将基带信号扩展到更宽的频带,使得其传输信息所用信号的带宽远大于信息本身的带宽。

        🔅Lora 特点:

  1. 传输距离远:2km ~ 20km,速度越低,传输距离越长;
  2. 低功耗:解决功耗于传输距离难覆盖的问题;
  3. 成本低:具有容量大的特点,可以节省模块及布线成本;
  4. 灵敏度高:在相同数据速率下,它的扩频调制技术的灵敏度比传统的频移键控(FSK)调制方式高 8 ~ 10dB
  5. 调制方式先进:基于扩频技术,采用直接序列扩频,具有前向纠错(FEC)的能力;
  6. 抗干扰能力强:对于同频干扰及各种噪声的干扰具有较强的抑制能力;
  7. 发射功率密度低:不易对其它设备造成干扰;
  8. 保密性高:被截获的可能性极低,采用 AES128 加密;
  9. 具有极好的抗多径衰落和多普勒效应性能:在城市中多径效应很明显,信号会因为多径叠加导致严重失真,移动的物体会带来多普勒效应,对无线接收端带来了很大的挑战,而 Lora 通信就能很好的克服这两点;

       🔅SX1278 介绍:

        物联网竞赛实训平台上继承了一个 SPI 接口的 Lora 模块,收发器型号为 SX1278SX1278 是一个半双工传输的低中频收发器,由射频前端(包括低噪声放大器 LNA 和功率放大器 PA 等)、上下变频、Lora FSK / OOK 调制解调器,数据 FIFO、寄存器和 SPI 接口等部分组成;

        SX1278 收发数据前,需要通过 SPI 接口对寄存器进行配置。寄存器在任何模式下都可以读,但仅在睡眠和待机模式下可写:

  • 发送数据时,通过 SPI 接口将发送数据写到数据 FIFO,由调制器调制再上变频,并由功率放大器放大后进行发送;
  • 接收数据时,接收数据由低噪声放大器放大再下变频,并由解调器解调后送入数据 FIFO,再通过 SPI 接口读取;
  •         🔅SX1278 工作方式:

            Lora 的初始化包括设置 Lora 模式(必须在睡眠模式下设置)、设置射频频率和功率、设置扩频因子、信号带宽和纠错编码率等。除了必须设置 Lora 模式和射频功率外,其它设置都可以省略(使用默认值);

            Lora 数据 FIFO 256 字节可完全由用户定制,用于发送或接收数据。除睡眠模式外,其它模式下均可读写,在切换到新的接收模式时,自动清除旧内容;

    图1        Lora 数据缓冲(图来自数据手册)

            🔅原理图

    图2        原理图

            查看局部射频收发模块原理图可知,MCU SX1278 通过引脚 PA5PA6PA7PA4 进行数据交互传输,而这四个引脚的第二功能为 MCU 的硬件 SPI1SX1278 复位引脚 NRESET(复位触发输入,低电平有效)与 PA9 相连接,数字 IO 引脚 DIO0 引脚与 PA10 相连接;

    图3        射频收发模块

    (2)STM32CubeMX 软件配置

    🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在下文中有讲解,这里不再赘述❗️

    【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出https://blog.csdn.net/m0_63116406/article/details/135604705?spm=1001.2014.3001.5502

    1️⃣点击引脚 PC15 → 选择 GPIO_Output 模式(此处默认为推挽输出);

    图4        LED 引脚配置

    2️⃣点击 "GPIO" → 点击引脚 PC15 → 将 "GPIO output level" 栏修改为 "High",即将 PC15 引脚初始化为高电平;

    ⚠️此处修改不是必须的,应当根据题意要求进行配置,这里默认为上电熄灭;

    图5        修改 PC15 初始化电平

    3️⃣点击左侧 "Connectivity" → 选择 "SPI1"  → 模式选择 "Full-Duplex Master" (全双工主机模式),不使能 "Hardware NSS Signal"(硬件片选信号);

    图6        使能 SPI1

    4️⃣点击引脚 PA4 → 选择 GPIO_Output 模式;

    图7        配置引脚 PA4

    5️⃣点击引脚 PA9 → 选择 GPIO_Output 模式;

    图8        配置引脚 PA9

    6️⃣点击引脚 PA10 → 选择 GPIO_Input 模式;

    图9        配置引脚 PA10

    7️⃣生成代码即可;

    8️⃣将赛点资源数据包中的参考代码:"lora.h""lora.c"添加到工程;

    图10        添加 Lora 驱动文件

    (3)代码编写

    🟡️MX_SPI1_Init 函数代码补全

    void MX_SPI1_Init(void)
    {
    
      /* USER CODE BEGIN SPI1_Init 0 */
    
      /* USER CODE END SPI1_Init 0 */
    
      /* USER CODE BEGIN SPI1_Init 1 */
    
      /* USER CODE END SPI1_Init 1 */
      hspi1.Instance = SPI1;
      hspi1.Init.Mode = SPI_MODE_MASTER;
      hspi1.Init.Direction = SPI_DIRECTION_2LINES;
      hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi1.Init.NSS = SPI_NSS_SOFT;
      hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
      hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi1.Init.CRCPolynomial = 7;
      if (HAL_SPI_Init(&hspi1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN SPI1_Init 2 */
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);	// 拉高 PA4,取消片选
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);	// 拉高 PA9,防止触发收发模块复位
      /* USER CODE END SPI1_Init 2 */
    
    }

    🟡️SPI_WriteRead 函数代码实现

    unsigned char SPI_WriteRead(unsigned char ucAddr, unsigned char ucData)
    {
    	uint8_t pTxData[2], pRxData[2];
    	pTxData[0] = ucAddr;
    	pTxData[1] = ucData;
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);	// 片选收发模块
    	HAL_SPI_TransmitReceive(&hspi1, pTxData, pRxData, 2, 10); // SPI 发送接收
    	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);		// 取消片选
    	return pRxData[1];
    }

    🟢️NODE_A main 函数

    /* USER CODE BEGIN Includes */
    #include "lora.h"
    #include "string.h"
    /* USER CODE END Includes */
    
    /* USER CODE BEGIN PV */
    uint8_t puc_lora[10];
    /* USER CODE END PV */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_SPI1_Init();
      /* USER CODE BEGIN 2 */
    	LORA_Init();	// 初始化 Lora 模块
    	puc_lora[0] = '*';
    	puc_lora[1] = 'A';
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    		LORA_Tx(puc_lora, 2);	// 发送字符串
    		HAL_Delay(1000);        // 间隔 1s
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }

    🟢️NODE_B main 函数

    /* USER CODE BEGIN Includes */
    #include "lora.h"
    #include "string.h"
    /* USER CODE END Includes */
    
    /* USER CODE BEGIN PV */
    uint8_t puc_lora[10];
    /* USER CODE END PV */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_SPI1_Init();
      /* USER CODE BEGIN 2 */
    	LORA_Init();	// 初始化 Lora 模块
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
    		if(LORA_Rx(puc_lora) == 2)	// Lora 接收
    		{
    			if(strcmp((char *)puc_lora, "*A") == 0)	// 比较字符串
    			{
    				HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);	// 翻转 LED 电平
    			}
    		}
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }

    (4)实验现象

            节点 B,每间隔 1sLED 电平翻转一次;


    二、踩坑日记

    (1)引脚配置

  • 配置片选引脚 PA4,否则 SPI 无法正常工作;
  • 配置发送引脚 PA9,并在初始化时配置为高电平,否则会触发收发模块的复位功能;配置接收引脚 PA10
  • 作者:逝灮

    物联沃分享整理
    物联沃-IOTWORD物联网 » 蓝桥杯物联网设计与开发基础模块7-Lora

    发表评论