一个由印度人编写的VC串口类

软件介绍

  一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些基础知识,如怎么用VC打开串口,如何对串口进行配置,读串口、写串口等。

  这个类有点特别,它没有使用事件驱动原理,它是以查询方式工作的。

简介:  

  对没有接触过串口通信的VC程序员来说显得非常困难,很久以前我在 codeguru.com 上搜索过串口通信相关信息得到了非常大的帮助,从那时起能编写一个简单易用的VC 串口类是我的梦想。

  经过七个月在串口通信编程方面实践经验后,我编写了一个基于API实现的简单串口类,在介绍此串口类之前先介绍一下VC 串口通信方面的基础知识。

串口通信基础:

  串口通信每个字节的传输以串行的方式进行,传输时低位先被发送,一个“包”由“开始位”+“数据位”+“奇偶校验位”(不是必需)+“停止位” 组成。

  奇偶校验位是可选的,它用来进行错误检测,您可以在软件里设置是否启用奇偶校验,而且还可以选择启用哪种校验方式,如“奇”校验(ODD)或“偶”校验(EVEN)。

  PC机通过串口发送和接收数据的流程如下:

  1、
打开串口

  2、 配置串口通信参数,如:波特率、校验方式、数据位数等
  3、 设置通信超时时间
  4、 写数据
  5、 读数据
  6、 关闭串口

用VC打开串口:

  打开串口可以用API函数 CreateFile() 来实现,打开串口有两种方式,分别为重叠I/O(OVERLAPPED)和非重叠(NON-OVERLAPPED)方式(其实这两种方式分别对应串口的异步和同步通信方式-VC串口通信技术网注)。CSerialCom 类工作于非重叠(NON-OVERLAPPED)模式(即同步通信模式),有关更多 OVERLAPPED 和 NON-OVERLAPPED 方面的消息可查询MSDN。

串口配置:

  VC 串口通信程序编写最重要的课题就是如何利用 DCB 结构来配置串口,对 DCB 结构填充不正确是大多数人常反犯的毛病,通常串口通信程序编写好后出现这样那样的问题就是因为这个结构没有正确填充所致。在利用 CreateFile() 函数打开串口时就需要我们对串口的波特率、校验方式、数据位、停止位等进行配置。

设置超时时间:

  每次打开串口时都必须利用 COMMTIMEOUTS 结构设置超时时间,如果未设置此结构,通信将以默认或上次打开此串口时设置的超时时间为准。

写串口:

  WriteFile() 函数可实现这一功能,在执行这一动作之前必须先打开并配置好串口。

读串口:

  利用 ReadFile() 可实现这一功能,同样,在执行这一动作之前必须先打开并配置好串口。

关闭串口:

  不再使用已经打开的串口后必须关闭它以将此串口资源释放出来,这样其它程序才可能再使用此串口资源,外于非重叠I/O(NON-OVERLAPPED)模式下的串口在打开期间是不能被其它程序或同一程序内的其它线程访问的。使用 CloseHandle() 函数可以关闭串口, CloseHandle() 函数只有一个参数,它是由 CreateFile() 打开串口时返回的设置句柄。

CSerialCom 串口类

  CSerialCom 类使用六个函数来实现上面提到的功能,它们分别是:

BOOL CSerialCom::OpenPort(CString portname)
{
portname= "//./" + portname;  

hComm = CreateFile(portname,
                      GENERIC_READ | GENERIC_WRITE,
                      0,
                      0,
                      OPEN_EXISTING,
                      0,
                      0);
if(hComm==INVALID_HANDLE_VALUE){
    return false;}
    else
    return true;  

}  

  OpenPort()成员函数用来打开串口,它需要的参数只有一个,就是串口名,如“COM1”,“COM2” 。

