基于STM32实现LORA通讯

本文用于学习记录如何实现在STM32单片机下实现简单的lora通讯。

认识lora

lora是一种低功耗远程无线通信技术,现如今被广泛应用。

使用lora

引脚定义

在对lora进行软件编程前,首先需要了解lora的工作原理及引脚定义,本文所使用的lora模块为亿佰特的lora无线通讯模块,其引脚定义如下:

虽然管脚多达18个,但我们需要控制的管脚只有1-5脚,清楚管脚定义后,接下来需要了解到lora通讯的通讯原理以及如何控制管脚;

工作模式

模块共有4种工作模式,模式由M1,M0所控制:

一般情况下我们主要使用传输模式0和休眠模式3,发送模式和接收模式可根据实际情况进行使用。

在配置M1,M0管脚的时候,我们还需要注意AUX管脚,模式切换的前提条件需要保证AUX输出为1,所以我们一般在配置完毕后等待2ms,AUX输出为高时才进行切换工作模式。

了解完通讯模式后,接下来就能掌握其通讯原理了,用户使用串口对lora模块发送数据,lora模块收到数据后通过无线传输的形式将数据发送出去,注意lora发送数据出去需要有地址和信道,否则发送将会失败,那么什么是lora地址和信道呢,每个lora模块都有自己的地址和信道,地址大家都能理解,信道的不同标志着lora无线通讯的频率也会不同,所以在特殊情况下,我们可以设置各个lora模块之间的不同信道,保证在数据传输过程中不会受到干扰;

寄存器配置

地址和信道通过操作寄存器设置,各个寄存器操作使用方法如下:

通过上面的表格,我们可以对lora模块的地址信道,波特率等等进行设置;

传输方式

下面是lora通讯的传输方式:

定点发射

广播发射

简单来说定点发射就是接收端模块的地址和信道必须与发送端发送的地址和信道完全一致才能接收到数据;

广播发射就是发送端发送的地址设为FFFF,信道为04,则其他信道为04的模块就能收到这条数据。

LORA编程

学习到了LORA的基本知识后,接下来就可以对其进行编程了,下面仅对lora部分进行代码编程,lora.c如下:

#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_it.h"
#include "stm32f4xx_rtc.h"
#include "stm32f4xx.h" 
#include "misc.h" 
#include "sys.h"
#include "loraCtrl.h"
#include "uartProc.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include "delay.h"
#include "un_struct.h"
#include "pcProc.h"
#include "loraCtrl.h"

unsigned char g_loraRxBuff[LORA_RX_BUFFER_SIZE];//定义lora串口的发送和接收数据大小
unsigned char g_loraTxBuff[LORA_TX_BUFFER_SIZE];
void lora_gpio_init(void);
void lora_uart_send(int len,unsigned char* pdata);
void lora_get_frame(int len);
void lora_send_client_test(unsigned char addrH,unsigned char addrL,unsigned char chain,unsigned char instr);
void lora_instruct_reply(int value);
void Lora_send_history_num(unsigned int value);

void lora_init(void)
{
	//串口初始化
	lora_gpio_init();
	uartProc_init(LORA_UART,9600,LORA_RX_BUFFER_SIZE,(u8*)g_loraTxBuff,LORA_TX_BUFFER_SIZE,(u8*)g_loraRxBuff,(FUNCPTR*)lora_get_frame);
	Lora_Set_Mode(0);
	delay_ms(5);
}
//Lora处理函数
void lora_get_frame(int len)
{
	pc_uart_send(len,(char*)&g_loraRxBuff); //回传lora连接测试字符串给上位机
}
//lora数据发送
void lora_uart_send(int len,unsigned char* pdata)
{
	int i=0;
	for(i=0;i<len;i++)
	g_loraTxBuff[i]=pdata[i];
	uart_dma_send_enable(LORA_UART,len);	
}
//loraGPIO管脚初始化
void lora_gpio_init(void)
{
	
	GPIO_InitTypeDef    GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOC时钟
	
	//配置M1,M0
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13; //GPIOB12与GPIOB13
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;			//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 			//推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 			//上拉
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//配置AUX
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_Init(GPIOC,&GPIO_InitStructure);	
	
}
//设置Lora模块地址
void lora_set_model_addr(unsigned char addrH,unsigned char addrL)
{
	unsigned char sendData[16];
	
	sendData[0]=0xc0;
	sendData[1]=0x0;
	sendData[2]=0x2;
	sendData[3]=addrH;
	sendData[4]=addrL;
	lora_uart_send(5,sendData);
	delay_ms(1);
}
//设置Lora信道
void lora_set_mode_chain(unsigned char chain)
{
	unsigned char sendData[16];
	sendData[0]=0xc0;
	sendData[1]=0x4;
	sendData[2]=0x1;
	sendData[3]=chain;
	lora_uart_send(4,sendData);

	delay_ms(2);
}

//设置Lora模块的串口波特率,空中速率
//串口波特率:
#define  LORA_COM_BARDRATE_1200 (0<<5)
#define  LORA_COM_BARDRATE_2400 (1<<5)
#define  LORA_COM_BARDRATE_4800 (2<<5)
#define  LORA_COM_BARDRATE_9600 (3<<5)
#define  LORA_COM_BARDRATE_19200 (4<<5)
#define  LORA_COM_BARDRATE_38400 (5<<5)
#define  LORA_COM_BARDRATE_57600 (6<<5)
#define  LORA_COM_BARDRATE_115200 (7<<5)

