基于PXI总线的高速数字传输模块设计及正交解调的实现(三)

论文价格:0元/篇 论文用途:仅供参考 编辑:论文网 点击次数:0
论文字数:**** 论文编号:lw202380400 日期:2024-09-30 来源:论文网

  5.3 PXI数字传输模块软件面板的设计和测试结果

  本课题上层应用程序是通过VC++工具进行开发的。之所以选择VC++是因为驱动程序也是在该软件平台上编写与实现的,这样便于应用程序与底层驱动的调用与衔接。应用程序访问设备驱动程序,一般由两种方法,一种是在应用程序中直接编程访问驱动程序,第二种方法是先利用 VC 等语言编写与驱动程序的接口,将函数封装成动态链接库供其它应用程序调用。这两种方法各有利弊,前一种方法比较灵活,应用程序几乎可实现对硬件的全面操作,但这种办法需应用程序开发工具支持与驱动程序的接口,并且开发者要全面了解驱动程序和硬件结构。后一种方法灵活性差,但动态连接库写好后上层应用程序可以用几乎任何一种高级语言写。并且由于应用程序和驱动程序之间隔了一层动态连接库,因此用户可以不用太关心驱动程序的情况和硬件结构。本课题选用直接接口设计。

  直接接口与通过动态连接库实现接口,除了在接口上有区别之外,在打开设备,读写设备等方面两者是一样的。下面介绍一下接口和界面的实现步骤[40]。

  (1)定义应用程序与设备驱动程序接口所需的唯一标识号GUID。

  (2)编写接口函数。

  (3)得到与对应GUID相关的信息。

  (4)获取接口数据。

  (5)获取符号连接名长度。

  (6)获取符号连接名。

  (7)创建文件,由于任何设备在Windows中都被认为是一个文件,所以从创建完文件开始,对该设备的操作将都使用文件读写函数完成。

  (8)应用程序通过写文件函数,向设备驱动程序发送读写请求。

  根据上述步骤设计的软面板如图5-5所示。通过软面板可以实现各种模式下的数据读写功能。

  最后对设计出来的板卡进行了硬件测试,在应用程序中编写如下简单程序:

  void CPDC4000DemoDlg::OnBlockDmaPciToLocalDemo()//DMA模式输出数据

{

   unsigned char pData[0x100];//待输出的数组

   for (int i = 0; i &< 0x100; i ++)

   {

       pData[i] = i + 0x0;

   }

   m_iStatus = STATUS_BLOCK_WRITE;

   BlockDmaPciToLocal(pData, 0x100);

}

  通过逻辑分析仪测量板卡的输出波形,得到输出低8位结果见图5-6。在源程序中写入的数据为pData数组,它的取值是从0开始依次加1,因此从最低位开始往上一位走,依次为2分频。而从输出波形可以看出,输出完全符合写入的数据,数据输出的速率为16 MHz。

图5-5 PXI卡软件面板

图5-6 低8位输出结果

  5.4 本章小结

  本章详细的介绍了PCI/PXI设备驱动程序特点,以及DDK开发驱动程序的主要技术内容。本课题用DDK成功的开发出了基于PCI9054的设备驱动,并成功安装到硬件上且板卡能正常工作。

  本设计中最突出的优点是采用DDK设计驱动程序,而没有采用DS(Driver Studio)和Windriver ,因为DDK是基于汇编语言的编程方式的,其优点是可以开发核心态的真正意义上的驱动程序,开发出来的驱动程序效率是最高的。

参考文献

[1]   马嘉. PXI模块仪器系统. 计算机系统测试与控制, 1999, 7(1): 28~30

[2]   周琴. GPIB总线及应用技术. 低压电器, 2008, 1(9): 16~17

[3]   张世箕. 自动测试系统. 第一版. 成都: 电子科技大学出版社, 1990: 21~23

[4]   孙家琪. 自动测试系统. 第一版. 北京: 机械工业出版社, 1990: 36~40

[5]   Subbarao V, Wunnava, Peter Hoo. Remote Instrumentation Access&&Control (RIAC)Through Inter-Networking. IEEE Instrumentation and Measurement Technology c- onference 1999: 118~119

[6]   马怀俭. 自动测试系统. 第一版. 哈尔滨: 哈尔滨理工大学出版社, 1994: 41~45

[7]   K. Chipperfield. Exploring VXIbus Systems and Instrumentation. IEEE,1995: 217~224

[8]   马怀俭. VXI总线讲座. 电测与仪表, 1990(4): 12

[9]   万鹏. 自动测试与VXI总线自动测试系统. 山东大学学报, 1997(3):85~86

[10]   杨乐平. 一种新的模块化仪器总线标准PXI. . 测控技术, 1998(5):62~63

