LoRa接收功能的目的是接收来自无线上的LORA信号,当芯片接收到无线数据后,会通过芯片的IRQ中断引脚触发MCU,进而MCU可通过SPI接口操作寄存器读取接收到的无线数据
所有LoRa数据的收发程序都需要调用SX1276LoRaProcess函数,
uint32_t SX1276LoRaProcess( void )
{uint32_t result = RF_BUSY;switch( RFLRState ){case RFLR_STATE_IDLE:break;case RFLR_STATE_RX_INIT:SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |//RFLR_IRQFLAGS_RXDONE |//RFLR_IRQFLAGS_PAYLOADCRCERROR |RFLR_IRQFLAGS_VALIDHEADER |RFLR_IRQFLAGS_TXDONE |RFLR_IRQFLAGS_CADDONE |//RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |RFLR_IRQFLAGS_CADDETECTED;SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );if( LoRaSettings.FreqHopOn == true ){SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );}else{SX1276LR->RegHopPeriod = 255;}SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );// RxDone RxTimeout FhssChangeChannel CadDoneSX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;// CadDetected ModeReadySX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );if( LoRaSettings.RxSingleOn == true ) // Rx single mode{SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );}else // Rx continuous mode{SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER );}memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE );PacketTimeout = LoRaSettings.RxPacketTimeout;RxTimeoutTimer = GET_TICK_COUNT( );RFLRState = RFLR_STATE_RX_RUNNING;break;case RFLR_STATE_RX_RUNNING:if( DIO0 == 1 ) // RxDone{RxTimeoutTimer = GET_TICK_COUNT( );if( LoRaSettings.FreqHopOn == true ){SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );}// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );RFLRState = RFLR_STATE_RX_DONE;}if( DIO2 == 1 ) // FHSS Changed Channel{RxTimeoutTimer = GET_TICK_COUNT( );if( LoRaSettings.FreqHopOn == true ){SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );}// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );// DebugRxGain = SX1276LoRaReadRxGain( );}if( LoRaSettings.RxSingleOn == true ) // Rx single mode{if( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ){RFLRState = RFLR_STATE_RX_TIMEOUT;}}break;case RFLR_STATE_RX_DONE:SX1276Read( REG_LR_IRQFLAGS, &SX1276LR->RegIrqFlags );if( ( SX1276LR->RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR ){// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );if( LoRaSettings.RxSingleOn == true ) // Rx single mode{RFLRState = RFLR_STATE_RX_INIT;}else{RFLRState = RFLR_STATE_RX_RUNNING;}break;}{uint8_t rxSnrEstimate;SX1276Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate );if( rxSnrEstimate & 0x80 ) // The SNR sign bit is 1{// Invert and divide by 4RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2;RxPacketSnrEstimate = -RxPacketSnrEstimate;}else{// Divide by 4RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2;}}SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );if( LoRaSettings.RFFrequency < 860000000 ) // LF{ if( RxPacketSnrEstimate < 0 ){RxPacketRssiValue = RSSI_OFFSET_LF + ( ( double )SX1276LR->RegPktRssiValue ) + RxPacketSnrEstimate;}else{RxPacketRssiValue = RSSI_OFFSET_LF + ( 1.0666 * ( ( double )SX1276LR->RegPktRssiValue ) );}}else // HF{ if( RxPacketSnrEstimate < 0 ){RxPacketRssiValue = RSSI_OFFSET_HF + ( ( double )SX1276LR->RegPktRssiValue ) + RxPacketSnrEstimate;}else{ RxPacketRssiValue = RSSI_OFFSET_HF + ( 1.0666 * ( ( double )SX1276LR->RegPktRssiValue ) );}}if( LoRaSettings.RxSingleOn == true ) // Rx single mode{SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );if( LoRaSettings.ImplicitHeaderOn == true ){RxPacketSize = SX1276LR->RegPayloadLength;SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength );}else{SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );RxPacketSize = SX1276LR->RegNbRxBytes;SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes );}}else // Rx continuous mode{SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr );if( LoRaSettings.ImplicitHeaderOn == true ){RxPacketSize = SX1276LR->RegPayloadLength;SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );SX1276ReadFifo( RFBuffer, SX1276LR->RegPayloadLength );}else{SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );RxPacketSize = SX1276LR->RegNbRxBytes;SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );SX1276ReadFifo( RFBuffer, SX1276LR->RegNbRxBytes );}}if( LoRaSettings.RxSingleOn == true ) // Rx single mode{RFLRState = RFLR_STATE_RX_INIT;}else // Rx continuous mode{RFLRState = RFLR_STATE_RX_RUNNING;}result = RF_RX_DONE;break;case RFLR_STATE_RX_TIMEOUT:RFLRState = RFLR_STATE_RX_INIT;result = RF_RX_TIMEOUT;break;case RFLR_STATE_TX_INIT:SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );if( LoRaSettings.FreqHopOn == true ){SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |RFLR_IRQFLAGS_RXDONE |RFLR_IRQFLAGS_PAYLOADCRCERROR |RFLR_IRQFLAGS_VALIDHEADER |//RFLR_IRQFLAGS_TXDONE |RFLR_IRQFLAGS_CADDONE |//RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |RFLR_IRQFLAGS_CADDETECTED;SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );}else{SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |RFLR_IRQFLAGS_RXDONE |RFLR_IRQFLAGS_PAYLOADCRCERROR |RFLR_IRQFLAGS_VALIDHEADER |//RFLR_IRQFLAGS_TXDONE |RFLR_IRQFLAGS_CADDONE |RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |RFLR_IRQFLAGS_CADDETECTED;SX1276LR->RegHopPeriod = 0;}SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );// Initializes the payload sizeSX1276LR->RegPayloadLength = TxPacketSize;SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength );SX1276LR->RegFifoTxBaseAddr = 0x00; // Full buffer used for TxSX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr );SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr;SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );// Write payload buffer to LORA modemSX1276WriteFifo( RFBuffer, SX1276LR->RegPayloadLength );// TxDone RxTimeout FhssChangeChannel ValidHeader SX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_01;// PllLock Mode ReadySX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_01 | RFLR_DIOMAPPING2_DIO5_00;SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );SX1276LoRaSetOpMode( RFLR_OPMODE_TRANSMITTER );RFLRState = RFLR_STATE_TX_RUNNING;break;case RFLR_STATE_TX_RUNNING:if( DIO0 == 1 ) // TxDone{// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );RFLRState = RFLR_STATE_TX_DONE; }if( DIO2 == 1 ) // FHSS Changed Channel{if( LoRaSettings.FreqHopOn == true ){SX1276Read( REG_LR_HOPCHANNEL, &SX1276LR->RegHopChannel );SX1276LoRaSetRFFrequency( HoppingFrequencies[SX1276LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] );}// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );}break;case RFLR_STATE_TX_DONE:// optimize the power consumption by switching off the transmitter as soon as the packet has been sentSX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );RFLRState = RFLR_STATE_IDLE;result = RF_TX_DONE;break;case RFLR_STATE_CAD_INIT: SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT |RFLR_IRQFLAGS_RXDONE |RFLR_IRQFLAGS_PAYLOADCRCERROR |RFLR_IRQFLAGS_VALIDHEADER |RFLR_IRQFLAGS_TXDONE |//RFLR_IRQFLAGS_CADDONE |RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL; // |//RFLR_IRQFLAGS_CADDETECTED;SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );// RxDone RxTimeout FhssChangeChannel CadDoneSX1276LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00;// CAD Detected ModeReadySX1276LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );RFLRState = RFLR_STATE_CAD_RUNNING;break;case RFLR_STATE_CAD_RUNNING:if( DIO3 == 1 ) //CAD Done interrupt{ // Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );if( DIO4 == 1 ) // CAD Detected interrupt{// Clear IrqSX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED );// CAD detected, we have a LoRa preambleRFLRState = RFLR_STATE_RX_INIT;result = RF_CHANNEL_ACTIVITY_DETECTED;} else{ // The device goes in Standby Mode automatically RFLRState = RFLR_STATE_IDLE;result = RF_CHANNEL_EMPTY;}} break;default:break;} return result;
}
以上程序是LORA芯片的状态处理程序,数据能够正常收发对传数据的前提时,收发接到的相关LORA参数需要全部一致。
对于接收功能,需要调用以下程序进行接收,当程序返回的数据长度大于0时,代表收到无线数据,收到的无线数据将拷贝到pbuf的缓存内。
unsigned char LORA_Recvframe(unsigned char *pbuf)
{unsigned char rxlen ,RFState;RFState=(tRFProcessReturnCodes)SX1276LoRaProcess();if(RFState==RF_RX_DONE){SX1276LoRaGetRxPacket( pbuf, &rxlen );int rssi=SX1276LoRaGetPacketRssi();int channel=SX1276LoRaGetPacketRxChannel();return rxlen;}return 0;
}
LORA_Recvframe函数必须在需要接收的实际持续调用该函数,直到返回值大于0为止
在发送模式下,仅在需要发送数据包数据的时候才会启动射频模块、PLL模块及PA模块,
这样可以优化功率消耗率。
通过发送TX模式请求,开始数据发送。
一旦完成数据发送,则发出TxDone中断请求,芯片回到待机模式。
发送操作完成后,可以手动将无线设备设置为睡眠模式或重新向FIFO数据缓存写入数
据,以便稍后再次进行Tx操作。
对于发送端,需要实现以下功能的函数
unsigned char LORA_Sendframe(unsigned char *pdat, unsigned char len, int freq,int bw,int sf)
{SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );//设置芯片位standby模式SX1276LoRaSetSpreadingFactor( Sf ); //设置扩频因子SX1276LoRaSetSignalBandwidth( Bw );//设置带宽SX1276LoRaSetErrorCoding( 1);SX1276LoRaSetRFFrequency(freq);//设置通信频率单位hzSX1276LoRaSetTxPacket( pdat, len );//调用该函数将带发送的数据拷贝到芯片的fifo中do{}while(SX1276LoRaProcess()!=RF_TX_DONE);//等待发送完成return 1;
}
上一篇:VUEElement案例实战
下一篇:分布式一致性与共识算法(一)