[005] [蓝桥杯物联网] LoRa模块通信原理概述与API使用方法

蓝桥杯
Contents
LoRa模块概述
模块描述
工作模式
数据FIFO
HAL库LoRa编程
CubeMX配置
SPI_WriteRead
函数封装
LoRa API使用
使用示例

MCU型号:STM32L071KBU
SDK:HAL库
工具:CubeMX + MDK

1 LoRa模块概述

1.1 模块描述

LoRa (Long Range, 远距离)模块收发器型号为SX1278,可以完成点对点的数据通信功能,属于半双工通信,其原理图与引脚描述如下图所示:

image-20220402152132346

▲ Lora模块原理图

image-20220402160909929

▲ Lora模块引脚描述

Lora竞赛板中引出了以下引脚:
在这里插入图片描述

  • PA5~7:一般配置为硬件SPI通信引脚
  • PA4:片选引脚,一般选择软件片选
  • PA9:复位引脚,无需复位时,初始化时拉高即可
  • PA10:DIO0外部中断引脚,当接收端接收到数据之后,DIO0 将触发上升沿信号,可编程在EXTI中断中处理接收数据

1.2 工作模式

在这里插入图片描述

SX1278寄存器在任何模式下都可以读,但仅在睡眠和待机模式下可写

1.3 数据FIFO

LoRa数据FIFO共256字节,用于发送和接收数据,除睡眠模式外,其他模式下均可读写,在切换到新的接收模式时,自动清除旧内容,如下图所示:

image-20220402163801589

▲ LoRa 数据FIFO

调制器用于发送数据,解调器用于接收数据

image-20220403025929695

  • 发送时,首先进入待机模式,将FIFO SPI 地址FifoAddrPtr设置为FIFO调制器基地址FifoTxBaseAddr,将负载长度PayloadLength设置为发送字节数,将数据写入FIFO,然后切换到发送模式,等待发送完成,发送完成后芯片自动返回到待机模式,切换到连续接收模式等待接收,如下图所示:

image-20220402164242149

▲ LoRa发送流程
  • 连续接收时,首先切换到接收模式,等待接收完成,接收完成后将FIFO SPI 地址FifoAddrPtr设置为FIFO接收开始地址FifoRxCurrentAddr,然后从FIFO读取RxNbBytes个字节数据,如下图所示:

image-20220402164300954

▲ LoRa接收流程

芯片不同模式之间转换时FIFO 的状态:

image-20220403024217581

2 HAL库LoRa编程

2.1 CubeMX配置

PA5~7配置为硬件SPI通信引脚:

image-20220403143635874

根据官方手册给出的LoRa模块SPI通信要求配置的参数:

  • 全双工通信
  • SPI 主机采用模式0,CPOL=0 和CPHA=0
  • 数据长度8 位,MSB 通信
  • SPI 速度需要小于10M(主频32M / 4 = 8M)

此外,还需要初始化PA9复位引脚和PA4片选引脚,配置成通用推挽输出,将它们拉高

PA10配置为外部中断触发引脚,上升沿触发:

image-20220403144425547

使能EXTI4_15中断:

image-20220403144455574

2.2 SPI_WriteRead函数封装

uint8_t SPI_WriteRead(uint8_t addr, uint8_t data)
{
    
    
    uint8_t tx_data[2], rx_data[2];

    tx_data[0] = addr;
    tx_data[1] = data;

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, tx_data, rx_data, 2, 10);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

    return rx_data[1];
}

2.3 LoRa API使用

2.3.1 LoRa初始化

void LORA_Init(void)
{
    
    
    SPI_WriteRead(0x81, 0);             /* 设置睡眠模式 */
    SPI_WriteRead(0x81, 0x80);          /* 设置LoRa模式 */
    SPI_WriteRead(0x81, 1);             /* 设置待机模式 */
    LORA_SetRFFrequency(434);           /* 设置射频频率(137~525MHz) */
    LORA_SetRFPower(10);                /* 设置射频功率(2~20dBm) */
    SPI_WriteRead(0x9E, 7 << 4);        /* 设置扩频因子(7~12) */
    LORA_SetBW(7);                      /* 设置信号带宽(0~9) */
    LORA_SetCR(1);                      /* 设置纠错编码率(1~4) */
    SPI_WriteRead(0x81, 5);             /* 设置连续接收模式 */
}