[11]   National Instruments. PXI Specification PCI eXtensions for Instrumentation An I- mplementation of CompactPCI, 1997:1~50

[12]   Arlene Meadows, Grey Hill. VXI技术现状及其技术规范. 国外电子测量技术, 1998(6): 3~4

[13]   杨乐平, 曾敏. VXI仪器软件技术新发展-IVI. 第八届VXI技术研讨会论文集, 1999. 25~31

[14]   席成洲. 一种开放的工业计算机标准-CompactPCI. 测控技术, 1998(1): 7~11

[15]   马永杰, 杨志民. 100MHz高速数据采集卡研制中关键技术的探讨. 西北师范大学学报(自然科学版), 1999(1): 37~37

[16]   方慧, 王飞, 何配琨等. TMS320C6000系列DSPs的原理与应用, 第2版. 北京: 电子工业出版社, 2001. 53~62

[17]   Exas Instruments Inc: TMS320C6416T FIXED-POINT DIGITAL SIGNAL PRO- CESSORS Data Sheet. Texas Instruments Inc:2004

[18]   苏涛, 蔡建隆. DSP接口电路设计与编程. 西安: 西安电子科技大学出版社, 2003. 21~56

[19]   黎向阳, 刘光平, 梁甸农. 宽带正交解调器幅相一致性测量. 国防科技大学学报, 2002(2): 60~63

[20]   向民, 张辉. 一种用于信号分析的数字正交解调电路设计. 电视技术, 2006(2): 65~69

[21]   立君, 马骏. 一种宽带正交解调器的试验研究. 现代电子, 2000(4): 30~32

[22]   崔勇, 王宏远. 基于SystemView的正交系统仿真与分析: 船舶电子工程, 2006(6): 90-92.

[23]   James Kimery.PXI测量系统面对今天的测试挑战.Electronic Products China, 2000(5): 18

[24]   王鲁平, 李飚. 基于EPLD技术的PCI总线接口设计. 电子技术应用,2001(3): 5

[25]   Finkelstein, Ehud, Weiss, Shlomo. PCI-based systems using CPLDand FPGA dev- ices. Proceedings of the Mediterranean Electrotechnical Conference-MELECON v2 1998 (3): 18~20

[26]   Plx technology, PCI9054 Data Book, Version 2. 1, January,2000:15~60

[27]   振勇, 翁木云. FPGA设计及应用. 第一版. 西安: 西安电子科技大学出版社, 2002. 1~22, 111~140, 195~218

[28]   DA先锋工作室, 吴继华, 王城. Altera FPGA/CPLD设计(基础篇)第一版. 北京: 人民邮电出版社, 2005. 1~116

[29]   ltera. CycloneII Device Handbook. San Jose: Altera Corporation ,2006: 1~484

[30]   任爱锋, 初秀琴, 常存等. 基于FPGA的嵌入式系统设计. 第一版. 西安: 西安电子科技大学出版社,2004. 9~126

[31]   Integrated Device Technology, Inc. IDT72V205/72V215/72V225/72V235/72V245 Data Sheet. Datasheet. FEBRUARY 2006:1~25

[32]   梅杰, 曹以龙, 许明东. 基于VerilogHDL语言的USB收发器设计. 电子技术, 2003, 12: 19~21

[33]   李玉柏, 彭启琮, 管庆. 基于VXI总线的虚拟仪器平台. 测控技术,1997, 16(3): 45~47

[34]   VXI Plug && play System Alliance. The VISA Library. Texas: VXI Plug&& play Sy- stem Alliance, 1996:121~256

[35]   VXI Plug && play System Alliance. VISA Implementation Specificationfor Textual Languages. Texas:VXI Plug && play System Alliance, 1996:57~146

[36]   Chris Cant . Windows WDM设备驱动程序开发指南(美)北京: 机械工业出版社, 2000. 1~100

[37]   Walter Oney, Programming the Windows Model Driver. Microsoft Press, 1999: 35~71

[38]   Microsoft,Windows 2000 DDK Documents, 1999: 20~54

[39]   Walter O. Programming the microsoft windows driver model[M] . USA ,1999: 21~50

[40]   VXI Plug && play System Alliance. Soft Front Panel Specification. Texas: VXI Plug && play System Alliance, 1996: 12~39

  附录1 攻读学位期间发表的论文

[1]    陈国斌, 汤清华, 汤丁诚. 基于PXI总线高速数字I/O卡设计. 电子技术应用, 2008, 33(1): 59~61

  附录2 FPGA控制程序

`define   COUNTERSIZE 129

`define   COUNTERSIZE_INT  10

module Statemachine (

     …)//由于篇幅限制,端口定义省略


always @ (GCLK0)

  if(LHOLD)

   LHOLDA&<=LHOLD;

  else

   LHOLDA&<=1'b0;


always@(posedge GCLK0 or negedge LRSTo_)

