Adlink PCI-7250 eventcallback

时间:2014-11-27 11:56:24

标签: c# .net pci data-acquisition pci-bus

我刚写了一个简单的C#,当任何数字输入变高时,从PCI-7250(数据采集卡)获得事件回调。这是我的代码:

public delegate void ReadDelegate(uint value)
public void Form1_Load(object sender, EventArgs e)
 { 
    m_dev = DASK.Register_Card(DASK.PCI_7250,0);

    ReadDelegate ReadNow = new ReadDelegate(FunctionToCall) 
    DASK.DI_EventCallBack((ushort)m_dev,1,(short)DASK.DBEvent,ReadNow) 
} 
private void FunctionToCall(uint int_value) 
{
 MessageBox.Show(int_value) 
}

运行时它只是在运行期间继续抛出一些随机数,然后最终崩溃。我相信它与EventType(DASK.DBEvent)有关。我仔细阅读了手册,但没有提到任何关于DASK.DBEvent。

请告知。

1 个答案:

答案 0 :(得分:0)

由于设备在其驱动程序中不支持回调,因此您可以通过在后台线程中轮询设备,使驱动程序的API从同步调用调整为回调。

首先,创建一个类,轮询设备以查找您有兴趣响应的物理事件。然后,在您的GUI代码中,将轮询工作放在后台并响应主线程中的回调。

我不熟悉ADLink驱动程序,因此我将总结一种设计方法并绘制一些不是线程安全的伪代码。这是一种使用Tasks的天真方法,但您也可以将其更新为使用延续或async/await。或者,如果您需要多个响应者,请使回调引发其他类可以订阅的事件。

投票类

public class EdgeDetector
{
  public delegate void OnRisingEdgeDetected(uint currentValue, uint linesThatAsserted);
  private bool m_shouldPoll;

  private void PollForRisingEdge(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
    while (m_shouldPoll)
    {
      // Optional: sleep to avoid consuming CPU

      uint newPortValue = device.ReadAllDigitalLines();
      uint changedLines = m_currentPortValue ^ newPortValue;
      uint risingEdges = newPortValue & changedLines;
      m_currentPortValue = newPortValue;

      if (risingEdges != 0)
      {
        onRisingEdgeDetected(currentValue: newPortValue,
                             linesThatAsserted: risingEdges);
      }
  }

  public void Start(PCI_7250 device, OnRisingEdgeDetected onRisingEdgeDetected)
  {
      m_shouldPoll = true;
      PollForRisingEdge(device, onRisingEdgeDetected);
  }

  public void Stop()
  {
      m_shouldPoll = false;
  }
}

WinForm类

private void Initialize()
{
  m_dev = DASK.Register_Card(DASK.PCI_7250, 0);
  m_mainThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
}

private void StartEdgeDetection()
{
  m_edgeDetectionTask = Task.Factory.StartNew( () =>
    {
      m_edgeDetector.Start(device: m_dev, onRisingEdgeDetected: RescheduleOnMainThread);
    });
}

private RescheduleOnMainThread(uint currentValue, uint linesThatAsserted)
{
  m_onEdgeDetectionTask = Task.Factory.StartNew(
    action: () =>
      {
        MessageBox.Show(currentValue);
      },
    cancellationToken: null,
    creationOptions: TaskCreationOptions.None,
    scheduler: m_mainThreadScheduler);
}

private void CleanUp()
{
  m_edgeDetector.Stop();
  m_edgeDetectionTask.Wait();
  m_onEdgeDetectionTask.Wait();
}

public void Form1_Load(object sender, EventArgs e)
{
  Initialize();
  StartEdgeDetection();
}

public void Form1_Closed(object sender, EventArgs e)
{
  CleanUp();
}