当前位置: 首页 > news >正文

第九章:LORA

1.理论部分

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

1.LORA特点

传输距离远:2km ~ 20km,速度越低,传输距离越长;

低功耗:解决功耗于传输距离难覆盖的问题;

成本低:具有容量大的特点,可以节省模块及布线成本;

灵敏度高:在相同数据速率下,它的扩频调制技术的灵敏度比传统的频移键控(FSK)调制方式高 8 ~ 10dB;

调制方式先进:基于扩频技术,采用直接序列扩频,具有前向纠错(FEC)的能力;

抗干扰能力强:对于同频干扰及各种噪声的干扰具有较强的抑制能力;

发射功率密度低:不易对其它设备造成干扰;

保密性高:被截获的可能性极低,采用 AES128 加密;

具有极好的抗多径衰落和多普勒效应性能:在城市中多径效应很明显,信号会因为多径叠加导致严重失真,移动的物体会带来多普勒效应,对无线接收端带来了很大的挑战,而 Lora 通信就能很好的克服这两点;

2.SX1278 介绍:

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

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

发送数据时,通过 SPI 接口将发送数据写到数据 FIFO,由调制器调制再上变频,并由功率放大器放大后进行发送;

接收数据时,接收数据由低噪声放大器放大再下变频,并由解调器解调后送入数据 FIFO,再通过 SPI 接口读取;

3.SX1278 工作方式:

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

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

3.程序编程

1.使能SUBGHZ

2.配置波特率

3.配置天线发送或者接收的输出模式

LORA驱动的移植

