【问题标题】:Adlink PCI-7250 eventcallbackAdlink PCI-7250 事件回调
【发布时间】:2015-01-26 00:31:40
【问题描述】:

我刚刚编写了一个简单的 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。

请多多指教。

【问题讨论】:

  • 我收到来自凌华科技支持团队的更新,不幸的是,PCI-7250 不支持任何回调或中断。我试图在上面使用回调,难怪它为什么不能正常工作。无论如何,是否有其他人对此有解决方法,通过使用其他一些技术来触发读取。
  • 您使用哪个函数参考?我发现只有一个用于 c++(2009 年),而在这一个中,PCI-7250 未列在 DI_EventCallBack-Method 支持的卡下。
  • @AquilaRapax:正如我在上面的帖子中 Adlink 支持团队已经验证 PCI-7250 不支持回调或中断。

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


【解决方案1】:

由于设备在其驱动程序中不支持回调,您可以通过在后台线程中轮询设备来调整驱动程序的 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();
}

【讨论】:

  • 这似乎是个好主意,类似于我之前尝试过的。一旦我回到办公室,我肯定会尝试这个。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 1970-01-01
相关资源
最近更新 更多