打印
[应用相关]

基于STM32实现LORA通讯

[复制链接]
1063|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-6-7 12:14 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本文用于学习记录如何实现在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=pdata;
        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之间的简单通讯。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_67924449/article/details/139352257

使用特权

评论回复
沙发
xuanhuanzi| | 2024-6-9 18:22 | 只看该作者
不同的lora芯片接口不太一样吧。SPI的和I2C的是不是都有

使用特权

评论回复
板凳
呐咯密密| | 2024-6-12 16:00 | 只看该作者
LORA的低功耗和射频距离都很不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1923

主题

15596

帖子

11

粉丝