//lora.c
#include "lora.h"extern SUBGHZ_HandleTypeDef hsubghz;/*** @brief Set the radio in LoRa?, FSK or Long Range FHSS mode.** @param ucPT 0-(G)FSK packet type*             1-LoRa mode*             3-Long Range FHSS* @return None.*/
void LORA_SetPacketType(uint8_t ucPT)
{uint8_t data = ucPT;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_PACKETTYPE, &data, 1);
}/*** @brief Set  LoRa? packets parameters** @param usPL ,number of symbols sent as preamble.* @param ucHT ,HeaderType, 0-1* @param ucDL ,Size of the payload (in bytes) to transmit or maximum size of thepayload that the receiver can accept* @param ucCM ,CRC on or off.* @param ucIQ ,InvertIQ or Not.*/
void LORA_SetPacketParams(uint16_t usPL, uint8_t ucHT, uint8_t ucDL, uint8_t ucCM, uint8_t ucIQ)
{uint8_t data[6];data[0] = usPL >> 8;data[1] = usPL;data[2] = ucHT;data[3] = ucDL;data[4] = ucCM;data[5] = ucIQ;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_PACKETPARAMS, data, 6);
}/*** @brief Set LoRa? Modulation Parameters** @param ucSF ,5-6-7-8-9-10-11-12, SF5-SF12* @param ucBW ,0-8-1-9-2-10-3-4-5-6, LORA_BW* @param ucCR ,1-2-3-4, LORA_CR_4_5 - LORA_CR_4_8* @param ucLO ,0-1, LowDataRateOptimize* @return None.*/
void LORA_SetModulationParams(unsigned char ucSF, unsigned char ucBW, unsigned char ucCR, unsigned char ucLO)
{uint8_t data[4];data[0] = ucSF;data[1] = ucBW;data[2] = ucCR;data[3] = ucLO;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_MODULATIONPARAMS, data, 4);
}/*** @brief Set Lora frequency band.** @param frequency , frequency in MHz.* @return None.*/
void LORA_SetRfFrequency(uint32_t MHz )
{uint8_t data[4];uint32_t chan  = (MHz << 20);data[0] = ( uint8_t )( ( chan >> 24 ) & 0xFF );data[1] = ( uint8_t )( ( chan >> 16 ) & 0xFF );data[2] = ( uint8_t )( ( chan >> 8 ) & 0xFF );data[3] = ( uint8_t )( chan & 0xFF );HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_RFFREQUENCY, data, 4 );
}/*** @brief  Set the device to SLEEP mode.** @param mode ,0 cold start.*              4 warm start.* @return None.*/
void LORA_SetSleep(uint8_t mode)
{uint8_t data = mode;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_SLEEP, &data, 1);
}/*** @brief  Set the device to STANDBY mode.** @param mode ,0 RC standby mode.*              1 XTAL standby mode.* @return None.*/
void LORA_SetStandby(uint8_t mode)
{uint8_t data = mode;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_STANDBY, &data, 1);
}/*** @brief Set the device to TX or RX mode.** @param mode ,0 Rx mode.*              1 Tx mode.* @return None.*/
void LORA_SetTxRx(uint8_t mode)
{uint8_t data[3] = {0xFF, 0xFF, 0xFF};if(mode == 0){//Rx Continuous modeBSP_RADIO_ConfigRFSwitch(RADIO_SWITCH_RX);HAL_Delay(1);HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_RX, data, 3);}else{data[0] = data[1] = data[2] = 0;BSP_RADIO_ConfigRFSwitch(RADIO_SWITCH_TX);HAL_Delay(1);HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_TX, data, 3);}
}/*** @brief Set the Power Amplifier configuration.** @param duty ,controls the duty cycle < 0x04.* @param hp_max ,selects the size of the PA. < 0x07* @param device ,0x00.* @param lut ,0x01.*/
void LORA_SetPA(uint8_t duty, uint8_t hp_max, uint8_t device, uint8_t lut)
{uint8_t data[4];data[0] = duty;data[1] = hp_max;data[2] = device;data[3] = lut;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_PACONFIG, data, 4);
}/*** @brief Get the device status.** @param None.* @return uint8_t status, device status.*/
uint8_t LORA_GetStatus(void)
{uint8_t status;HAL_SUBGHZ_ExecGetCmd(&hsubghz, RADIO_GET_STATUS, &status, 1);return status;
}/*** @brief Sets the TX parameter power and the TX ramping time.** @param power ,0xF7 ~ 0x16* @param ramptime ,SET_RAMP_10U - SET_RAMP_3400U*/
void LORA_SetTxPara(uint8_t power, uint8_t ramptime)
{uint8_t data[2];data[0] = power;data[1] = ramptime;HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_TXPARAMS, data, 2);}/*** @brief LoRa Initialization function.*        Default setting:*          - LoRa mode.*          - Frequency 476MHz.* @note   This function must be called before using other functions.* @param None.* @return None.*/
void LORA_Init(void)
{
//    uint8_t status = 0;
//    uint8_t data[4] = {0, 0, 0, 0};
//    uint8_t error[3];LORA_SetSleep(0);HAL_Delay(5);LORA_SetStandby(0);HAL_Delay(5);LORA_SetStandby(1);HAL_Delay(5);LORA_SetPacketType(1);LORA_SetRfFrequency(433);LORA_SetPA(1, 0, 1, 1);	//14DBLORA_SetTxPara(13, 0x4);LORA_SetModulationParams(7, 4, 1, 0);LORA_SetPacketParams(8, 0, 8, 1, 0);LORA_SetTxRx(0);
}/*** @brief LoRa Send** @param ucBuf ,A pointer to the data buffer.* @param ucSize ,send data length.*/
void LORA_Tx(uint8_t *ucBuf, uint8_t ucSize)
{uint16_t i = 0;uint8_t status = 0;LORA_SetPacketParams(8, 0, ucSize, 1,0);        HAL_SUBGHZ_WriteBuffer(&hsubghz, 0, ucBuf, ucSize);LORA_SetTxRx(1);do{status = LORA_GetStatus();--i;}while((status != 0xac) && (i != 0));LORA_SetTxRx(0);
}/*** @brief LoRa Receive** @param ucBuff ,A pointer to the data buffer.* @param ucSize ,Receive data length.* @return 1, received data.*         0, no data.*/
uint8_t LORA_Rx(uint8_t *ucBuff, uint8_t *ucSize)
{uint8_t status[2];status[0] = LORA_GetStatus();if (status[0] == 0xd4){HAL_SUBGHZ_ExecGetCmd(&hsubghz, RADIO_GET_RXBUFFERSTATUS, status, 2);HAL_SUBGHZ_ReadBuffer(&hsubghz, status[1], ucBuff, status[0]);*ucSize = status[0];LORA_SetTxRx(0);return 1;}else{return 0;}
}void BSP_RADIO_Init(void)                                               //需要自己编写的新增的函数
{GPIO_InitTypeDef GPIO_InitStruct = {0};                             //PC13初始化为推挽输出__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}void BSP_RADIO_ConfigRFSwitch(BSP_RADIO_Switch_TypeDef Config)          //PC13切换不同电平
{{switch (Config){case RADIO_SWITCH_RX:{HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);break;}case RADIO_SWITCH_TX:{HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);break;}default:break;}}
}
//lora.h
#ifndef __LORA_H__
#define __LORA_H__#include "main.h"
#include "stdio.h"
#include "gpio.h"void LORA_Init(void);
void LORA_Tx(uint8_t *ucBuf, uint8_t ucSize);
uint8_t LORA_Rx(uint8_t *ucBuf, uint8_t *ucSize);typedef enum
{RADIO_SWITCH_RX     = 1,RADIO_SWITCH_TX     = 2,
} BSP_RADIO_Switch_TypeDef;void BSP_RADIO_Init(void);
void BSP_RADIO_ConfigRFSwitch(BSP_RADIO_Switch_TypeDef Config);#endif /* __LORA_H__ */

