前言
调试的过程中碰到的问题基本都是以前没有遇到过的,而且需要对整个协议栈及射频方面的工作流程较熟悉才能找到问题的原因,需要多读SX1276的数据手册以及与射频芯片的物理层通信例程和MAC层通信例程进行对比相结合。
正文
发送失败
LoRa 模块在进行 模式切换时,比如TX 切换到RX模式,需要先将设备切换到standby模式
CRC 校验失败,然后程序陷入死循环
按逻辑来讲,CRC校验失败,应该进行的操作是吧校验失败的这个数据包丢弃,然后重启接收机(芯片每次接收完成都应该重启SX1276)
但是,程序一旦接收CRC校验失败就陷入循环,通过调试发现,原来是开启了一个定时器,定时时间为0,然后定时器的处理函数中又开启了此定时器,定时时间依旧没0,所以陷入了死循环。
这个定时器就是:
TimerStart( &RxTimeoutSyncWord );
在接收处理函数void SX1276OnDio0Irq( void ) 中的CRC校验失败分支的处理代码中,以及定时器对应的处理函数void SX1276OnTimeoutIrq( void )中都开启了这个定时器。
如果是单个接收模式下,开启这个定时器并没有什么问题,但是在我调试的代码中,我开始的是连续接收模式,此模式根本没有同步字接收超时继续开着接收模式就可以了,并不需要特别的处理,可以不需要处理,
而官方SDK中:
void SX1276OnDio0Irq( void )
{
.........
if( SX1276.Settings.Fsk.CrcOn == true )
{
irqFlags = SX1276Read( REG_IRQFLAGS2 );
if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
{
// Clear Irqs
SX1276Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
RF_IRQFLAGS1_PREAMBLEDETECT |
RF_IRQFLAGS1_SYNCADDRESSMATCH );
SX1276Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
TimerStop( &RxTimeoutTimer );
if( SX1276.Settings.Fsk.RxContinuous == false )
{
TimerStop( &RxTimeoutSyncWord );
SX1276.Settings.State = RF_IDLE;
}
else
{
// Continuous mode restart Rx chain
SX1276Write( REG_RXCONFIG, SX1276Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
}
if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
{
RadioEvents->RxError( );
}
SX1276.Settings.FskPacketHandler.PreambleDetected = false;
SX1276.Settings.FskPacketHandler.SyncWordDetected = false;
SX1276.Settings.FskPacketHandler.NbBytes = 0;
SX1276.Settings.FskPacketHandler.Size = 0;
break;
}
}
..........
}
void SX1276OnTimeoutIrq( void )
{
switch( SX1276.Settings.State )
{
case RF_RX_RUNNING:
if( SX1276.Settings.Modem == MODEM_FSK )
{
SX1276.Settings.FskPacketHandler.PreambleDetected = false;
SX1276.Settings.FskPacketHandler.SyncWordDetected = false;
SX1276.Settings.FskPacketHandler.NbBytes = 0;
SX1276.Settings.FskPacketHandler.Size = 0;
// Clear Irqs
SX1276Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
RF_IRQFLAGS1_PREAMBLEDETECT |
RF_IRQFLAGS1_SYNCADDRESSMATCH );
SX1276Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
if( SX1276.Settings.Fsk.RxContinuous == true )
{
// Continuous mode restart Rx chain
SX1276Write( REG_RXCONFIG, SX1276Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
TimerStart( &RxTimeoutSyncWord );
}
else
{
SX1276.Settings.State = RF_IDLE;
TimerStop( &RxTimeoutSyncWord );
}
}
if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
{
RadioEvents->RxTimeout( );
}
break;
................
}
}
这两处代码有着类似的才做,但是RxTimeoutSyncWord
这个定时器会进入void SX1276OnTimeoutIrq( void )
这个函数,而这个函数中又会重新开启RxTimeoutSyncWord
这个定时器,导致死循环,所以在这里,应该讲两处的开启定时器的操作去掉(TimerStart( &RxTimeoutSyncWord );
),这样程序逻辑才正常。
CRC 校验失败,然后在单步模式下,CRC一直失败
这个问题不是程序的问题,原因是因为我在单步模式下看CRC做接收,然后我的单步调试打断了射频芯片的正常工作。嗯、、就是这样,这个故事告诉我们,不要手贱。