【物联网竞赛-LoRa驱动函数剖析】

一、入门LoRa无线扩频通信技术

Semtech 的低功耗广域网无线电调制技术“LoRa®”的名称来源于该技术支持的极远距离数据链路。LoRa 信号可以传播的距离超过 700 公里。然而,一般来说,LoRa 通信范围在城市地区可达 3 英里(5 公里),在农村地区可达 10 英里(15 公里)。

LoRa 在物理层运行,使设备能够将数据转换为 RF 信号,使用啁啾扩频通信和免许可的亚千兆赫频带在空中发送消息。使用 LoRa 芯片组构建的设备的物联网 (IoT) 解决方案的一个关键特征是其超低功耗要求。使用 LoRa 芯片构建的传感器和其他设备可以在单节电池上使用长达 10 年。

反过来,LoRaWAN® 正迅速成为 LPWAN 部署的事实标准。LoRaWAN 标准由 LoRa Alliance® 管理,是一种使用 LoRa 物理层的异步软件协议。通过使用 LoRa 和 LoRaWAN,可以实现非常大规模的灵活网络。

二、涉及的重要函数

1、RadioInit( uint32_t freq, int8_t power, uint32_t txTimeout ) 无线射频初始化函数

void NS_RadioInit( uint32_t freq, int8_t power, uint32_t txTimeout, uint32_t rxTimeout)
{
    
    
	 NS_RadioEventsInit();//无线射频模块注册事件回调函数
     NS_RadioSetTxRxConfig( freq, power, txTimeout );
	 Radio.Rx( rxTimeout );//设置LoRa模块为接收模式,同时设置超时时间,必要步骤
}

初始化分三大步骤,第一步对无线射频模块注册事件回调函数,第二步设置载波频率和发射功率以及进行发射与接收的参数初始化,第三步设置LoRa模块为接收模式和超时时间

2、uint16_t ReadRadioRxBuffer( uint8_t *payload) 无线射频接收函数

uint16_t ReadRadioRxBuffer( uint8_t *payload)
{
    
    
	  uint16_t LengthTemp;
	  LengthTemp = LoRaBufferSize;
	  if(LengthTemp <= 0)
	  {
    
    
        return 0;
	  }
	  LoRaBufferSize = 0;
    //payload = LoRaBuffer;
	  memcpy( payload, LoRaBuffer, LengthTemp );
	  return LengthTemp;
}

通过LoRa无线射频技术接收到的信息,调用ReadRadioRxBuffer函数可以把接收到的数据存储到payload指针局部变量中。

3、Radio.Send( uint8_t *buffer, uint8_t size ) 无线射频发送函数

void SX1276Send( uint8_t *buffer, uint8_t size )
{
    
    
    uint32_t txTimeout = 0;

    switch( SX1276.Settings.Modem )
    {
    
    
    case MODEM_FSK:
        {
    
    
            SX1276.Settings.FskPacketHandler.NbBytes = 0;
            SX1276.Settings.FskPacketHandler.Size = size;

            if( SX1276.Settings.Fsk.FixLen == false )
            {
    
    
                SX1276WriteFifo( ( uint8_t* )&size, 1 );
            }
            else
            {
    
    
                SX1276Write( REG_PAYLOADLENGTH, size );
            }

            if( ( size > 0 ) && ( size <= 64 ) )
            {
    
    
                SX1276.Settings.FskPacketHandler.ChunkSize = size;
            }
            else
            {
    
    
                memcpy1( RxTxBuffer, buffer, size );
                SX1276.Settings.FskPacketHandler.ChunkSize = 32;
            }

            // Write payload buffer
            SX1276WriteFifo( buffer, SX1276.Settings.FskPacketHandler.ChunkSize );
            SX1276.Settings.FskPacketHandler.NbBytes += SX1276.Settings.FskPacketHandler.ChunkSize;
            txTimeout = SX1276.Settings.Fsk.TxTimeout;
        }
        break;
    case MODEM_LORA:
        {
    
    
            if( SX1276.Settings.LoRa.IqInverted == true )
            {
    
    
                SX1276Write( REG_LR_INVERTIQ, ( ( SX1276Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
                SX1276Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
            }
            else
            {
    
    
                SX1276Write( REG_LR_INVERTIQ, ( ( SX1276Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
                SX1276Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
            }

            SX1276.Settings.LoRaPacketHandler.Size = size;

            // Initializes the payload size
            SX1276Write( REG_LR_PAYLOADLENGTH, size );

            // Full buffer used for Tx
            SX1276Write( REG_LR_FIFOTXBASEADDR, 0 );
            SX1276Write( REG_LR_FIFOADDRPTR, 0 );

            // FIFO operations can not take place in Sleep mode
            if( ( SX1276Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
            {
    
    
                SX1276SetStby( );
                DelayMs( 1 );
            }
            // Write payload buffer
            SX1276WriteFifo( buffer, size );
            txTimeout = SX1276.Settings.LoRa.TxTimeout;
        }
        break;
    }

    SX1276SetTx( txTimeout );
}

在sx1276-board.c文件中将SX1276Send(uint8_t *buffer, uint8_t size )赋值给Radio结构体中的void ( *Send )( uint8_t *buffer, uint8_t size );从而完成LoRa信息的发射信息。

4、编写OnTxDone()、 OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )、 OnTxTimeout( void )、 OnRxTimeout( void )、 OnRxError( void )函数实现RadioEvents_t结构体的抽象函数

void OnTxDone( void )
{
    
    
    Radio.Sleep( );
    Radio.Rx( RX_TIMEOUT_VALUE );
}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
    
    
    Radio.Sleep( );
    LoRaBufferSize = size;
    memcpy( LoRaBuffer, payload, LoRaBufferSize );
    RssiValue = rssi;
    SnrValue = snr;
    Radio.Rx( RX_TIMEOUT_VALUE );
}

void OnTxTimeout( void )
{
    
    
    Radio.Sleep( );
	Radio.Rx( RX_TIMEOUT_VALUE );
}

void OnRxTimeout( void )
{
    
    
    Radio.Sleep( );
	Radio.Rx( RX_TIMEOUT_VALUE );
}

void OnRxError( void )
{
    
    
    Radio.Sleep( );
	Radio.Rx( RX_TIMEOUT_VALUE );
}

通过编写回调函数实现LoRa消息的收发功能

在LoRa的实验中,主要学会应用RadioInit(),Radio.Send(),ReadRadioRxBuffer() 这三个函数就可以实现LoRa的收发控制实验。如需要稳定准确的消息传输,可添加网络ID、设备地址address、CRC校验等封装成特定的消息报文进行传输可参考这里

猜你喜欢

转载自blog.csdn.net/a6662580/article/details/123461009
今日推荐