这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【转载】Lora模块使用方法--from毅

共1条 1/1 1 跳转至

【转载】Lora模块使用方法--from毅

工程师
2025-06-19 21:37:41     打赏

1、Lora模块

LoRa模块为基于LPWAN的远距离无线通信模块,支持LORAWAN标准协议,串口数据透传双向通讯,主要应用在智能抄表、智慧路灯、智慧农业、智能停车、智能安防等领域。LoRa技术具有远距离、低功耗、多节点、低成本的特性

基于LoRaWAN的网络能够提供安全的数据传输距离远的双向通信,并且用最少的网络基础设施覆盖城市区域,LoRa技术在智慧农业、智慧建筑、智慧物流等多种应用场景中都将得到广泛应用。

屏幕截图 2025-06-19 213124.png

2、应用场景

家庭安防报警及远程无钥匙进入;
智能家居以及工业传感器等l;
无线报警安全系统;
楼宇自动化解决方案;
无线工业级遥控器;
智能智能农业、油田方案;医疗保健产品;
高级抄表架构(AMI);
汽车行业应用。

3、引脚定义

屏幕截图 2025-06-19 213134.png

Lora可配置参数

Lora设置模式下可以连续发送6个字节进行功能的设置,将功能封装为结构体

typedef struct{

uint8_t head;

uint8_t addh;

uint8_t addl;

uint8_t sped;

uint8_t chan;

uint8_t option;

}Lora_WorkParameter;//工作参数

其中:

head 为C0时设参数掉电保存 为C2时掉电不保存

addh 模块地址高字节

addl 模块地址低字节

sped 7 6位控制串口通信模式 5 4 3 设置串口速率 2 1 0 设置无线空中速率

chan 7 6 5保留 4 3 2 1 0 通信通道设置 00H-0FH d对应410HZ~441HZ Lora模块就工作在此频率空间

option 7 定点发送使能位 为1时定点传输模式用户前三个字节作为高地址 低地址 通道、 为0时 透明传输

6 IO驱动方式 默认1

5 4 3 无线唤醒时间

2 FEC开关

1 0 发射功率

4、Lora使用方法

4.1 Lora的四种工作模式

Lora有四种工作模式,类似esp8266,模块的使用都会有配置模式和通讯模式等,Lora将模式分为四种

屏幕截图 2025-06-19 213145.png

M0,M1两引脚通常与两个普通GPIO口链接,通过置位高低电平控制模块的工作模式,通常使用一般模式和休眠模式,其中休眠模式就是配置模式。


5、模块传输模式

模块传输模式有三种,模块的工作会时刻监听Lora工作频率433MHz下的任何数据

(1)透明传输:即透传数据,例如:A设备发5字节数据AABBCCDDEE到B设备,B设备就可以收到数据AABBCCDDEE。(透明传输,针对设备相同地址、相同的通信信道,用户数据可以是字符或16进制数据形式)

(2)定向传输:即定点传输,例如:A设备(地址为:0x0001,信道为0x02)需要向B设备(地址为:0x0003,信道为0x10)发送数据AABBCC,其通信格式为:0003 04 AABBCC,其中0003为模块B的地址,04为信道,

则模块B可以收到AABBCC。同理,如果B设备需要向A设备发送数据AABBCC,其通信格式为:000102AABBCC,则A设备可以收到AABBCC。(定向传输,针对设备间地址和通信信道不同,数据格式为16进制,发送格式:

高位地址+低位地址+信道+用户数据)

屏幕截图 2025-06-19 213156.png

(3)广播与数据监听:将发送数据中的模块地址写为为0xFFFF(即65535),可以被相同信道上任意地址的模块收到,从而起到广播和监听的作用。

屏幕截图 2025-06-19 213203.png

三者的区别:

简单的说,当只需要点对点通信(即两个LORA相互通信)时,可使用前两种方式。

其中,透明传输可以以字符或16进制数据形式发送,需要两个LORA模块的地址、信道相同,而定向传输只能以16进制的特定格式发送,无需二者地址或信道相同。(由于LORA模块的地址和信道有十分多的选择,

一般不会出现冲突的可能,所以个人推荐使用透明传输更方便。)

6、c语言实现

