One way單向通訊Hopping跳頻應用
本篇介紹一種適用於單向傳輸One way跳頻應用,適用於遙控器應用上做多次重傳已達避開干擾的介紹
當發射端或接收端是移動的情況下,通訊的狀況有時會不好,其原因有可能是訊號干擾、天線效應、多路徑效應、訊號衰落等原因,為了提高在有效通訊距離內的傳輸品質,本篇提出一個基於資料重傳及跳頻的傳輸機制。
由於單向傳輸系統的發射端在發射資料後,無法得知資料是否有正確的送到接收端,為了減少資料傳輸錯誤或遺失的可能,通常可經由發射端可將資料重複多次傳輸。
另外,因為干擾、天線效應、多路徑效應在不同的頻率下的影響程度不同,使用多個頻率的傳輸效果通常會比使用固定頻率的傳輸效果佳
資料重傳及跳頻機制:
圖1==> 是一個四頻率跳頻的單向跳頻傳輸協定的例子,發射端每隔一段時間發射一次資料,相同的資料會在四個頻率各發射一次
(即每筆資料都傳送四次),每發射一次資料後即變換一次頻率,也就是利用不同的頻道傳送相同的資料來減少資料錯誤的可能。
A=TX端;B=RX端
整個傳輸過個分成兩個階段:
1. 同步階段
2. 資料接收階段
在同步階段中,接收端會去尋找發射端,如圖2 所示,接收端會在每個頻率等待發射端發射四次的時間,當接收端收到發射端的
封包時,就會進入"資料傳輸階段"。
當發射端開始發射資料後,只要有一個頻道是可通訊的狀況下,接收端的最大反應時間為「頻道數量 x Data report time」,若
頻道數量越大,則最大反應時間就會越長。
資料接收階段:
接收端每收到一個正確的封包後,"必須設定時間"來對齊發射端,避免接收端和發射端的時間差異越來越大。當接收端等待超過
一個slot time(間隙時間) 時,代表資料傳輸發生錯誤,接收端必須主動跳到下一個頻道以接收資料。為了節省電源,接收端可以在沒有傳輸活動的時間不進入接收模式,如圖3 中的Idle time。
當同步失效:
當接收端靠近一個很大的干擾源或是距離發射端太遠時,接收端會一直接收不到發射端的資料,當這個情形發生時,有可能會因
為兩邊的時序不同而造成當干擾源消失或回到傳輸距時仍然無法通訊,此時接收端必須回到同步階段。一般而言我們可以定為連
續兩筆資料傳輸時間(即 8 個slot time)都沒有收到正確的封包時,就回到同步階段,如圖4
Demo Code:<RC_A9139-F6_Ux0_433MHz Band Ref. Code for FIFO mode with Slave Bootloader CL=20pF V0.2.zip>
底下使用Amiccom A9139F6 51核Soc製作相關one way的跳頻
此code使用timer的方式來設計相關的slot time
One Cycle timer~=1ms
#define t0hrel 1067 //1ms @12.8MHz #define TIMERPERIOD 400 #define TIMERTIMEOUT 300 #define CHANNELNUM 4
void Timer0ISR ( void ) interrupt 1 { TR0=0; TF0 = 0; // Clear Timer0 interrupt TH0 = (65536-t0hrel)>>8; // Reload Timer0 high byte,low byte TL0 = 65536-t0hrel; TR0=1; timer++; if (timer>TIMERPERIOD)//400ms { timer=0; HoppingCount=HoppingCount+1; } if(HoppingCount==CHANNELNUM||Hoppingflag==1) HoppingCount=0; if (timer>TIMERTIMEOUT)//300ms f_Timeout=1; if (timer==2) Slot_TX=1; }
TX端:
Slot_TX為timer=2時Set "1",且每經400ms timer清0一次,也就是每400ms發送一包Tx,共發4包
第1包channel=0
第2包channel=100
第3包channel=200
第4包channel=300
#define MAXCHANNEL 400//4個頻點切換
while ( 1 ) { if(Slot_TX) { Slot_TX = 0; RFLIB_StrobeCmd ( CMD_TX ); Delay10us(1); while(GIO2);//wait WTR GO Low channel=channel+100; if(channel==MAXCHANNEL) { channel=0; } RFLIB_SetCH(channel);//調整頻率 } }
Rx端:
開機後當Timer=1且HoppingCount=0,也就是選用頻點1時,HoppingCount每400ms +1次,也就是每400ms切換一新頻點
if(timer==1&&HoppingCount==0) { SETGPIO ( GPIO1_ARCWTR, GPIO2_RXD, CKO_DCK, ENABLE, SelectConfig ); RFLIB_StrobeCmd(CMD_STBY); RFLIB_StrobeCmd(CMD_RX);//Enter RX Mode SETGPIO ( GPIO1_FSYNC, GPIO2_RXD, CKO_DCK, ENABLE, SelectConfig );//Set GPIO1=Fsync mode(ID同步禎) Delay10us(1); f_Timeout=0;
如果GIO1超過300ms尚未拉High,表示Rx mode超過300ms都還沒收到第一包發來的ID Code,此時觸發f_Timeout
當RX是剛開機第一次連接Flag_FirstLink=1,且Rx端收到正確的第1包 Packect時,需做Timer對齊動作Clr_timer();
若RX並非FirstLink就走else部分,舉起Hoppingflag=1來歸零HoppingCount=0,使系統回到PLL mode,並跳到下一頻點channel+100,等待下次重新進入RX mode(timer=1),timer over 400ms auto clear 0,也就是配合Tx端每400ms,重新進入一次Rx mode
while((GIO1==0) && (f_Timeout==0));Wait ID sync ok if (f_Timeout) { f_Timeout = 0; if (Flag_FirstLink) { Err_Loss = 0; while(GIO1==0);//wait tx連續發4個頻點,直到收到ID同步碼 Clr_timer(); SETGPIO ( GPIO1_ARCWTR, GPIO2_RXD, CKO_DCK, ENABLE, SelectConfig ); while(GIO1);//Wait WTR Go LOW,表示完成RX Flag_FirstLink = 0; HoppingCount=0; } else { Hoppingflag=1; RFLIB_StrobeCmd(CMD_PLL); SETGPIO ( GPIO1_ARCWTR, GPIO2_RXD, CKO_DCK, ENABLE, SelectConfig ); channel=channel+100; if(channel==MAXCHANNEL) { Err_Loss++;//若TX發的4包都沒收到,Err_Loss累加 channel=0; } RFLIB_SetCH(channel); } }
若沒有f_Timeout表示正常接收到TX資料,一樣需要對齊Timer時間,並完成本次RX 接收GIO1=WTR Go Low後進入PLL Mode,接收packet
若沒有f_Timeout表示該頻點沒有受到干擾,因此就不進行更換頻點,而是繼續用此頻點通訊,直到出現RX超時才會進行更換頻點
else { Hoppingflag=0; Clr_timer(); SETGPIO ( GPIO1_ARCWTR, GPIO2_RXD, CKO_DCK, ENABLE, SelectConfig ); while(GIO1); RFLIB_StrobeCmd(CMD_PLL); RxPacket(); }
同步Clock階段:
透過稍微調整的初始計數來重置和重新啟動Timer0,並將timer從60開始數。
void Clr_timer(void) { TR0 = 0; TH0 = (65536-1067-5)>>8; // Reload Timer0 high byte,low byte TL0 = 65536-1067-5; timer=TIMERINIT;//60 TR0 = 1; }
若在接收資料的過程中該設定的頻率持續沒有收到資料,此時就會更換下一個頻率繼續接收資料,如果此頻率有收到資料(ID Sync OK),之後就持續用此頻率繼續收下一次的資料,如下圖,假設第1頻點有收到,接下來RX就都會用頻道1號接收,而TX還是會在每個頻點都打相同資料包,連續打4包