编写LORA的功能函数,需要我们自己去写

void BSP_RADIO_ConfigRFSwitch(BSP_RADIO_Switch_TypeDef Config)          //PC13切换不同电平
{{switch (Config){case RADIO_SWITCH_RX:{HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);break;}case RADIO_SWITCH_TX:{HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);break;}default:break;}}
}
#include "main.h"
#include "i2c.h"
#include "subghz.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "lora.h"
#include "oled.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t lora_tx[3] = {0x11,0x22,0x00};
uint8_t lora_rx[3]= {0};
uint8_t oled_str[24];
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE *p)
{HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,0xffff);return ch;
}
/* USER CODE END 0 *//*** @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 */MX_USART2_UART_Init();/* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_SUBGHZ_Init();MX_USART2_UART_Init();MX_I2C1_Init();/* USER CODE BEGIN 2 */OLED_Init();LORA_Init();//初始化LORAprintf("this is LORA init\r\n");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){//按键KEY1按键进行LORA发送if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET){lora_tx[2]++;HAL_GPIO_WritePin(LD1_GPIO_Port,LD1_Pin,GPIO_PIN_RESET);LORA_Tx(lora_tx,3);while(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == GPIO_PIN_RESET);}}LORA_Rx(lora_rx,3);if((lora_rx[0] == 0x11) && (lora_rx[1] == 0x22)){HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,GPIO_PIN_RESET);//LORA接收完成之后要清0lora_rx[0]= 0;lora_rx[1] = 0;}sprintf((char *)oled_str,"LORA_TX:%#x",lora_tx[2]);OLED_ShowString(0, 0, oled_str, 16);HAL_Delay(10);sprintf((char *)oled_str,"LORA_RX:%#x",lora_rx[2]);OLED_ShowString(0, 2, oled_str, 16);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

相关文章:

  • 小触控APP:高效自动连点,解放双手
  • 如何预测与控制多项目中的人员负载过高
  • 什么是 Sentinel?
  • Bug闭环解决之道:主流Bug追踪工具优劣对比
  • 把握技术风口,链接优质资源——2025深圳国际全触与显示展重磅推出六大新技术展区,布局新蓝海
  • 【第二章:机器学习与神经网络概述】03.类算法理论与实践-(2)朴素贝叶斯分类器
  • 数据集笔记:中国公交路线线路
  • 纯血HarmonyOS5 打造小游戏实践:扫雷(附源文件)
  • 基于 Spark 实现 COS 海量数据处理
  • Java底层原理:深入理解类加载机制与反射
  • 运维打铁: Windows 服务器基础运维要点解析
  • 2025年- H89-Lc197-- 5. 最长回文子串(多维动态规划)--Java版
  • 【技术分享】XR技术体系浅析:VR、AR与MR的区别、联系与应用实践
  • Web开发中的多媒体元素
  • Spring核心技术底层实现详解
  • 在AI时代看清糖网:糖尿病视网膜病变筛查的转型之路
  • 软件设计模式期末复习模拟解析
  • DMDRS部署实施手册(ORACLE=》DM)
  • MySQL与Oracle视图:深入解析与全面对比
  • 设计模式 - 工厂方法
  • 苏州专业做网站公司有哪些/百度账号人工客服
  • 办公用品网站建设策划书/运营推广seo招聘
  • 国外 网站 模板/搜狗seo查询
  • Wordpress热门评论插件/陕西seo关键词优化外包
  • 网页设计源代码css案例/网络营销的优化和推广方式
  • 网站脑图用什么做/nba最新交易消息