lora.h

#ifndef _LOAR_H_

#define _LOAR_H_


#include "stm32f10x.h"


#define LORA_M0_CLK       RCC_APB2Periph_GPIOB

#define LORA_M0_PORT      GPIOB

#define LORA_M0_PIN       GPIO_Pin_5


#define LORA_M1_CLK       RCC_APB2Periph_GPIOB

#define LORA_M1_PORT      GPIOB

#define LORA_M1_PIN       GPIO_Pin_6


#define LORA_AUX_CLK       RCC_APB2Periph_GPIOB

#define LORA_AUX_PORT      GPIOB

#define LORA_AUX_PIN       GPIO_Pin_7


#define M0(x) (x)?(GPIO_SetBits(LORA_M0_PORT,LORA_M0_PIN)):(GPIO_ResetBits(LORA_M0_PORT,LORA_M0_PIN))

#define M1(x) (x)?(GPIO_SetBits(LORA_M1_PORT,LORA_M1_PIN)):(GPIO_ResetBits(LORA_M1_PORT,LORA_M1_PIN))

#define AUX_Sta() (GPIO_ReadInputDataBit(LORA_AUX_PORT,LORA_AUX_PIN))


/*********************设置Lora工作参数***********/

//修改参数命令

#define CMD_STOREPRM      0xC0//所设置参数会保存

#define CMD_NOTSTOREPRM   0xC2//所设置参数不会保存

//UART协议中奇偶校验

#define PRM_UART_Parity_8N1      0x00//不奇偶校验

#define PRM_UART_Parity_8O1      0x01//偶校验

#define PRM_UART_Parity_8E1      0x10//奇校验

//UART协议中波特率

#define PRM_UART_BaudRate_1200    0x00

#define PRM_UART_BaudRate_2400    0x01

#define PRM_UART_BaudRate_4800    0x02

#define PRM_UART_BaudRate_9600    0x03

#define PRM_UART_BaudRate_19200   0x04

#define PRM_UART_BaudRate_38400   0x05

#define PRM_UART_BaudRate_57600   0x06

#define PRM_UART_BaudRate_115200  0x07


//设置空中数据传输速率

#define PRM_Sky_Speed_0_3       0x00//0.3kbps

#define PRM_Sky_Speed_1_2       0x01//1.2kbps

#define PRM_Sky_Speed_2_4       0x02//2.4kbps

#define PRM_Sky_Speed_4_8       0x03//4.8kbps 

#define PRM_Sky_Speed_9_6       0x04//9.6kbps

#define PRM_Sky_Speed_19_2      0x05//19.2kbps


//设置传输模式

#define PRM_TRAN_MODE_TT        0x00//透传传输模式

#define PRM_TRAN_MODE_FP        0x01//定点传输模式

//AUX RX TX IO驱动方式

#define PRM_IO_Driver_PP        0x01//内部具有上拉

#define PRM_IO_Driver_OD        0x00//内部具有开路

//唤醒时间

#define PRM_WarkUp_Time_250     0x00//单位ms

#define PRM_WarkUp_Time_500     0x01

#define PRM_WarkUp_Time_750     0x02

#define PRM_WarkUp_Time_1000    0x03

#define PRM_WarkUp_Time_1250    0x04

#define PRM_WarkUp_Time_1500    0x05

#define PRM_WarkUp_Time_1750    0x06

#define PRM_WarkUp_Time_2000    0x07


//FEC纠错开关

#define PRM_FEC_OPEN            0x01//打开

#define PRM_FEC_CLOSE           0x00//关闭

//设置发射功率

#define PRM_EmissionPower_20    0x00//20dbm

#define PRM_EmissionPower_17    0x01

#define PRM_EmissionPower_14    0x02

#define PRM_EmissionPower_10    0x03


//设置默认的参数(也可以在外面设置参数)

#define CMD_DEFAULT                    CMD_STOREPRM

#define PRM_UART_Parity_DEFAULT        PRM_UART_Parity_8N1

#define PRM_UART_BaudRate_DEFAULT      PRM_UART_BaudRate_9600

#define PRM_Sky_Speed_DEFAULT          PRM_Sky_Speed_2_4