BOOL CSerialCom::ConfigurePort(DWORD BaudRate, BYTE ByteSize,
                               DWORD fParity, BYTE Parity, BYTE StopBits)
{
    if((m_bPortReady = GetCommState(hComm, &m_dcb))==0)
    {
        MessageBox("GetCommState Error","Error",MB_OK+MB_ICONERROR);
        CloseHandle(hComm);
        return false;
    }  

    m_dcb.BaudRate =BaudRate;
    m_dcb.ByteSize = ByteSize;
    m_dcb.Parity =Parity ;
    m_dcb.StopBits =StopBits;
    m_dcb.fBinary=TRUE;
    m_dcb.fDsrSensitivity=false;
    m_dcb.fParity=fParity;
    m_dcb.fOutX=false;
    m_dcb.fInX=false;
    m_dcb.fNull=false;
    m_dcb.fAbortOnError=TRUE;
    m_dcb.fOutxCtsFlow=FALSE;
    m_dcb.fOutxDsrFlow=false;
    m_dcb.fDtrControl=DTR_CONTROL_DISABLE;
    m_dcb.fDsrSensitivity=false;
    m_dcb.fRtsControl=RTS_CONTROL_DISABLE;
    m_dcb.fOutxCtsFlow=false;
    m_dcb.fOutxCtsFlow=false;  

    m_bPortReady = SetCommState(hComm, &m_dcb);
    if(m_bPortReady ==0)
    {
        MessageBox("SetCommState Error","Error",MB_OK+MB_ICONERROR);
        CloseHandle(hComm);
        return false;
    }
    return true;
}  

  ConfigurePort() 函数对串口地配置,它所需参数如下所示:

  DWORD BaudRate

  DWORD BaudRate 用来描述串口通信使用的波特率,如此参数为 CBR_9600 时,波特率为9600bps,PC机支持的标准波特率有:CBR_110 ,CBR_300 ,CBR_600 ,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_14400, CBR_19200,CBR_38400,CBR_56000,CBR_57600,CBR_115200,CBR_128000,CBR_256000

  BYTE ByteSize

  此参数描述数据位位数,标准值为8或4。

  DWORD fParity

  奇偶校验开关,如果此参数为真(TRUE)则开启奇偶校验,为假(FALSE)则关闭奇偶校验。

  BYTE Parity

  校验方式,可选方式如下:

 
EVENPARITY

  MARKPARITY
  NOPARITY
  ODDPARITY
  SPACEPARITY

  BYTE StopBits

  停止位位数,可取值如下:

 
ONESTOPBIT

  ONE5STOPBITS
  TWOSTOPBITS

备注:ConfigurePort() 函数是假定串口的流控制是由硬件来完成的,软件在收发数据过程中不检测CTS/RTS 和 Xon/Xoff 状态,您可以修改DCB结构来启用软件流控制。

BOOL CSerialCom::SetCommunicationTimeouts(DWORD ReadIntervalTimeout,
                                          DWORD ReadTotalTimeoutMultiplier,
                                          DWORD ReadTotalTimeoutConstant,
                                          DWORD WriteTotalTimeoutMultiplier,
                                          DWORD WriteTotalTimeoutConstant)
{
    if((m_bPortReady = GetCommTimeouts (hComm, &m_CommTimeouts))==0)
        return false;
    m_CommTimeouts.ReadIntervalTimeout =ReadIntervalTimeout;
    m_CommTimeouts.ReadTotalTimeoutConstant =ReadTotalTimeoutConstant;
    m_CommTimeouts.ReadTotalTimeoutMultiplier =ReadTotalTimeoutMultiplier;
    m_CommTimeouts.WriteTotalTimeoutConstant = WriteTotalTimeoutConstant;
    m_CommTimeouts.WriteTotalTimeoutMultiplier =WriteTotalTimeoutMultiplier;
    m_bPortReady = SetCommTimeouts (hComm, &m_CommTimeouts);  

    if(m_bPortReady ==0)
    {
        MessageBox("StCommTimeouts function failed",
                   "Com Port Error",MB_OK+MB_ICONERROR);
        CloseHandle(hComm);
        return false;
    }
    return true;
}

  SetCommunicationTimeouts() 成员函数用来设置读/写超时时间,它所需参数如下:

  DWORD ReadIntervalTimeout

  设置读串口时,收到两个字符的最大时间间隔,单位为毫秒。在执行ReadFile() 期间,一但收到两个字符的时间间隔超过这一设定值,ReadFile()立即返回。如果这一参数设置为零,则表明这一特性未启用。

  ReadTotalTimeoutConstant

  常量,用来计算读操作总超时时间。每个读操作过程中,这个参数被加到ReadTotalTimeoutMultiplier。如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant两个参数都为零则表明总超时计算功能没有启用。

  ReadTotalTimeoutMultiplier

  用来保存读操作总超时时间的

  WriteTotalTimeoutConstant

  常量,用来计算写操作总超时时间。与ReadTotalTimeoutConstant差不多。

  WriteTotalTimeoutMultiplier

  用来保存写操作总超时时间的,如果WriteTotalTimeoutMultiplier 和 WriteTotalTimeoutConstant两参数均为零,表明写操作总超时时间特性不被启用。

  例如,您需要传送一块数据包,设定了写操作超时时间为500ms(每个字符间发送时间最大间隔),您可以用设置超时成员函数来设定,内容为:SetCommunicationTimeouts(0,500,0,0,0);如果设置成功,函数返回真,否则返回假。