#define LORA_WIRELESS_RATE_2D4K   (0)
#define LORA_WIRELESS_RATE_4D8K   (3)
#define LORA_WIRELESS_RATE_9D6K   (4)
#define LORA_WIRELESS_RATE_19D2K   (5)
#define LORA_WIRELESS_RATE_38D4K   (6)
#define LORA_WIRELESS_RATE_62D5K   (7)

#define LORA_COM_DATABITS_8N1		(0<<3)
#define LORA_COM_DATABITS_8O1		(1<<3)
#define LORA_COM_DATABITS_8E1		(2<<3)

void lora_set_baudrate(unsigned char baudrate,unsigned char databits,unsigned char wirelessRate)
{
	unsigned char sendData[8];
//	Lora_Set_Mode(3);
//	delay_ms(2);
	sendData[0]=0xc0;
	sendData[1]=0x2;
	sendData[2]=0x1;
	switch(baudrate)
	{
		case 0:
			sendData[3]=LORA_COM_BARDRATE_1200;
			break;
		case 1:
			sendData[3]=LORA_COM_BARDRATE_2400;
			break;
		case 2:
			sendData[3]=LORA_COM_BARDRATE_4800;
			break;
		case 3:
			sendData[3]=LORA_COM_BARDRATE_9600;
			break;
		case 4:
			sendData[3]=LORA_COM_BARDRATE_19200;
			break;
		case 5:
			sendData[3]=LORA_COM_BARDRATE_38400;
			break;
		case 6:
			sendData[3]=LORA_COM_BARDRATE_57600;
			break;
		case 7:
			sendData[3]=LORA_COM_BARDRATE_115200;
			break;
		default:
			sendData[3]=LORA_COM_BARDRATE_9600;
			break;
	}
	switch(databits)
	{
		switch(databits)
		{
			case 0:
				sendData[3] |= LORA_COM_DATABITS_8N1;
				break;
			case 1:
				sendData[3] |= LORA_COM_DATABITS_8O1;
				break;
			case 2:
				sendData[3] |= LORA_COM_DATABITS_8E1;
				break;
			default:
				sendData[3] |= LORA_COM_DATABITS_8N1;
				break;
		}
	}
	switch(wirelessRate)
	{
		case 0:
			sendData[3] |= LORA_WIRELESS_RATE_2D4K;
			break;
		case 1:
			sendData[3] |= LORA_WIRELESS_RATE_4D8K;
			break;
		case 2:
			sendData[3] |= LORA_WIRELESS_RATE_9D6K;
			break;
		case 3:
			sendData[3] |= LORA_WIRELESS_RATE_19D2K;
			break;
		case 4:
			sendData[3] |= LORA_WIRELESS_RATE_62D5K;
			break;
		default:
			sendData[3] |= LORA_WIRELESS_RATE_2D4K;
			break;
	}
	
	lora_uart_send(4,sendData);
//	delay_ms(2);
//	Lora_Set_Mode(0);
	delay_ms(1);
}
//配置LORA模块的工作模式
void Lora_Set_Mode(u8 mode)
{
//	 while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) != RESET);
	switch(mode)
	{
		case 0://传输模式
		M1 = 0;
		M0 = 0;
		delay_ms(1);
		break;
		case 1://WOR发送模式
		M1 = 0;
		M0 = 1;
		delay_ms(1);
		break;
		case 2://WOR接收模式
		M1 = 1;
		M0 = 0;
		delay_ms(1);
		break;
		case 3://休眠模式(配置模式)
		M1 = 1;
		M0 = 1;
		delay_ms(1);
		break;
		default:
		M1 = 0;
		M0 = 0;
		delay_ms(1);
		break;
	}
	 while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == RESET);
	delay_ms(2);

}

lora.h代码如下

#include "sys.h"
#ifndef _LORACTRL_H_
#define _LORACTRL_H_

#define M0 PBout(12)
#define	M1 PBout(13)
#define LORA_RX_BUFFER_SIZE 0x1000
#define LORA_TX_BUFFER_SIZE 0x1000
#define RX_BUFF_SIZEMAX 128
#define TX_BUFF_SIZEMAX 128
#define LORA_UART 3			//定义LORA串口
void lora_init(void);
void Lora_Set_Mode(u8 mode);
void lora_set_model_addr(unsigned char addrH,unsigned char addrL);
void lora_set_baudrate(unsigned char baudrate,unsigned char databits,unsigned char wirelessRate);
void lora_uart_send(int len,unsigned char* pdata);
void lora_write_reg(unsigned char reg,unsigned char len,unsigned char pdata[]);
void lora_read_reg_cmd(u8 regAddr,u8 len);
void Lora_send_test_data(unsigned char *pdata);
//void lora_send_data(unsigned char maddr1,unsigned char maddr2,unsigned char mchain,char *pdata,u8 len);
void lora_send_client_test(unsigned char addrH,unsigned char addrL,unsigned char chain,unsigned char instr);
void lora_set_mode_chain(unsigned char chain);
void lora_instruct_reply(int value);
void Lora_send_history_num(unsigned int value);


#endif

通过上述程序编写,即可完成对lora的程序编写,最后可写个测试代码进行验证

LORA测试

这里我是自己写了个上位机程序,方便自己调试使用,发送了测试数据tx:Hello Lora!目标lora收到数据后给我回复了个rx: Hello Lora!以上测试结果实现了lora之间的简单通讯。

结束

注:本文仅供参考

本文主要是为了记录自己曾经学习lora时的经验,也方便日后自己学习查看,文中的代码如果直接粘贴可能会报错,若有需要的可使用lora.c中的配置函数即可完成lora的初始化工作,后面会在找时间完善该文章,谢谢观看!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值