本方案是一個基于FPGA的二進制時鐘,使用GPS作為時間參考。
歷史上準確測量時間提出了許多挑戰(zhàn)。只有約翰哈里森設計了一個可靠的時鐘,它可以在格林威治子午線保持參考時間,從而能夠在1700年代進行準確的導航以及繪制尚未開發(fā)的海洋和陸地的圖表。
今天,我們生活在日益互聯(lián)的世界中,準確的時間參考同樣重要。如果沒有一個共同的時間參考,當我們從一個信號塔傳遞到另一個信號塔時,信號塔就無法輕松同步代碼和切換呼叫。同樣,沒有共同時間參考的時間戳業(yè)務和銀行交易也可能具有挑戰(zhàn)性,并成為事件順序的仲裁噩夢。
當然,可用的最準確的時鐘是原子鐘,但遺憾的是,它們也是最昂貴的,這限制了機構使用它們的能力。
然而,有一個時間參考精確到+/-10ns,可以從空中免費提取,這就是全球導航衛(wèi)星系統(tǒng)提供的時間參考。當然,其中最著名的是全球定位系統(tǒng)(GPS),盡管有幾個,例如GLONASS和Galileo。
所有這些衛(wèi)星都包含原子鐘,這使我們能夠實現(xiàn)跨系統(tǒng)的高度準確的時間參考。
在這個項目中,我們將使用GPS接收器Pmod接收GPS信號并對其進行處理,以便我們可以在二進制時鐘上顯示時間。
為此,我們將使用Vivado和SDK,這將是我們使用SDK的最后一個項目,因為Vitis可用。
維瓦多設計
要開始設計,我們需要做的第一件事是安裝Digilent庫,使我們能夠配置PmodGPS/
該庫支持在Vivado和SDK的硬件和軟件開發(fā)中使用Pmod。
為此,請在我們的Vivado項目中選擇、項目選項并選擇IP并導航到新的IP存儲庫。
我們還需要一些東西來驅動NeoPixel顯示器,同樣對于之前的項目,我在這里將一個neopixelIP模塊推送到我的github
然后我們就可以創(chuàng)建一個Vivado項目,該項目將利用這些IP模塊與PmodGPS通信。
在新的Vivado項目中,我們需要以下IP
ZynqPS-為最小化配置
PmodGPS-將在軟件控制下與PmodGPS通信
AXIBRAM控制器-使ZynqPS能夠在PL中讀取和寫入BRAM
BRAM-雙端口BRAM包含Neo像素值
NeoPixelIP-驅動NeoPixel驅動信號
處理器重置塊-為系統(tǒng)提供重置
AXI互連-使多個AXI從設備能夠連接到單個PS主設備
需要配置PS才能提供
50MHz時的結構時鐘
20MHz的結構時鐘-用于為NeoPixelIP提供時鐘
GPMasterAXI接口
已啟用結構中斷
這應該會產(chǎn)生如下所示的框圖
在生成和導出位流之前,我們還需要設置引腳的IO位置。
我將在PmodGPS的Minized上使用Pmod2,在NeoPixel驅動器上使用Pmod1我們在XDC文件中執(zhí)行此操作,如下所示。
這樣我們就可以實現(xiàn)設計并將硬件設計導出到SDK以生成所需的軟件。
軟件設計
在SDK中,我們需要根據(jù)剛剛從Vivado導出的硬件設計創(chuàng)建一個新的應用程序和BSP。
一旦在BSP中創(chuàng)建了它,我們應該會在BSPMSS文件中看到Pmod驅動程序。
對于更改,我們的軟件應用程序將是中斷驅動的。
我們的軟件解決方案將遵循的架構是
配置和初始化PmodGPS
配置和初始化BRAM控制器
配置中斷控制器并啟用來自PmodGPSUART的中斷。
等待PmodGPS鎖定信號
從PmodGPS讀取位置和時間數(shù)據(jù)
將時間轉換為二進制元素進行顯示
更新NeoPixel顯示
為了使用PmodGPS和AXIBRAM控制器,我們可以使用PmodGPS.h和xbram.h中提供的API
雖然可以使用xscugic.h提供的API配置中斷控制器
intSetupInterruptSystem(PmodGPS*InstancePtr,u32interruptDeviceID,u32interruptID){
intResult;
u16Options;
INTC*IntcInstancePtr=&intc;
XScuGic_Config*IntcConfig;
IntcConfig=XScuGic_LookupConfig(interruptDeviceID);
if(NULL==IntcConfig){
returnXST_FAILURE;
}
Result=XScuGic_CfgInitialize(IntcInstancePtr,IntcConfig,
IntcConfig-》CpuBaseAddress);
if(Result!=XST_SUCCESS){
returnXST_FAILURE;
}
XScuGic_SetPriorityTriggerType(IntcInstancePtr,interruptID,0xA0,0x3);
Result=XScuGic_Connect(IntcInstancePtr,interruptID,
(Xil_ExceptionHandler)XUartNs550_InterruptHandler,
&InstancePtr-》GPSUart);
if(Result!=XST_SUCCESS){
returnResult;
}
XScuGic_Enable(IntcInstancePtr,interruptID);
XUartNs550_SetHandler(&InstancePtr-》GPSUart,(void*)GPS_intHandler,
InstancePtr);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,IntcInstancePtr);
Xil_ExceptionEnable();
Options=XUN_OPTION_DATA_INTR|XUN_OPTION_FIFOS_ENABLE;
XUartNs550_SetOptions(&InstancePtr-》GPSUart,Options);
returnXST_SUCCESS;
}
我想做的第一件事是確保PmodGPS能夠鎖定信號并為我提供準確的位置。
當此代碼在Pmod2連接到PmodGPS的Minized上執(zhí)行時,我們會在終端上看到以下輸出,為我提供了一個位置。
為了檢查這是正確的位置,將它輸入到谷歌地圖中可以以合理的精度提供我辦公室的位置。
由于能夠鎖定GPS信號,因此更新了代碼以提供時間。這個時間被稱為協(xié)調世界時或簡稱UTC,UTC參考格林威治標準時間,目前也恰好與英國的時間相同。
時間作為浮點數(shù)從PmodGPS輸出,如下面的終端輸出所示。
為了能夠創(chuàng)建一個二進制時鐘,我們需要將其分解為以下內(nèi)容
小時幾十
小時單位
分十
分鐘單位
秒十
秒單位
這將使我們能夠使用NeoPixelArray繪制時間。
二進制時鐘顯示時間如下
在NeoPixel上,我將在陣列中間使用6x4LED陣列。
但首先我們需要將UTC時間轉換為所需的格式,我們可以使用以下方法將時間(例如153400)拆分為正確的小時、分鐘和秒分組。
然后我們可以根據(jù)二進制時間顯示的需要將每個元素分成十位和單位。
一旦我們分離了數(shù)字,我們就需要將值轉換為二進制值,為此我創(chuàng)建了一個簡單的子例程
這個函數(shù)返回一個代表二進制數(shù)的四位向量,對于這個例子,我們不需要超過4位。
由于NeoPixel陣列被視為一個長64NeoPixel元素,因此對于每個計數(shù)位置,我們只需要更改LED偏移位置。
根據(jù)該位是否已設置,LED的顏色是否會發(fā)生變化,設置的位為綠色,否則為藍色。
我使用下面的代碼來確定設置LED的值,因為二進制轉換函數(shù)返回一個指針。
當我把所有這些放在一起時,一旦PmodGPS鎖定信號,二進制時鐘就會按預期運行。
確認
對于許多人來說,讀取二進制時鐘可能與傳統(tǒng)時鐘不同。因此,通過終端查看NeoPixel顯示和UTC時間輸出,我們可以驗證顯示是否正確。
解碼后的時間看起來是正確的。
結論
該項目演示了我們?nèi)绾屋p松快速地將GPS用于導航以外的系統(tǒng),并創(chuàng)建一個有趣的示例,該示例可用作顯示器等。
-
FPGA
+關注
關注
1629文章
21729瀏覽量
602977 -
gps
+關注
關注
22文章
2894瀏覽量
166180 -
二進制
+關注
關注
2文章
795瀏覽量
41643
發(fā)布評論請先 登錄
相關推薦
評論