前言
調試的過程中碰到的問題基本都是以前沒有遇到過的,而且需要對整個協議棧及射頻方面的工作流程較熟悉才能找到問題的原因,需要多讀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做接收,然后我的單步調試打斷了射頻芯片的正常工作。嗯、、就是這樣,這個故事告訴我們,不要手賤。
文章列表