一般只需要设置LoRa模式(必须在睡眠模式下设置)和射频功率/频率即可,其他使用默认值

射频功率在10mW可提供超过25KM视距传输。

注意注意:LoRa模块间频率、带宽、扩频因子和前导码长度等参数相同才能通信。

2.3.2 发送数据

void LORA_Tx(unsigned char *pucBuf, unsigned char ucSize)
{
    
    
    unsigned int i;
    unsigned char ret;

    SPI_WriteRead(0x81, 1);             /* 设置待机模式 */
    ret = SPI_WriteRead(0x0E, 0);       /* 读取FifoTxBaseAddr */
    SPI_WriteRead(0x8D, ret);           /* 设置FifoAddrPtr */
    SPI_WriteRead(0xA2, ucSize);        /* 设置PayloadLength */
    for(i = 0; i < ucSize; i++)         /* 写数据到FIFO */
        SPI_WriteRead(0x80, pucBuf[i]);
    SPI_WriteRead(0x81, 3);             /* 设置发送模式 */
    i = 65535;
    do
    {
    
    
        ret = SPI_WriteRead(0x12, 0);     /* 读标志 */
        i--;
    }while(((ret & 8) == 0) && (i != 0));  /* 等待发送完成 */
    SPI_WriteRead(0x92, 8);             	/* 清除发送完成 */
    SPI_WriteRead(0x81, 5);             	/* 设置连续接收模式 */
}
  • pucBuf:指向发送数据缓冲区的指针
  • ucSize:待发送数据的字节数(数据FIFO最大256字节,因此单次发送数据超过256字节后的数据会被截断)

每次发送完数据后,LoRa模块都会切换到连续接收模式,等待数据的接收。

2.3.3 接收数据

unsigned char LORA_Rx(unsigned char *pucBuf)
{
    
    
    unsigned char i, ret;

    ret = SPI_WriteRead(0x12, 0);       /* 读标志 */
    if(ret & 0x40)                      /* 接收完成 */
    {
    
    
        SPI_WriteRead(0x81, 1);           /* 设置待机模式 */
        SPI_WriteRead(0x92, 0x40);        /* 清除接收完成 */
        ret = SPI_WriteRead(0x10, 0);     /* 读取FifoRxCurrentAddr */
        SPI_WriteRead(0x8D, ret);         /* 设置FifoAddrPtr */
        ret = SPI_WriteRead(0x13, 0);     /* 读取RxNbBytes */
        for(i = 0; i < ret; i++)
            pucBuf[i] = SPI_WriteRead(0, 0);/* 从FIFO读数据 */
        SPI_WriteRead(0x81, 5);           /* 设置连续接收模式 */
    }
    else
        ret = 0;
    return ret;
}
  • pucBuf:指向接收缓冲区的指针
  • 返回值:接收到的数据长度(unit:字节)

每次接收完数据后,LoRa模块都会切换到连续接收模式,继续等待数据的接收。

2.4 使用示例

按下USER按键发送数据:

uint8_t tx_data[2] = {
    
    0x12, 0x34};
uint8_t rx_data[2];
void lora_send(void)
{
    
    
    LORA_Tx(tx_data, sizeof(tx_data));
}

在外部中断EXTI4_15_IRQHandler回调函数中打印接收到的数据:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    
    
    if (GPIO_Pin == GPIO_PIN_10)
    {
    
    
        uint8_t data_length = LORA_Rx(rx_data);
        printf("size: %d, rx1:%x, rx2:%x\r\n", data_length, rx_data[0], rx_data[1]);
    }
}

实验结果:LoRa模块都能正常发送数据,且均能收到对方发送的数据。

image-20220403145243200

END

猜你喜欢

转载自blog.csdn.net/kouxi1/article/details/123937802
005