基于Spartan-6的高速數據采集、處理和實(shí)時(shí)傳輸研究
擇一種最佳的設計方案。表 1為不同抽取倍數下的帶寬和混疊衰減規格:
本文引用地址:http://dyxdggzs.com/article/201612/326826.htm最后確定選擇CIC2濾波器抽取倍數為15,CIC5抽取倍數為2,RCF抽取倍數為2就可以滿(mǎn)足系統設計的要求。
3.2.3 可變系數RCF濾波器參數設置
根據2.2.1節設計得到的RCF抽取倍數為30,可以根據式來(lái)計算得到抽取濾波器的抽頭數為150。

其中,為60MHz,
為15,
為CIC5濾波器抽取降速后的頻率也即2MHz,當輸入通道模式時(shí)單通道實(shí)模式時(shí)為1。對可變系數的RCF濾波器進(jìn)行編程設置時(shí)需要先向地址0x30C寫(xiě)入整數 149(
=59)。然后濾波器的響應
逐一寫(xiě)入到地址0x000~0xFF中。這樣就完成了RCF寄存器的編程設置。
3.2.4 AD6620工作模式寄存器編程
對頻率變換單元、固定系數的CIC2和CIC5以及RCF濾波器變化進(jìn)行編程設置后,要使AD6620正常工作還需要對其工作方式和相關(guān)寄存器進(jìn)行配置。AD6620的工作方式主要由地址0x300H的寄存器中低四位決定,其中,bit0=1時(shí)系統處于軟復位狀態(tài),bit0=0則處于正常狀態(tài);bit1=1時(shí)系統處于雙通道實(shí)數輸入模式;bit2=1時(shí)系統處于單通道復數輸入模式;如果bit0~bit2都是0,那么系統處于單通道實(shí)數輸入模式;bit3=1/0為時(shí)鐘主從工作模式。因此,當各寄存器配置完成后需要將寄存器bit0拉低,也即置為0狀態(tài)使其脫離軟復位狀態(tài),進(jìn)入正常工作模式。另外,在本文中AD6620讀寫(xiě)內部寄存器是采用的異步讀寫(xiě)時(shí)序,數據輸出是并行16位輸出模式。 總的來(lái)說(shuō),采用FPGA實(shí)現AD6620初始化的過(guò)程如下:
1)首先判斷AD6620有沒(méi)有經(jīng)過(guò)硬件復位,如果沒(méi)有經(jīng)過(guò)硬件復位而又要實(shí)現系統復位,那么可以通過(guò)程序去編程地址0x300H的寄存器的bit0位置為1,使得AD6620處于軟件復位狀態(tài),這樣就可以對非動(dòng)態(tài)的寄存器進(jìn)行相關(guān)編程;
2)對NCO單元、CIC2、CIC5濾波器的抽取倍數和系數進(jìn)行編程,將相應的控制系數寫(xiě)入相對應的地址寄存器中;
3)對RCF濾波器系數進(jìn)行編程,分別向地址0x000H~0xFF中寫(xiě)入這150個(gè)抽頭系數,剩下的寫(xiě)入0。
4)對AD6620所有配置工作完成后,必須向地址0x300H的bit0寫(xiě)入0,使其脫離軟復位狀態(tài),這樣AD6620才可以在所配置工作方式下對輸入的數據進(jìn)行處理?! ?/p>
4.實(shí)時(shí)數據傳輸模塊
基于USB2.0的數據傳輸設計主要包括以下幾個(gè)部分:(1)基于EZ-USB FX2的硬件電路設計(2)EZ-USB FX2系列器件CY7C68013A的固件程序(設置CY7C68013A工作模式、傳輸方式等,需要對其內部寄存器進(jìn)行相關(guān)配置),主要通過(guò)Keil C51軟件進(jìn)行開(kāi)發(fā)。
4.1 實(shí)時(shí)數據傳輸部分的硬件設計
實(shí)時(shí)數據傳輸部分(USB2.0的數據傳輸)的硬件設計方案如圖10所示,USB模塊與FPGA間的連線(xiàn)如圖11所示。
在高速數據傳輸部分采用了Cypress公司的EZ-USB FX2 CY7C68013A芯片,采用單片USB 2.0外設可以避免用FPGA直接實(shí)現USB通信協(xié)議時(shí)可靠性低的問(wèn)題。在數據采集、傳輸以及測試過(guò)程中,CY7C68013A作為從機,負責將FPGA發(fā)送給它的基帶數據,利用其16位SLAVE FIFO(關(guān)于SLAVE FIFO的傳輸示意圖如圖所示)將數據緩沖發(fā)送給上位機。在SLAVE FIFO數據傳輸中,上位機應用程序、固件程序和FPGA程序都非常關(guān)鍵,要配合好才能完成數據的高速數據傳輸。在這個(gè)系統中,FPGA起著(zhù)主控制器作用,CY7C68013A則相當于一個(gè)從設備。具體的工作流程是:FPGA把接收過(guò)來(lái)的16位數字基帶信號發(fā)送給CY7C68013A,CY7C68013A以SLAVE FIFO的方式將這些數據緩沖,并以批量數據傳輸的方式發(fā)送給上位機,上位機接收到這些數據后加以存儲和顯示。
4.2 CY7C68013A的固件程序設計
固件程序是指運行在設備CPU中的程序,只有在該程序運行時(shí),外設才能稱(chēng)之為具有給定功能的外部設備。固件程序負責初始化單元,重新設置設備。主要包括設備描述符信息、設備功能代碼。設備描述信息描述USB設備的一半特性和配置,如設備類(lèi)別、接口配置、VID和PID等。主機在設備列舉時(shí)要獲取USB設備的描述符,從而獲得設備的配置信息和相關(guān)驅動(dòng)信息。用戶(hù)可以通過(guò)修改固件中的描述符來(lái)改變設備的特性。設備功能代碼有設備的功能需求決定。通信控制功能代碼執行主機請求分析處理和數據交換處理功能。
采用ARM公司的Keil C51 uVision4.02開(kāi)發(fā)CY7C68013A的固件程序。為了簡(jiǎn)化固件編程,CYPRESS提供了固件編程框架,在此基礎上添加我們所需要的配置代碼即可完成軟件編程?! ?/p>
復位上電時(shí),固件先初始化一些全局變量,然后調用初始化函數ID_Init(),初始化設備一直到?jīng)]有配置的狀態(tài)和打開(kāi)中斷,循環(huán)1s后枚舉,直到端點(diǎn)0接收到SETUP包退出循環(huán),進(jìn)入循環(huán)語(yǔ)句while,執行任務(wù)函數,函數包括:
(a)TD_POLL()用戶(hù)任務(wù)調度函數;
(b)如果發(fā)現USB設備請求,則執行對應的USB請求;
(c)如果發(fā)現USB空閑置位,則調用TD_Suspend()這個(gè)掛起函數,調用成功后則內核掛起,直到出現USB遠程喚醒信號,調用TD_Resume(),內核喚醒后重新進(jìn)入while循環(huán)。
固件框架程序需要以下幾個(gè)文件:
(1)FX2.h:庫函數申明,以及變量、宏定義、數據類(lèi)型定義;
(2)Fxregs.h:FX2LP寄存器頭文件;
(3)Fw.c:固件框架源文件;
(4)Periph.c:用戶(hù)調度函數、用戶(hù)可以修改,在不同的應用中文件名不一樣;
(5)Dscr.a51:USB描述符列表,用戶(hù)可以修改;
(6)Ezusb.lib:EZUSB庫文件;
(7)USBJmpTb.OBJ:中斷跳轉函數目標文件
這種情況下,需要在固件程序中,進(jìn)行相應的修改。在SLAVE FIFO中,特別是自動(dòng)傳輸(CY7C68013A單片機不干預數據傳輸),固件程序主要完成各個(gè)端口的初始化。因此我們要修改兩個(gè)地方:(1)USB設備描述符列表Dscr.a51,根據實(shí)際情況修改里面的端口數和傳輸方式等;(2)初始化函數void TD_Init(void)。在SLAVE FIFO這種方式下,設置EP2為4緩沖的輸出端口,EP6為4緩沖的輸入端口。
5. 上位機軟件設計
上位機應用程序是系統與用戶(hù)之間交流的接口,它通過(guò)通用驅動(dòng)程序完成對外設的控制和通信。主機端應用程序負責向FX2的FIFO發(fā)送或者接收數據。本報告中采用的固件架構是EZ-USB FX2/FX2LP(CY7C68013, 驅動(dòng)程序是Cyusb.sys。用Visual Studio2008軟件進(jìn)行上位機開(kāi)發(fā),利用C++/MFC來(lái)開(kāi)發(fā)基于對話(huà)框的應用程序,系統的主要功能模塊有:打開(kāi)USB設備、復位USB設備、系統數據測試與顯示等。
在VS2008中建立一個(gè)MFC 單文檔/對話(huà)框應用程序后,在路徑項目中包含頭文件cyapi.h和cyapi.lib所在的路徑。然后手動(dòng)導入cyapi.lib,注意是CV6_7的lib,不要導入BCB的。
開(kāi)發(fā)USB應用程序的一般工作流程如下。
1)首先要創(chuàng )建一個(gè)USB設備對象
CCyUSBDevice *USBDevice = new CCyUSBDev(Handle);括號中的Handle是USB所關(guān)聯(lián)對象的句柄,一般在MFC中直接就是m_hwnd。
2)打開(kāi)USB設備。
可以用到兩個(gè)函數open();isopen()這兩個(gè)都可以用來(lái)打開(kāi)USB設備,isopen()還可以判斷能否獲得USB設備句柄,一般來(lái)說(shuō),如果只有一個(gè)USB設備連接,可以這樣打開(kāi):
USBDevice->open(0)//打開(kāi)0號USB設備;如果要判斷,可以:
if(!USBDevice->open(0)) //打開(kāi)失敗
{messagebox("USB未連接");}
或者if(!USBDevice->Isopen())
如果連接有多個(gè)USB設備,那么可以枚舉所有的USB,用到DeviceCount()函數;具體的可以參考cybulk的例子。執行USBDevice->DeviceCount()后,返回所連接的USB設備個(gè)數:
if (USBDevice->DeviceCount()) //保證至少有一個(gè)USB設備連接
{
for (i = 0; i DeviceCount(); i++) //枚舉所有USB設備
{
USBDevice->Open(i);//打開(kāi)第i號USB設備
m_DeviceListComBox.AddString(USBDevice->DeviceName);//所選擇的當前設備名}
}
3)端點(diǎn)枚舉
在cybulk的例子中介紹了如何枚舉固件中使用的所有端點(diǎn),也就是使用多個(gè)端點(diǎn)的情況,其枚舉步驟主要包括一下幾個(gè)端點(diǎn):
(1)創(chuàng )建USB設備并打開(kāi)該設備
CCyUSBDevice *USBDevice=new CCyUSBDevice(m_hWnd);//USB設備USBDevice->Open(0);//打開(kāi)0號USB設備。
(2)獲取所用的端點(diǎn)數目
intepts = USBDevice->EndPointCount();
EndPointCount();函數返回當前所用的端點(diǎn)數+1,也就是包含了控制端點(diǎn)。例如在固件接口描述符Interface Descriptor中設置Number of end points項(第5項)的值為4,則epts的值為4+1=5。
(3)定義端點(diǎn)指針
CCyUSBEndPoint *endpt;CCyUSBEndPoint建立一個(gè)端點(diǎn)對象,可建立所有的端點(diǎn)類(lèi)型,控制端點(diǎn),bulk端點(diǎn),ISO端點(diǎn)等;
(4)枚舉端點(diǎn),并獲得其屬性:端點(diǎn)號,傳輸方向
for (i=1; i
{
endpt = USBDevice->EndPoints[i];//EndPoints-端點(diǎn)列表,最大16.EndPoints[0]指向控制端點(diǎn)(CCyControlEndPoint),未使用的端點(diǎn)設置為NULL。
if (endpt->Attributes == 2) // Bulk Attributes 判斷傳輸類(lèi)型bulk,control,等。
{
sprintf(s, "0x%02x", endpt->Address);
if (endpt->Address & 0x80) //Address--判斷傳輸方向in or out 0x8_-in;0x0_-out
{
m_InEndptComBox.AddString(s); //最高位為8,in端點(diǎn),添加到in組合框m_InEndptComBox.SetItemData(m_InEndptComBox.GetCount()-1,i);
else
{
m_OutEndptComBox.AddString(s); //否則,最高位為0,out端點(diǎn),添加到out組合框m_OutEndptComBox.SetItemData(m_OutEndptComBox.GetCount()-1,i);
}}} 這樣,就完成了某個(gè)具體端點(diǎn)的選擇。如果只需要使用一個(gè)端點(diǎn)的話(huà),那上面的代碼無(wú)疑就顯得冗長(cháng)不夠簡(jiǎn)潔了。僅使用一個(gè)端點(diǎn),可以使用EndPointOf()函數,該函數直接使用指定的端點(diǎn),返回其指針;例如,要使用端點(diǎn)2,in傳輸,那么,可以這樣:
CCyUSBDevice *USBDevice=new CCyUSBDevice(m_hWnd); //USB設備
USBDevice->Open(0); //打
評論