#define PRM_CHANNEL_DEFAULT            0x17//00-73h变化 410~525MHz

#define PRM_TRAN_MODE_DEFAULT          PRM_TRAN_MODE_TT

#define PRM_WarkUp_Time_DEFAULT        PRM_WarkUp_Time_250

#define PRM_FEC_DEFAULT                PRM_FEC_OPEN

#define PRM_EmissionPower_DEFAULT      PRM_EmissionPower_20


#define LORA_MODE_PATTERN     0x00 //一般模式

#define LORA_MODE_WARKUP      0x01 //唤醒模式

#define LORA_MODE_POWERSAVE   0x10 //省电模式

#define LORA_MODE_SLEEP       0x11 //休眠模式


typedef struct{

u8 head;

u8 addh;

u8 addl;

u8 sped;

u8 chan;

u8 option;

}__Lora_WorkParameter;//工作参数


typedef union {

Lora_WorkParameter lora_workprm;

u8 buff[6];

}LORA_WORKDATA;//接收或则发送工作参数,使用共用体方便使用


#define WIRELESS_RX_MAX 1024

#define WIRELESS_TX_MAX 1024

typedef struct{

uint8_t  rx_buff[WIRELESS_RX_MAX];//串口数据接收缓冲区

uint8_t  tx_buff[WIRELESS_TX_MAX];//串口数据发送缓冲区

uint8_t  rx_over;    //接收完成标志0 -- 没有接收完成 1 -- 接收完成

uint32_t rx_count;                //接收数据的个数

uint32_t tx_count;                //发送数据的个数

}Lora_TypeDef;


void Lora_Init(void);

void UART4_Config(u32 boad);

void UART4_SendData(u8 data);

void Lora_SendCmd(u8* data, u8 size);

void Lora_SendData(u8 *data,u16 len);

void Lora_SetWorkParameters(void);

void Lora_DataAnalysis(void);

Lora.c


Lora_TypeDef loradata = {0};

LORA_WORKDATA lora_parameter = {0};

u16 lora_self_addr = 0x0001;//本身地址

u16 lora_target_addr = 0x0002;//目标地址


void Lora_Init(void)

{

//相关管脚初始化

GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(LORA_M0_CLK|LORA_M1_CLK|LORA_AUX_CLK,ENABLE);

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_Pin = LORA_M0_PIN;

GPIO_Init(LORA_M0_PORT,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin = LORA_M1_PIN;

GPIO_Init(LORA_M1_PORT,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStruct.GPIO_Pin = LORA_AUX_PIN;

GPIO_Init(LORA_AUX_PORT,&GPIO_InitStruct);

UART4_Config(9600);//串口3初始化+接收中断初始化

Lora_SetWorkParameters();

// Lora_CurrentPram();//读取Lora模块的参数

}


void UART4_Config(u32 boad)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

GPIO_InitTypeDef GPIO_InitStruct;

//3.给结构体赋值  TX管脚 输出

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;  //具体外设用哪个模式,从参考手册8.1.11中查询

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


//4.调用init函数,将参数写入到寄存器中

GPIO_Init(GPIOC,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //具体外设引脚用哪个模式,从参考手册8.1.11中查询

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;


GPIO_Init(GPIOC,&GPIO_InitStruct);

/*****************************************************************/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);

USART_InitTypeDef USART_InitStruct;

USART_InitStruct.USART_BaudRate = boad;  //波特率

USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件流控制

USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; //发送和接收都使能

USART_InitStruct.USART_Parity = USART_Parity_No; //无奇偶校验位

USART_InitStruct.USART_StopBits =  USART_StopBits_1;  //1个停止位

USART_InitStruct.USART_WordLength = USART_WordLength_8b;  //8个数据位

//8.调用init函数,将参数写入到寄存器中

USART_Init(UART4,&USART_InitStruct);


//配置为串口接收中断与空闲中断

USART_ITConfig(UART4,USART_IT_RXNE,ENABLE);  //打开接收中断

USART_ITConfig(UART4,USART_IT_IDLE,ENABLE); //打开空闲中断

NVIC_SetPriority(UART4_IRQn,1);

NVIC_EnableIRQ(UART4_IRQn);


USART_Cmd(UART4,ENABLE);

}

void UART4_IRQHandler(void)

{

uint8_t data = 0;

data = data;

if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)

{

if(loradata.rx_count>WIRELESS_RX_MAX)

loradata.rx_count=0;

loradata.rx_buff[loradata.rx_count++] = UART4->DR;

USART_ClearITPendingBit(UART4, USART_IT_RXNE);

//USART_SendData(USART1,UART4->DR);  //串口1显示

}

if(USART_GetITStatus(UART4, USART_IT_IDLE) == SET)

{

loradata.rx_over = 1;

USART_ReceiveData(UART4); 

}

}