begin

if(LRSTo_==1'b0)

   begin

    LRS_I_&<=1'b0;

    LRS_O_ &<=1'b0;

    

   end

else

   begin

    LRS_I_&<=1'b1;

    LRS_O_ &<=1'b1;

   end

end

  //output logic

always @ (posedge GCLK0)

  begin

     casex (State)

     1'b0:

     begin

       if (!LADS_)

       begin

        

        LREADY_ &<= 1'b0;

        if (LWR_==1'b0)

         begin

           LREN_I_ &<=1'b0;

           WEN_O_ &<=1'b1;

  

       begin

         LREADY_ &<=1'b0;

         if (LWR_== 0)

        begin

           LREN_I_ &<=1'b0;  

           WEN_O_ &<=1'b1;

        end

       else

         begin

           LREN_I_ &<=1'b1;  

           WEN_O_ &<=1'b0;

        end

      

         State &<= 1'b1;


       end

       else     //Cycle Last

       begin

         LREADY_ &<=1'b1;

         LREN_I_ &<=1'b1;  

         WEN_O_ &<=1'b1;

         State &<=1'b0;

     end

     end

     default:

       State &<=1'b0;

        endcase

  end


assign LOE_O_ =(LRSTo_)?1'b0:1'b1;

assign LOE_I_ =(LRSTo_)?1'b0:1'b1;

//assign LLINT_=1'b1;  


always@(posedge GCLK0 or negedge LRSTo_)//or negedge LGCLK

begin

if(LRSTo_==1'b0)

   begin

    counter&<=6'b0;

    WCLK_reg &<=1'b0;

   end

else

  if(counter==`COUNTERSIZE)

   begin

  WCLK_reg&<=!WCLK_reg;

  counter&<=6'b0;

   end

  else

   counter&<=counter+6'b000001;

end

assign WCLK_O=(`COUNTERSIZE==129)?GCLK0:WCLK_reg;

always@(posedge GCLK0)

begin

  LHF_I_buf1&<=LHF_I_;

  LHF_I_buf2&<=LHF_I_buf1;

end

  

always@(posedge GCLK0 or negedge LRSTo_)

begin

if(LRSTo_==1'b0)

  begin

   counter_int&<=8'b0;

   LLINT_&<=1'b1;

   sub_state&<=3'b000;

  end

else

  begin

   case(sub_state)

    3'b000:

     begin

    LLINT_&<=1'b1;

      if(!LHF_I_buf1&&&&LHF_I_buf2)

       sub_state&<=3'b001;

      else

       sub_state&<=3'b000;

     end

    

    3'b001:

     begin

      counter_int&<=counter_int+8'b00000001;

      LLINT_&<=1'b0;

      if(counter_int==`COUNTERSIZE_INT)

       sub_state&<=3'b000;

      else

       sub_state&<=3'b001;

     end

    default sub_state&<=3'b000;

   endcase

  end

end

if(!LRSTo_)

   count&<=0;

  else if(count_flag)

   count&<=count+1;

   else count&<=0;

always@(posedge GCLK0 or negedge LRSTo_)

if(!LRSTo_)

   LRE_ENA_&<=1'b1;

else if(count&>15)

   LRE_ENA_&<=1'b0;

else

   LRE_ENA_&<=1'b1;

endmodule

  

附录3 PXI部分驱动程序代码
PXI驱动部分代码

/************************************************************************

* Function : DispatchRead

* Description: Handle IRP_MJ_READ, which is not implemented by this driver ReadFile

************************************************************************/

NTSTATUS DispatchRead(IN PDEVICE_OBJECT fdo,

           IN PIRP pIrp)

{                       //DispatchRead

  KdPrint((DBG_NAME "Read Device Start.\n"));

  ULONG ReturnedValue;

  NTSTATUS status = STATUS_SUCCESS;

  //将从硬件采集到的数据送给应用程序, 如果不能很快处理,将IRP进行串行化,交给StartIo处理。

  IoMarkIrpPending(pIrp);

  IoStartPacket(fdo, pIrp, NULL, CancelIrp);

  KdPrint((DBG_NAME "Read Device End.\n"));

  return STATUS_PENDING;

}                       //DispatchRead

/************************************************************************

* Function : DispatchWrite

* Description: Handle the IRP_MJ_WRITE, which is not implemented by this driver

WriteFile

************************************************************************/

NTSTATUS DispatchWrite(IN PDEVICE_OBJECT fdo,

           IN PIRP pIrp)

{                     //DispatchWrite

  KdPrint((DBG_NAME "Write File Start.\n"));

  //将应用程序的数据送到硬件, 将IRP串行化,交给StartIo处理

  IoMarkIrpPending(pIrp);

  IoStartPacket(fdo, pIrp, NULL, CancelIrp);

  KdPrint((DBG_NAME "Write File End.\n"));

  return STATUS_PENDING;

}        

/************************************************************************

* Function : DispatchIoControl

* Description: Processes the IOCTL IRPs sent to this device.

************************************************************************/

{    case IOCTL_PDC4000_REGISTER_EVENT://注册Event变量  

status= bReferenceObjectByHandle(*(PHANDLE)pIrp-&>AssociatedIrp.SystemBuffer,

         EVENT_MODIFY_STATE, *ExEventObjectType,

         pIrp-&>RequestorMode, (PVOID*)&&pdx-&>pWaitEvent, NULL);

     if (!NT_SUCCESS(status))

     {

       pdx-&>bSetWaitEvent = FALSE;

       KdPrint((DBG_NAME "WARNNING - ObReferenceObjectByHandle failed\n"));

     }

     else

     {

       pdx-&>bSetWaitEvent = TRUE;

       KdPrint((DBG_NAME "OK - ObReferenceObjectByHandle succeed\n"));

     }

     lReturnedValue = 0;

     break;

  case IOCTL_PDC4000_UNREGISTER_EVENT:   //反注册Event变量

     pdx-&>pWaitEvent = NULL;

     pdx-&>bSetWaitEvent = FALSE;

     lReturnedValue = 0;

     break;

  case IOCTL_PDC4000_READ_DATA:  

     ULONG Num, Buffer;

     lPdcAddress = (ULONG)pdx-&>PdcMemBase0;

     RtlCopyMemory(&&Num, pIrp-&>AssociatedIrp.SystemBuffer, sizeof(ULONG));

     KdPrint((DBG_NAME "Input Value is %x.", Num));

     Buffer = READ_REGISTER_UCHAR((unsigned char *)(lPdcAddress + Num));

     KdPrint((DBG_NAME "Read Data Value is %x.\n", Buffer));

     RtlCopyMemory( pIrp-&>AssociatedIrp.SystemBuffer, &&Buffer, sizeof(ULONG));

     lReturnedValue = sizeof(ULONG);

     break;

  case IOCTL_PDC4000_WRITE_DATA:

     ULONG dwWriteBuffer[2];

     lPdcAddress = (ULONG)pdx-&>PdcMemBase0;

     RtlCopyMemory(dwWriteBuffer, pIrp-&>AssociatedIrp.SystemBuffer, 2 * sizeofpIrpStack-&>Parameters.DeviceIoControl.InputBufferLength;//0x10;

     RtlCopyMemory(pdx-&>DmaInfo[0].vaCommonBuffer, pIrp-&>AssociatedIrp.SystemBuffer, lDMAPciToLocalTransferSize);

     KdPrint((DBG_NAME "The vaCommonBuffer is %X.\n", *(unsigned char *)(pdx-&>DmaInfo[0].vaCommonBuffer)));

     lPdcAddress = (ULONG)pdx-&>LocalRegisterMemBase;

dcd.BTERMInputEnable  = 1;

     dcd.DACChainLoad   = 0;

     dcd.DemandMode      = 0;

     dcd.DmaChannelPriority   = Rotational;

     dcd.DmaEOTPinEnable     = 0;

     dcd.DoneInterrputEnable = 1;

     dcd.EnableTransferCountClear = 0; //For sgl DMA

     dcd.FastSlowTerminateModeSelect = 0;

     dcd.InternalWaitStates = 0;

     dcd.InterrputSelect     = 1;

     dcd.LocalAddressingMode = 0;

     dcd.LocalBurstEnable = 1;

     dcd.LocalBusWidth    = 0;

     dcd.MemoryWriteAndInvalidateMode = 0;

     dcd.ReadyInputEnable = 1;

     dcd.ScatterGatherMODE = 0;

     //DMA threshold

     dte.DirectionOfTransfer = 0;

     dte.EndOfChain = 0;

     dte.InterruptAfterTerminalCount = 0;

     dte.NextDescriptorAddress = 0;

     KdPrint((DBG_NAME "The lDMAPciToLocalTransferSize is 0x%X.\n", lDMAPciToLocalTransferSize));

     rc = DmaBlockTransfer(pdx, 0, &&dte);

     if (rc != RC_SUCCESS)

     {     KdPrint((DBG_NAME "Can't DmaBlockTransfer.\n"));   }

     KdPrint((DBG_NAME "IOCTL_PDC4000_BLOCK_DMA_PCI_TO_LOCAL End.\n"));

     break;

  case IOCTL_PDC4000_BLOCK_DMA_LOCAL_TO_PCI:

     IoMarkIrpPending(pIrp);

     IoStartPacket(fdo, pIrp, NULL, CancelIrp);

如果您有论文相关需求,可以通过下面的方式联系我们
客服微信:371975100
QQ 909091757 微信 371975100