BOOL CSerialCom::WriteByte(BYTE bybyte)
{
    iBytesWritten=0;
    if(WriteFile(hComm,&bybyte,1,&iBytesWritten,NULL)==0)
        return false;
    else
        return true;
} 

  WriteByte() 成员函数用来向串口写数据。

BOOL CSerialCom::ReadByte(BYTE &resp)
{
    BYTE rx;
    resp=0;  

    DWORD dwBytesTransferred=0;  

    if (ReadFile (hComm, &rx, 1, &dwBytesTransferred, 0))
    {
        if (dwBytesTransferred == 1)
        {
            resp=rx;
            return true;
         }
    }
    return false;
} 

ReadByte() 成员函数实现读串口功能,如果您知道有数据发送来了,可能使用 ReadByte() 来读取数据,如果不知道何时有数据发送过来,可以周期性调用此函数,当没收到数据超过超时时间后, ReadByte() 自动返回。在实际应用中,通信双方可能会以某种协议进行的,此时一般有表明通信数据包结束的标志,如3964协议的结束符是‘ETX’,您可能通过它来判断是否传输结束。

void CSerialCom::ClosePort()
{
CloseHandle(hComm);
return;
}  

  ClosePort() 成员函数用来关闭一个已经打开的串口。

如何使用CSerialCom类

  使用CSerialCom类前的准备工作:

  1、
复制SerialCom.h 和 SerialCom.cpp两个文件到工程所在目录

  2、 在VC工程中导入这两个文件
  3、 加入#include "SerialCom.h"句代码到程序适当位置
  4、 创建CSerialCom类的一个实例

  现在就可以调用CSerialCom类成员函数来进行串口通信了,操作流程如下:

  1.  1 // 打开串口。 需要检查函数返回值来判断串口是否正确打开
     2 port.OpenPort( );
     3
     4 // 配置串口。需要检查函数返回值来判断否正确配置
     5 port.ConfigurePort( );
     6
     7 // 设置超时时间。需要检查函数返回值来判断否正确配置
     8 port.SetCommunicationTimeouts( );
     9
    10 // 写串口,由于一次只能写一个字节,一般需要多次调用此函数才能将需要发送的字符串发送完
    11 port.WriteByte();
    12
    13 // 读串口,由于一次只能读一个字节,一般需要多次调用此函数才能将需要读取的字符串读完
    14 port.ReadByte( );
    15
    16 // 关闭串口
    17 port.ClosePort();

    下载地址: http://pan.baidu.com/s/1c0nLdFq

时间: 2024-12-22 18:47:22

一个由印度人编写的VC串口类的相关文章

一个印度人写的VC串口类CSerialCom(有串口基础介绍)

一个由印度人编写的VC串口类(也是一种VC串口控件),他还配合这个类写了VC 串口通信方面的一些基础知识,如怎么用VC打开串口,如何对串口进行配置,读串口.写串口等. 这个类有点特别,它没有使用事件驱动原理,它是以查询方式工作的. 简介: 对没有接触过串口通信的VC程序员来说显得非常困难,很久以前我在 codeguru.com 上搜索过串口通信相关信息得到了非常大的帮助,从那时起能编写一个简单易用的VC 串口类是我的梦想. 经过七个月在串口通信编程方面实践经验后,我编写了一个基于API实现的简单

上位机简单串口类,VC串口类

我是在一家做硬件的的公司里面做软件开发工程师的,我做的软件大多是是编写软件通过串口去控制硬件,所以串口编程对于我来说是很重要的.串口编程之前一直使用的是自己写的简单串口(只有发送,没有接收)类,或者上网下的CSerialPort类(个人觉得不好用啊,互锁变量一堆,代码一开始还让人看不懂,对于上位机使用不合适).对于我做的上位机软件,其实使用串口只是需要顺序发送,接收数据无误就行了,不需要考虑太多东西.所以最近有点空,就自己再写了一个串口类(希望可以简单使用的,没有太高的要求的). (1)界面 界

IT 外包中的甲方乙方,德国人,美国人,印度人和日本人印象杂谈

开篇介绍 最近经常和朋友聚会,三十而立的年龄自然讨论最多的就是各自的小家庭,如何赚钱,工作,未来的就业发展,职业转型等话题.还有各种跳槽,机会选择,甲方乙方以及外包中的各种趣事,外企与国内私企的发展机会,还有各种老外大PK.今天在这里也就聊聊这些话题,相信这些话题对现在正在面临一些职业选择的朋友有所借鉴,以及对将要面对一些的人和物有所认识和了解. 当然本文中讲述的一些观点仅为个人观点不代表任何组织和个人,只尽量描述一些我所经历过的或者知道的一些东西.关于外包行业中的这些比较,好与坏,得与失大家可

