zoukankan      html  css  js  c++  java
  • 关于串口数据读取的几个问题

    串口COM数据读取可以采用MSCOMM控件,或者采用CSerialPort类进行控制,CSerialPort类可以从下面网址获取:http://www.codeguru.com/network/serialport.shtml。具体可以参考龚建伟的个人网页,非常感谢他提供了串口方面的书籍。

    在进行串口数据读写的程序编写过程中,遇到了下面几个问题:
    1、采用MSCOMM控件编写时,采用下面代码:
            CString strTemp;
            strTemp.Format(TEXT("CTestSDCardDlg::OnOnCommTestMscomm comEvent=%d, count=%d\n"),
            m_COMTest.GetCommEvent(),m_COMTest.GetInBufferCount());
            TRACE(strTemp);
            
            if( m_COMTest.GetCommEvent() == 2 && 0 != m_COMTest.GetInBufferCount())  // 表明有数据传送过来
            {
                strTemp.Format(TEXT("in Buffer count = %d\n", m_COMTest.GetInBufferCount()));
                TRACE(strTemp);
            }
    结果第一个strTemp输出的是comEvent = 2, count = 8
    第二个strTemp输出的却为:in Buffer count = 0
    这个让我实在是难以明白,我并没有获取过数据,两行代码也基本类似,为什么会出现这样的情况,很费解,不得以,用CSerialPort类进行程序编写

    如果您知道如何解决这个问题,请发邮件或者在底下回复告诉我,请您写信的时候标题注明串口,我将非常谢谢您,!我的邮箱:
        ubunoon@163.com

    2、CSerialPort类进行程序编写时遇到:
     a. CSerialPort类并没有定义串口关闭函数,显然,很多时候我们是需要关闭串口的,因此,采用在CSerialPort类中添加了ClsoePort函数
    具体定义如下:
       VOID CSerialPort::ClosePort()
    {
         do
         {
              SetEvent(m_hShutdownEvent);
              Sleep(10);
         } while (m_bThreadAlive);
    }
    其实就是把CSerailPort的析构函数的前面部分取了过来
      b. 这期间,碰到一个问题,就是我启动了串口监控,在关闭的时候等待了好长时间都没有关闭,后来运行编写时才明白,是由于将大量获取的串口数据写出到CEdit控件上,而串口发送数据又是非常频繁的,导致系统响应出现问题,后来,将这些写到CEdit控件的数据给注释后,关闭非常迅速。

      c. 在将数据写到CEdit的时候,发现数据怎么也不正确,用串口调试助手获取的数据与自己获取的数据始终不能够对上号,后来,在仔细核对源代码的时候发现,我常用TEXT宏来确定是否采用Unicode代码,当我在CString的Format函数中将TEXT去掉后,发现数据正确显示,而且获得的数据也是正确的。 这让我明白,串口数据是最好以纯的unsigned char来读取,这也是编写硬件相关软件的一个重要要求!

    对于硬件方面的软件编写,需要学习的东西很多,现在仅将工作遇到的问题记录下来,也可以使自己或者他人能够避免出现这些错误或者问题。

    // 下面内容为2008-08-28日添加:
    龚建伟修改了CSerailPort的方法,使得能够一次性输出多个字符,这本身没有错,但是,里面隐含了一个重要的bug,那就是,如果你在差不多相同的时间内,两次调用WriteToPort来进行多个字符输出,那么,后来的数据将覆盖前面的数据,而你得到的并不是正确的数据!

    因为这个隐含的bug,差不多花去了我一天的时间进行调试,因为我两次输出基本上相同的字符流,但含义不一样,在串口监测看到只有一次输出,而在调用日志上却又有两次输出,因此,我就非常纳闷,仔细查看了CSerailPort源代码,才发现两次WriteToProt的调用时间实在是太短了,没有线程间切换的时间那么长,因此,无论怎么处理CSerialPort均不可能得到正确的两次输出,为此,我只好在调用之前先做一些处理,使得一次性输出整个流!

    这个问题这是冤枉啊!

    后记:
        这也难怪同事一个劲的劝我转入到.net领域中去,我想哪儿应该不存在这些问题的,毕竟人家是经过上百次的测试的,而C++中开源代码虽然由大家维护,也是具有很强的健壮性的,但修改后的代码,是否还有那样的健壮性,是很难肯定的。因此在不清楚整个构架的情况下,不清楚每一个细节的情况下,对开源源代码进行修改反而容易出现更多隐含的bug,这些bug一旦暴露出来,其后患无穷。而如果开源代码不进行修改,则与商业库的区别便在于价格以及调试方便。相反,开源的代码更多的是需要修改后才能够更加适合某个工程,而商业库则更易定制。因此,虽然商业库受制于他人,但转入一个更为健全的商业库对于写程序是更为有利的事情,工程时间也将更加紧凑!
  • 相关阅读:
    如何使用 SPICE client (virt-viewer) 来连接远程虚拟机桌面?
    小米手机会不会更好
    5年一梦
    每天进步一点点——分布式文件系统下的本地缓存
    iOS开发中的NSDateFormatter日期格式解析总结
    IOS假设将一个十六进制的color转换成UIColor,非常有用
    HH实习(hpu1287)(斐波那契运用)
    学习用CMake来编写Qt程序
    【MFC设置静态文本框背景为透明】
    排序(3)---------冒泡排序(C语言实现)
  • 原文地址:https://www.cnblogs.com/ubunoon/p/SerialPortReadProblem.html
Copyright © 2011-2022 走看看