void UART4_SendData(u8 data)

{

while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);

UART4->DR = data;

}



void Lora_SendCmd(u8* data, u8 size)

{

for(u8 i=0; i<size; i++)

UART4_SendData(data[i]);

}


//数组发送函数

//数组的首地址    数组的长度

void UART4_SendBuff(uint8_t *buff,uint16_t length)

{

uint16_t temp=0;

for(temp=0;temp<length;temp++)

{

UART4_SendData(buff[temp]);

}

}


void Lora_SendData(u8 *data, u16 len)

{

u8 addrh = (lora_target_addr>>8)&0xFF;

u8 addrl = lora_target_addr&0xFF;

uint8_t buff[256] = {addrh,addrl,PRM_CHANNEL_DEFAULT};

for(u8 i=0; i<len; i++)

buff[i+3] = data[i];

for(u8 i=0; i<len+3; i++)

UART4_SendData(buff[i]);

}


//设置Lora的模式

void Lora_SetMode(u8 mode)

{

if((mode != LORA_MODE_PATTERN) && (mode != LORA_MODE_WARKUP) && (mode != LORA_MODE_POWERSAVE) && (mode != LORA_MODE_SLEEP))  

return ;

GPIO_WriteBit(LORA_M0_PORT,LORA_M0_PIN,(BitAction)(mode & 0x1));

GPIO_WriteBit(LORA_M1_PORT,LORA_M1_PIN,(BitAction)((mode>>4) & 0x1));

vTaskDelay(100);

}


//#define LORA_MODE_PATTERN     0x00 //一般模式

//#define LORA_MODE_WARKUP      0x01 //唤醒模式

//#define LORA_MODE_POWERSAVE   0x10 //省电模式

//#define LORA_MODE_SLEEP       0x11 //休眠模式


//Lora模块复位

void Lora_Reset(void)

{

u8 tx_buff[] = {0xC4,0xC4,0xC4};

Lora_SetMode(LORA_MODE_SLEEP);//进入休眠模式

Lora_SendCmd(tx_buff,sizeof(tx_buff));//发送重启命令

}

//设置lora工作参数

void Lora_SetWorkParameters(void)

{

//关闭串口4中断

USART_ITConfig(UART4,USART_IT_RXNE, DISABLE);

NVIC_DisableIRQ(UART4_IRQn);

Lora_SetMode(LORA_MODE_SLEEP);//进入休眠模式

lora_parameter.lora_workprm.head = CMD_STOREPRM;//掉电不丢失

lora_parameter.lora_workprm.addh = (lora_self_addr>>8) & 0xff;

lora_parameter.lora_workprm.addl = lora_self_addr & 0xff;

lora_parameter.lora_workprm.sped = (PRM_UART_Parity_8N1<<6)|(PRM_UART_BaudRate_9600<<3)|(PRM_Sky_Speed_2_4);

lora_parameter.lora_workprm.chan = PRM_CHANNEL_DEFAULT;    // 0x17 00-73h变化 410~525MHz

lora_parameter.lora_workprm.option = ((PRM_TRAN_MODE_FP<<7)|(PRM_IO_Driver_PP<<6)|

    (PRM_WarkUp_Time_250<<3)|(PRM_FEC_OPEN<<2)|(PRM_EmissionPower_20));

Lora_SendCmd(lora_parameter.buff,sizeof(lora_parameter.buff));

vTaskDelay(100);

Lora_SetMode(LORA_MODE_PATTERN);//进入一般模式


//开中断

USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);

NVIC_EnableIRQ(UART4_IRQn);

}

来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。








共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]