如题:单片机每秒发送100多组数据过来,每组数16个字。
上位机必须从测试一开始即时显示经转换过的三个数值,并同时显示趋势曲线图,每次测试结束后仪器自动开始下一次测试,两次测试间隔的几秒钟内必须将几百个测试原始数据保存到数据库。本来一切任务已经实现,但现在要求提速,仪器两次测试间隔时间仅需3——5秒,上位机实时跟踪速度必须更快更稳定,用MSCOMM控件的效果都明白,谁能给出有效的例程用API函数读取串口啊!
    本来这在CSDN里早属老掉牙的问题,但一般的都是使用VC在做,即使全部准确“翻译”为VB代码,俺都一直没找到正确的方法,麻烦高手之间迷津,给一VB例程!注:通讯设置定为115200bps,这是UART 16550型串口的最高速率,有没有办法检测出串口的UART型号啊?MS在WIN98安装盘下的MSD小程序都可以的。另:问题解决得好的话,分可加倍!

解决方案 »

  1.   

    楼上的方法比较好 
    在vb上调用api 可能比你直接用mscomm还要慢
    100多组数据过来,每组数16个字 (那就十定长了)
    你可以试试把 RThreshold 设置大一点 800 个字节产生一次中断
    2次就刚好 我想串口接收到缓冲区应该是硬件的问题 
    这样数度可以跟的上
    不知道你试过没有
      

  2.   

    可以计算一下:
    要求:“单片机每秒发送100多组数据过来,每组数16个字”
          就算是200组×16字节=3200字节
    考虑:停止位、校验位,算起来就是:32000bit/s=32kbit/s
          相比115200,约占用30%的资源,
    因此:就看你对信息处理的工作量了。1、通讯采用API,只能在数据的接收与发送中能享受到底层功能的速度,无助于对信息的处理。而且在VB上调用API过程中的转折也会影响速度,这点跟采用MsComm控件相比,不会有太大的改善。
    因此想加快速度,最好用VC写一个库,不但是包含串口通讯的功能,而且最好能包含一些信息处理的方法在里面,这样可能能提高速度。2、但如果想继续使用原来已编好的功能,那么就要在通讯的处理上采用一些手段:如果:你能够边接收一些信息就能边处理一些,那么RThreshold设置得太大,就会在等待OnComm事件中浪费了时间,因此如何设置RThreshold应根据你的情况来设定。我觉得可以通过OnComm事件,把接收到的东东放到一个“队列”中,信息处理功则通过检查这个队列把信息不断取出来进行处理,让接收、处理两个功能并行处理,充分利用通讯的间隙。通过“优化”的手段,可以把通讯(接收)的功能做得很小巧的。另外通过把VB编译成EXE来执行也是提高速度的一个手段。
      

  3.   

    谢谢各位的高见,不过俺并没有通过OnComm事件来接收所有数据,因为那样做唯一的好处就是:反复调用/引发同一个过程的话,在一分钟之内就发生一次“缓冲区溢出错误”。
        
        故正确的处理方法是:RThreshold设为一组数据的长度(16),无论通过上位机启动仪器还是用户在下位机上操作,都把RThreshold的响应作为测试开始,然后在循环中等待/读取数据,另外,因为下位机在测试过程中发送数据不会间断,故连续一段时间未接收到数据则可认为停止。
    大体流程如下:
    事件OnComm
        IF 并非数据到达,而是其它通讯事件则退出
        RThreshold=0 '一次测试只需响应一次oncomm事件。
        For 循环
            '此过程中并非仅接收测试数据,还包括其它通信命令。仪器要求上位机更新某些参数等。
            查找标志代码
            IF 找到
                 记录第一个标志代码位置
                 Exit For
            Else
                 无可用数据 THEN (RThreshold=16:Exit Sub)
            End IF
        Next 
        
        PreviousTick=GetTickCount '  记录 GetTickCount值
        Do
            If 串口缓冲区中的数据长度小于16 '数据未到达则等待
        '=========================================================
                If GetTickCount - PreviousTick > 300 Then'超过三百毫秒未接收到数据则认为停止
                     停止后计算结果并进行相关处理(排除异常,显示结果等)
                     循环动态数组,将所有测试原始数值保存到数据库。
                     RThreshold=16 '等待接收下一次测试数据。
                End IF
                Doevents
            End If
            
            For'循环接收到的数据 
                1、查找标志代码
                2、取二进制值
                3、按特定公式转换到正确的(浮点)数值
                IF 数值正常
                     显示到label
                     显示实时趋势(曲线图跟踪)
                     保存到(动态)结构数组
                End If
                PreviousTick=GetTickCount '更新上次收到数据的时间为当前值
            Next
        Loop
    End Sub    只要计算机内存足够(128以上),串口为UART 16550或以上,同时带有AGP显卡(不是主板集成的那种)现在实时数据跟踪已基本没问题了,但仪器现在速度加快,两次测试间隔时间不超过五秒,根据不同试样,收到的数据一般有几百条甚至上千条,如何在这段时间内,保证所有收到的数据存入数据库呢?能否让数据保存异步执行?方法?能否让数据保存异步执行?方法?
    能否让数据保存异步执行?方法?
    能否让数据保存异步执行?方法?
      

  4.   

    1.你要确定速度的瓶颈在那里。
    2.做个测试,分开判断只通信的速度,只是处理数据的速度,只是存储数据到数据库的速度。
    3.我估计很可能是你(接受+处理+存储数据)总的效率较慢。
    4.如果是初步分析可以做成多线程,将通信、处理、存储数据分开。
    5.VB中多线程比较麻烦,可以考虑将接受数据放到一个缓冲区中,放2个Timer控件,一个定时处理数据,处理好放到另一个缓冲区,另一个定时存储数据。
    6.以上都不行可以考虑换Delphi或C++(或多台电脑分布式处理了!!!)。
      

  5.   

    我上面的提议是希望你通过OnComm事件,把通讯(接收数据)功能与数据处理功能分开,让各模块更“专业”,“更快”,不用去操心“别人”的事情,这是大数据量通讯的常见做法,也是你说的”异步处理”的思想,我们在串口通讯方面就是采用这种方式的,只要通讯占用的时间比例不是太高(当然也要看数据处理量的大小),这种方法是可行的。你提到的:...通过OnComm事件来接收所有数据,因为那样做唯一的好处就是:反复调用/引发同一个过程的话,在一分钟之内就发生一次“缓冲区溢出错误”。
    那应该是属于你程序处理的问题,不应该是OnComm的问题。
      

  6.   

    每秒发送100多组数据,那就是10ms一组数据,你就是用API直接去读串口,恐怕时间也不够,即时显示应该是想象中的吧。如果不要根据收到的数据实时进行控制的话,可以用API的方式来相对比较简单地解决问题。如果要比较理想地解决问题的话,就写一个串口驱动,接收数据,上层一个应用程序,直接和驱动通信,显示和保存数据,效率最高。我实现过每秒500包数据的接收和实时控制,没有问题的。