当前位置:首页>> 深入浅出Win32多线程程序设计之综合实例

深入浅出Win32多线程程序设计之综合实例

发布时间:2017-11-19作者:智汇小新

本章我们将以工业控制和嵌入式系统中运用极为广泛的串口通信为例讲述多线程的典型应用。

而网络通信也是多线程应用最广泛的领域之一,所以本章的最后一节也将对多线程网络通信进行简短的描述。

1.串口通信

在工业控制系统中,工控机(一般都基于PC Windows平台)经常需要与单片机通过串口进行通信。因此,操作和使用PC的串口成为大多数单片机、嵌入式系统领域工程师必须具备的能力。

串口的使用需要通过三个步骤来完成的:

(1) 打开通信端口;

(2) 初始化串口,设置波特率、数据位、停止位、奇偶校验等参数。为了给读者一个直观的印象,下图从Windows的"控制面板->系统->设备管理器->通信端口(COM1)"打开COM的设置窗口:

 



(3) 读写串口。

在WIN32平台下,对通信端口进行操作跟基本的文件操作一样。

创建/打开COM资源

下列函数如果调用成功,则返回一个标识通信端口的句柄,否则返回-1:
 

HADLE CreateFile(PCTSTR lpFileName, //通信端口名,如"COM1"
           WORD dwDesiredAccess, //对资源的访问类型
           WORD dwShareMode, //指定共享模式,COM不能共享,该参数为0
           PSECURITY_ATTRIBUTES lpSecurityAttributes,
           //安全描述符指针,可为NULL
           WORD dwCreationDisposition, //创建方式
           WORD dwFlagsAndAttributes, //文件属性,可为NULL
           HANDLE hTemplateFile //模板文件句柄,置为NULL
           );


获得/设置COM属性

下列函数可以获得COM口的设备控制块,从而获得相关参数:
 

BOOL WINAPI GetCommState(
           HANDLE hFile, //标识通信端口的句柄
           LPDCB lpDCB //指向一个设备控制块(DCB结构)的指针
           );


如果要调整通信端口的参数,则需要重新配置设备控制块,再用WIN32 API SetCommState()函数进行设置:
 

BOOL SetCommState(
           HANDLE hFile, //标识通信端口的句柄
           LPDCB lpDCB //指向一个设备控制块(DCB结构)的指针
           );


DCB结构包含了串口的各项参数设置,如下:
 

typedef struct _DCB
           {
           // dcb
           DWORD DCBlength; // sizeof(DCB)
           DWORD BaudRate; // current baud rate
           DWORD fBinary: 1; // binary mode, no EOF check
           DWORD fParity: 1; // enable parity checking
           DWORD fOutxCtsFlow: 1; // CTS output flow control
           DWORD fOutxDsrFlow: 1; // DSR output flow control
           DWORD fDtrControl: 2; // DTR flow control type
           DWORD fDsrSensitivity: 1; // DSR sensitivity
           DWORD fTXContinueOnXoff: 1; // XOFF continues Tx
           DWORD fOutX: 1; // XON/XOFF out flow control
           DWORD fInX: 1; // XON/XOFF in flow control
           DWORD fErrorChar: 1; // enable error replacement
           DWORD fNull: 1; // enable null stripping
           DWORD fRtsControl: 2; // RTS flow control
           DWORD fAbortOnError: 1; // abort reads/writes on error
           DWORD fDummy2: 17; // reserved
           WORD wReserved; // not currently used
           WORD XonLim; // transmit XON threshold
           WORD XoffLim; // transmit XOFF threshold
           BYTE ByteSize; // number of bits/byte, 4-8
           BYTE Parity; // 0-4=no,odd,even,mark,space
           BYTE StopBits; // 0,1,2 = 1, 1.5, 2
           char XonChar; // Tx and Rx XON character
           char XoffChar; // Tx and Rx XOFF character
           char ErrorChar; // error replacement character
           char EofChar; // end of input character
           char EvtChar; // received event character
           WORD wReserved1; // reserved; do not use
           } DCB;

读写串口

在读写串口之前,还要用PurgeComm()函数清空缓冲区,并用SetCommMask ()函数设置事件掩模来监视指定通信端口上的事件,其原型为:
 

BOOL SetCommMask(
           HANDLE hFile, //标识通信端口的句柄
           DWORD dwEvtMask //能够使能的通信事件
           );


串口上可能发生的事件如下表所示:

事件描述
EV_BREAKA break was detected on input.
EV_CTSThe CTS (clear-to-send) signal changed state.
EV_DSRThe DSR(data-set-ready) signal changed state.
EV_ERRA line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RINGA ring indicator was detected.
EV_RLSDThe RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHARA character was received and placed in the input buffer.
EV_RXFLAGThe event character was received and placed in the input buffer. The event character is specified in the device''''s DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTYThe last character in the output buffer was sent.


在设置好事件掩模后,我们就可以利用WaitCommEvent()函数来等待串口上发生事件,其函数原型为:

BOOL WaitCommEvent(
           HANDLE hFile, //标识通信端口的句柄
           LPDWORD lpEvtMask, //指向存放事件标识变量的指针
           LPOVERLAPPED lpOverlapped, // 指向overlapped结构
           );


我们可以在发生事件后,根据相应的事件类型,进行串口的读写操作:

BOOL ReadFile(HANDLE hFile, //标识通信端口的句柄
           LPVOID lpBuffer, //输入数据Buffer指针
           DWORD nNumberOfBytesToRead, // 需要读取的字节数
           LPDWORD lpNumberOfBytesRead, //实际读取的字节数指针
           LPOVERLAPPED lpOverlapped //指向overlapped结构
           );
           BOOL WriteFile(HANDLE hFile, //标识通信端口的句柄
           LPCVOID lpBuffer, //输出数据Buffer指针
           DWORD nNumberOfBytesToWrite, //需要写的字节数
           LPDWORD lpNumberOfBytesWritten, //实际写入的字节数指针
           LPOVERLAPPED lpOverlapped //指向overlapped结构
           );

 

 

 

公司简介

宜科(天津)电子有限公司是中国工业自动化的领军企业,于2003年在天津投资成立,销售和服务网络覆盖全国。作为中国本土工业自动化产品的提供商和智能制造解决方案的供应商,宜科在汽车、汽车零部件、工程机械、机器人、食品制药、印刷包装、纺织机械、物流设备、电子制造等诸多领域占据领先地位。宜科为智慧工厂的整体规划实施提供自系统层、控制层、网络层到执行层自上而下的全系列服务,产品及解决方案涵盖但不局限于云平台、MES制造执行系统、工业现场总线、工业以太网、工业无线通讯、机器人及智能设备组成的自动化生产线、自动化电气控制系统集成、智能物流仓储系统等,以实现真正智能化的生产制造,从而带来生产力和生产效率的大幅提升,以及对生产灵活性和生产复杂性的管理能力的大幅提升。多年来,宜科以创新的技术、卓越的解决方案和产品坚持不懈地为中国制造业的发展提供全面支持,并以出众的品质和令人信赖的可靠性、领先的技术成就、不懈的创新追求,在业界独树一帜。帮助中国制造业转型升级,加速智能制造进程,成为中国工业4.0智慧工厂解决方案当之无愧的践行者。

更多详情>>

联系我们

  • 联系人:章清涛
  • 热线:18611695135
  • 电话:
  • 传真:
  • 邮箱:18210150532@139.com

Copyright © 2015 ilinki.net Inc. All rights reserved. 智汇工业版权所有

电话:010-62314658 邮箱:service@ilinki.net

主办单位:智汇万联(北京)信息技术有限公司

京ICP备15030148号-1