Delphi+SPCOMM开发串口通信程序,为什么读取串口数据的速度这么慢呢?
下面是串口监测数据:
0.00005615 QX34D.exe IRP_MJ_CREATE Serial0 SUCCESS Options: Open 
0.00000391 QX34D.exe IOCTL_SERIAL_SET_QUEUE_SIZE Serial0 SUCCESS InSize: 512 OutSize: 256
0.00000475 QX34D.exe IOCTL_SERIAL_PURGE Serial0 SUCCESS Purge: TXABORT RXABORT TXCLEAR RXCLEAR
0.00000168 QX34D.exe IOCTL_SERIAL_GET_TIMEOUTS Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCCESS RI:3 RM:3 RC:2 WM:3 WC:3
0.00000168 QX34D.exe IOCTL_SERIAL_GET_BAUD_RATE Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_CHARS Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_HANDFLOW Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_PROPERTIES Serial0 SUCCESS
0.00000140 QX34D.exe IOCTL_SERIAL_GET_WAIT_MASK Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_BAUD_RATE Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_CHARS Serial0 SUCCESS
0.00000168 QX34D.exe IOCTL_SERIAL_GET_HANDFLOW Serial0 SUCCESS
0.00000754 QX34D.exe IOCTL_SERIAL_SET_BAUD_RATE Serial0 SUCCESS Rate: 9600
0.00000419 QX34D.exe IOCTL_SERIAL_SET_RTS Serial0 SUCCESS
0.00000419 QX34D.exe IOCTL_SERIAL_SET_DTR Serial0 SUCCESS
0.00000307 QX34D.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial0 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
0.00000168 QX34D.exe IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13
0.00000307 QX34D.exe IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake:1 Replace:80000042 XonLimit:2048 XoffLimit:512
0.00000922 QX34D.exe IOCTL_SERIAL_SET_WAIT_MASK Serial0 SUCCESS Mask: RLSD ERR RING 
22.14897312 QX34D.exe IOCTL_SERIAL_WAIT_ON_MASK Serial0 CANCELLED
0.80403124 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 1: 06 
0.00002151 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 50 
0.00001620 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 52 
0.00001592 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 4F 
0.00001928 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 47 
0.00001732 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 52 
0.00001872 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 41 
0.00001816 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 4D 
0.04674700 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 9: 50 35 31 30 37 F4 00 00 06 
0.00002319 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 1: 02 
0.17158270 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 00 08 FF FF FF FF FF FF FF FF 06 
0.00002850 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 4: 52 00 00 08 
0.17178524 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 08 08 FF FF FF FF FF FF FF FF 06 
0.00002682 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 4: 52 00 08 08 
0.17176960 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 10 08 00 00 01 45 00 00 01 45 06 
0.00002766 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 4: 52 00 10 08 
0.17178915 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 18 08 FF FF FF FF FF 01 01 FF 06 
0.00002570 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 4: 52 00 18 08 
0.15588350 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 8: 57 00 20 08 00 00 01 46 
0.00002738 QX34D.exe IRP_MJ_WRITE Serial0 SUCCESS Length 4: 52 00 20 08 
0.01553130 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 5: 00 00 01 46 06 0.15618130 QX34D.exe IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 28 08 FF FF FF FF FF 01 01 FF 06

解决方案 »

  1.   

    spcomm的缺点就是一直等到缓冲区满或者超时才返回数据,可以用一下cport,这两个几乎不用改代码,只改一下那个参数名称,spcomm里面的是一个bufferlength,那个里面是count
      

  2.   

    还有就是缓冲区的清空问题,这个控件也没有相应的过程或函数来清空,但是在控件内是有用到这个清空函数PurgeComm( hCommFile, PURGE_TXABORT or PURGE_RXABORT or
                               PURGE_TXCLEAR or PURGE_RXCLEAR ) ;
    不过是写在打开串口的函数里了,我是想每次接读完数据就清空缓冲区怎么 做?
      

  3.   

    在源代码里有     INPUTBUFFERSIZE = 2048;,但改了以后,效果也不明显,缓冲不用清,自动清空的
      

  4.   

    ffwin():
    首先感谢参与讨论这个问题
    1、比如我想接收“06”这样一个字节,我的INPUTBUFFERSIZE要设置成多大
    2、你看为什么我的接收时间会那么久,并且是超时的:
    0.17178524  QX34D.exe  IRP_MJ_READ Serial0 TIMEOUT Length 13: 57 00 08 08 FF FF 06
      

  5.   

    ffwin():
    对于“缓冲区滿时才返回数据”这个概念我一直是糊涂着,不明白是指什么意思?
    比如我有设定为2048,那为什么当我也可以一次只收到1节数据,如“06”
      

  6.   

    INPUTBUFFERSIZE在程序运行期又是不可以改的,设计期定好就没得变了
    看来只能用时间来控制什么时间让它返回数据,但这又怎么控制呢,SPCOMM可以做的到吗?
      

  7.   

    www.cnpack.org
    下载里面的组件包,用cnrs232你说的那个问题.在你发送数据前,清空接收和发送缓冲区.然后发送数据.发送完后用一个线程轮训接收缓冲区.当里面的数据达到了你的要求,就返回.
      

  8.   

    spcomm 是用发送间隔来产生事件的,也就是两个字符到达的间隔,readintervalTimeout属性.
    接收慢不会是因为缓冲区的问题,可能是属性设置的问题
    如果发送时是不定期的,但两次发送时是有间隔的,如30ms或1s ,那么接收间隔以此来区分,当接收时,检测一个间隔就回返回.
      

  9.   

    SPCOMM有缓冲区 有一种是有数据就触发 设置BUFFERSIZE为0一种是事件驱动 有了发送的事件,接受缓冲区就做好了接受数据的准备在俩次发送之间设置一个时间间隔,它的值大于等于 (数据传输到设备时间+设备反应延迟+数据返回传输时间)然后设置为事件驱动.当发送的数据返回超时,SOCOMM自动把上次数据包丢弃,进入下次发送.这是SPCOMM的时间分隔比较常用方法