【问题标题】:serial device ignores EscapeCommFunction with C串行设备使用 C 忽略转义逗号功能
【发布时间】:2011-06-13 16:56:57
【问题描述】:

我正在(最终)从 MSDOS 迁移到 Windows XP,以便通过串行端口控制仪表。我的旧 C DOS 代码工作正常。

我想做如下:

  • 仪表持续读取读数 每隔几秒,但不发送任何 信息,直到它被要求 电脑
  • 当计算机准备好接收时 来自仪表的信息,它要求它。它不接受其他信息。

我的问题是读数是由仪表生成的,因此只是进入计算机。

我已将 DCB serail 参数设置如下,打算使用 RTS 和 DTR 控制通信:

dcbSerialParams.BaudRate=CBR_4800;
dcbSerialParams.ByteSize=7;
dcbSerialParams.StopBits=TWOSTOPBITS;
dcbSerialParams.Parity=EVENPARITY;
dcbSerialParams.fDtrControl=DTR_CONTROL_ENABLE;
dcbSerialParams.fRtsControl=RTS_CONTROL_ENABLE;

我在DOS下的旧代码是这样的:

 outportb(COM1+4,0x03);  /* start Minolta reading */   

 for(j=0;j<=10;j++) /*each reading consists of 11 ascii characters*/
  {
  while(!((inportb(COM1+5)) & 1)); /*wait until char received*/
  reading[j]=inportb(COM1);
  }
 sscanf ( &reading[4], "%f", &lum[k] );
 
 outportb(COM1+4,0x00);  /* stop Minolta reading */

在我看来这应该可行:

void serial_notready(void)
{
EscapeCommFunction(hSerial,CLRDTR);
EscapeCommFunction(hSerial,CLRRTS);
}

void serial_ready(void)
{
EscapeCommFunction(hSerial,SETDTR);
EscapeCommFunction(hSerial,SETRTS);
}

int serial_read(char reading[])
{
DWORD dwBytesRead = 0;
int nbytes=11;
ReadFile(hSerial, reading, nbytes, &dwBytesRead, NULL);
return(dwBytesRead);
}

serial_ready(void);
x = 0; while(x == 0){x=serial_read(reading);}
serial_notready(void);

但是,Minolta 不会等待从计算机接收 RTS。它只是继续并在每个可用时发送读数。同时,计算机不会拒绝任何不需要的阅读,而是接受它。

我一直把头撞在墙上试图弄清楚这一点,尝试了各种排列都无济于事。非常感谢任何帮助!

更新:

基本故事是我在显示器上呈现给定的亮度(亮度),然后需要相应的亮度读数。这是针对一整套亮度完成的。

L   ---
U      ---
M         ---
     TIME

我呈现 lum1, lum2, lum3, lum4,.... 如果测量值与显示器不同步,那么我可能会得到一个假定的读数 3,它实际上是 lum2,或者某种平均值,因为读数越过了边界在 lum2 和 lum3 显示器之间。而且,正如您所说,汉斯,读数总是落后于显示亮度。即使我总是系统地落后于一个读数也会很糟糕(我的情况更糟 - 这是读数和亮度之间的随机关系)。

所以 windows 串行例程的行为对我来说是一场噩梦。再次感谢您的帮助!

【问题讨论】:

    标签: c winapi serial-port


    【解决方案1】:

    我使用免费的第三方串口仿真器 VPS。它有一个间隔请求计时器,可以在需要更新/抓取数据时进行检测。还允许我将总线数据包记录到 excel 文件中。

    【讨论】:

    • 谢谢 Esan,我会去看看的。
    【解决方案2】:
    dcbSerialParams.fDtrControl=DTR_CONTROL_ENABLE; 
    dcbSerialParams.fRtsControl=RTS_CONTROL_ENABLE;
    

    您立即启用 DTR 和 RTS 信号。当您打开端口时,仪表将立即开始发送数据。该数据被缓冲在驱动程序的接收缓冲区中。您之前在 DOS 代码中没有缓冲区。这取决于您调用 serial_notready() 需要多长时间。如果需要一秒钟左右,您将拥有一个相当完整的缓冲区。是的,这使得仪表看起来只是在发送数据。而且您总是在阅读旧样本。

    从设置为禁用的 DCB 值开始。请注意,该方案很脆弱,您可以在 DOS 中非常可靠地关闭信号。现在你有一个介于两者之间的驱动程序。您很可能最终关闭 RTS 为时已晚。这可能会导致阅读过时。另一种方法是启动一个连续读取的线程。并让您的主代码只使用它读取的最后一个值。开销很低,串口很慢。

    【讨论】:

    • 非常感谢汉斯!我会跟进你的建议。
    【解决方案3】:

    首先要做的是检查对EscapeCommFunction() 的调用的返回值。如果返回值为is zero,则调用失败,应使用GetLastError()接收更多错误信息。

    【讨论】:

    • 感谢您的帮助。我实际上不认为有错误,只是赢得不能按我想要/预期的方式工作的串行通信例程。比尔
    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    相关资源
    最近更新 更多