一个印度人写的文章,看完惊出一身冷汗,肯定包括你!

我自己也有亲身体会,我们身边人看书的的确不多了.当然也不是说我多么喜欢读书了.个人也是没事喜欢看看电影了,单身狗就不没有逛街这个娱乐了.个人有空常去上海图书馆看书,这里看书的人很多,但是大部分是学生 和 老人,或者是父母陪同孩子了. 近日,一名印度工程师所写<令人忧虑,不阅读的中国人>红遍网络.他说,或许不应过分苛责.但我只是忧虑,如果就此疏远了灵魂,未来的中国可能会为此付出代价. 没事陪朋友到图书馆走一趟,而不是电影院,不是大街上! 文如下: 我在从飞往上海的飞机上.正是长途飞行中的睡眠时间

[转]一个普通IT人的十年回顾---金旭亮

金旭亮老师十年体会,很有收获.转自网络. 金旭亮于1989年与超级解霸的开发者梁肇新同时迈入广西大学的校门,却走了一条与其不同的路. 1994年起开始自学计算机专业本科课程,并开始编程,从未间断,迄今已逾10年,仍对软件痴心不改.2002年北京理工大学计算机应用技术专业研究生毕业,后留校任教,主讲程序设计系列课程.2003年在CSDN论坛发表自传——<一个普通IT人的十年回顾>,细诉自己的坎坷学习经历,言辞激昂澎拜,感染了无数学子之心.发表后一石激起千层浪,先后收到近千封国内外邮件,对作者经历

触目惊心:华人大讨论,印度人在很多公司升的很快的原因(总结并欢迎大家分享)(转自北美华人网站)

令面提到的各种案例触目惊心.究竟是不是这样呢?还得请各位读者自行鉴别以及分享更多亲历.下文里面的一些"政治不正确"的说法,不代表本平台观点. 某年年快升的印度职业经理人和他家侄子传授工作经验的原话翻译: 你觉得我们不干活这个世界会受影响么?算了吧,我们又不是解决世界和平和非洲饥饿.要有策略,不要做小事情杂事情,不要做别人看不到的事情,重要的是抓住最显眼的那部分工作去做,让所有人看到你.就像一个邮轮,你要在锅炉房里面烧煤保证引擎工作,这个有意思么?谁看见?看见了也会说你是应该做的.你要站

为什么国外客户愿意把软件交给印度人来做?

因为在硅谷的投资经历,我直接会见过大量在硅印度人的创业公司.在班加罗尔的很多印度软件代工企业,印度的软件外包做得不错,但为什么能做好,媒体上人们分析的原因基本都是不靠谱的. 通过了解印度人的教育结构.以及我直接管理过的印度人做事方式,我充分理解了印度人软件外包做得这么好真正原因所在——是他们远远强于中国人的沟通方式,而不是他们的语言能力. 当年任中兴印度公司CEO不久,我与两个印度员工一起去见客户.他们去之前就列出24个要讨论的问题,用了一上午时间把这24个问题一个一个讨论完了.中午我们到客户办

印度人在接管硅谷的时候,中国人在做什么?

虎嗅注:本文转自微信公众号“纯科学”(ID:chunkexue),原标题<印度对中国真正的威胁是什么>,作者:汪涛.虎嗅获得授权转载,发布时有删节. 我在网上写了很多关于印度的文章,文中结论都依据我在印度长达15年的亲身商业经历,和近三年长驻印度搜集到的第一手资料而得出.仅从不可思议的“印度价格”和“印度时间”来看,印度几乎不可能与中国相竞争.对此,我个人也确实是越来越释怀.但是,另外一个因素却使我越来越忧虑,这就是更加不可思议的“印度管理”. 如果说,在制造业和工作效率上,中国已经甩出印度十

印度人还上不起网?每天超过800万人在火车站使用免费WiFi

印度人还上不起网?早在2015年,谷歌推出了向印度火车站免费提供WiFi的举措,今天这家美国科技巨头宣布该计划已经超过了400个车站的目标,现在每天吸引了超过800万用户. 当Google透露每个月有超过八百万人使用基于铁路的无线网络时,谷歌对该计划的覆盖范围进行了深入的了解.该公司平均说,用户每次会话消耗350MB数据,其中一半通过WiFi程序每天至少两次上网. 在另一个规模的迹象中,谷歌今年早些时候开始通过为价格提供高速连接来实现该计划的货币化.标准选项包括为Google及其合作伙伴(包括印