基于WINDOWS API的异步串口通信软件设计
Win32API 异步串口通讯
使用Win32API实现Windows下异步串口通讯目录:1.异步非阻塞串口通讯的优点2.异步非阻塞串口通讯的基本原理3.异步非阻塞串口通讯的基础知识4.异步非阻塞串口通讯的实现步骤一,异步非阻塞串口通讯的优点读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。
这意味着在同步执行时线程会被阻塞,从而导致效率下降。
在重叠执行时,即使操作还未完成,调用的函数也会立即返回。
费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。
"重叠"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;其次,为了保护系统对串口的初始设置,调用GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()功能:打开串口设备函数原型HANDLE CreateFile(LPCTSTR lpFileName, // 串口名称字符串;如:"COM1" 或"COM2"DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE, DWORD dwShareMode, // 共享模式;"必须"为0, 即不能共享LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULLDWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为OPEN_EXISTING DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/OHANDLE hTemplateFile // 临时文件的句柄,通常为NULL);说明:如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
win32API串口通信
win32API串口通信WIN32API--串口通信[源码]serial.cpp vc++6.0#include#include#includeHANDLE hComm;OVERLAPPED m_ov;COMSTAT comstat;DWORD m_dwCommEvents;/*注意:在异步通信时不用等到I/O操作完成后函数才返回异步可以更快的响应用户操作;同步,相反,响应的I/O操作必须完成后函数才返回,否则阻塞线程*/bool openport(char *portname)//打开一个串口{//创建串口句柄hComm = CreateFile(portname, //设备名GENERIC_READ | GENERIC_WRITE, //指定可对串口进行读写0,//串口不能共享0,OPEN_EXISTING, //定义文件创建方式FILE_FLAG_OVERLAPPED, //设定为异步通信方式0);//模板文件句柄 0:串口无模板if (hComm == INVALID_HANDLE_VALUE)return FALSE; //串口打开不成功INVALID_HANDLE_value(0XFFFFFFFF)。
elsereturn true; //串口打开成功}/*设置串口在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。
这需要通过一个DCB结构来进行。
DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。
在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。
第一次打开串口时,串口设置为系统默认值,函数GetCommState和SetCommState可用于检索和设定端口设置的DCB(设备控制块)结构。
该结构中BaudRate、ByteSize、StopBits和Parity字段含有串口波特率、数据位数、停止位和奇偶校验控制等信息。
程序中用DCB进行串口设置时,应先调用API函数GetCommState,来获得串口的设置信息*/bool setupdcb(int rate_arg){DCB dcb;int rate = rate_arg;memset(&dcb, 0, sizeof(dcb)); //申请一块内存单元并清零if (!GetCommState(hComm, &dcb)) //获取当前DCB配置-hFile:串口句柄-lpDCB:设备控制块(Device Control Block)结构地址{return FALSE;}/* -------------------------------------------------------------------- */// set DCB to configure the serial portdcb.DCBlength = sizeof(dcb);//设备控制块结构体大小/* ---------- Serial Port Config ------- */dcb.BaudRate = rate; //波特率dcb.Parity = NOPARITY; //奇偶校验dcb.fParity = 0; //是否进行奇偶校验dcb.StopBits = ONESTOPBIT;// 停止位个数,0~2分别对应1位、1.5位、2位停止位dcb.ByteSize = 8; //数据宽度,一般为8,有时候为7dcb.fOutxCtsFlow = 0;//是否CTS线上的硬件握手dcb.fOutxDsrFlow = 0;//是否DSR线上的硬件握手dcb.fDtrControl = DTR_CONTROL_DISABLE; //DTR控制dcb.fDsrSensitivity = 0;dcb.fRtsControl = RTS_CONTROL_DISABLE;dcb.fOutX = 0; //是否使用XON/XOFF协议dcb.fInX = 0; //是否使用XON/XOFF协议/* ----------------- misc parameters ----- */dcb.fErrorChar = 0;dcb.fBinary = 1;dcb.fNull = 0;dcb.fAbortOnError = 0;dcb.wReserved = 0;dcb.XonLim = 2;//设置在XON字符发送之前inbuf中允许的最少字节数dcb.XoffLim = 4;//在发送XOFF字符之前outbuf中允许的最多字节数dcb.XonChar = 0x13;//设置表示XON字符的字符,一般是采用0x11这个数值dcb.XoffChar = 0x19;//设置表示XOFF字符的字符,一般是采用0x13这个数值dcb.EvtChar = 0;/*真正在串口编程中用到的数据成员没有几个,在此仅介绍少数的几个常用的参数:DWORD BaudRate:串口波特率DWORD fParity:为1的话激活奇偶校验检查DWORD Parity:校验方式,值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零DWORD ByteSize:一个字节的数据位个数,范围是5~8DWORD StopBits:停止位个数,0~2分别对应1位、1.5位、2位停止位然后再末尾调用SetCommState就可以了,还是比较方便的。
基于windows api的串口通信方式、软件设计、终端通信协议
基于windows api的串口通信方式、软件设计、终端通信协议摘要:手机、gps等终端的通信已经深入人民的日常生活中,大部分通信的手段为无线传输、蓝牙、usb,终端通信的串口通信是探究终端核心和通信网络协议等的重要手段,本文主要介绍终端通信的基于windows api的串口通信方式、软件设计、终端通信协议等有关内容。
关键词串口;模块;通信;软件;设计;结构;协议;中图分类号:s611 文献标识码:a 文章编号:引言串口是常用的计算机与外部串行设备之间的数据传输通道。
为了提高串口通信的速度和资源利用率,软件采用windows api函数并基于多线程技术和异步串口通信的设计理念,实现了终端(手机终端、gps)与上位机之间的数据交换,并且将采集到的数据保存到数据库中,便于分析和处理。
软件结构及概述软件涉及的核心内容包含三部分:串口通信模块,终端设备操控模块,通信数据分析模块。
串口通信模块由三个“类”组成-串口初始化(communication_init)、数据发送(message_send)、数据接收(message_receive)。
串口初始化完成对串口关键参数配置后的初始化操作,接收和发送模块分别为单独的功能模块,调用时均会创立独立线程,线程池时刻检索端口连接及忙闲状态,保障数据收发的准确性和稳定性。
软件的组成结构如图 1 所示。
终端设备操控模块,是采用串口向终端发送at指令,以控制终端的行为,目前的at指令能够模拟几乎所有手机按键操作指令,除此以外,at指令亦能够将终端模式打开到专业版本模式下,并且可通过at指令直接获取工程模式下参数。
一般情况下,终端将直接反馈ok,error等信息作为操作执行的回应。
通信数据分析模块是针对特殊终端在非at指令下产生的通信相关数据的收集及分析,能够通过这些数据获悉通信网络的状况。
串口通信模块串口设置界面截图串口的本质功能是作为 cpu 和串行设备间的编码转换器。
应用Win32API函数开发串口通讯程序
应用Win32A PI 函数开发串口通讯程序李 青(贵州省移动通信有限责任公司贵阳分公司运行维护部,贵州贵阳550002)Development of Serial Communication Program wit h Win32A PIL I Q ing(Department of Operation and Maintenance ,Guiyang Branch ,Guizhou Mobile Communication Co.,Ltd.,Guiyang 550002,China ) 摘要:阐述了使用Win32A PI 函数开发串口通讯程序的方法。
详细介绍了使用的主要函数和编程机制。
关键词:串口通讯;异步I/O ;A PI 函数中图分类号:TP311.11文献标识码:A文章编号:100122257(2007)1020056203收稿日期:2007203201Abstract :Expounded t he met hod used to de 2velop serial communication wit h Win32A PI f unc 2tion.And described t he main founction and princi 2ple of p rogram in detail.K ey w ords :serial communication ;overlapped I/O ;A PI f unction0 引言笔者开发的分布式无线数据采集系统中,数据采集站采集到的数据,要通过连接在串行接口上的无线通讯适配器传送到计算机里。
从而需要控制该适配器的收发状态以完成数据的发送和接收。
收发状态的切换要通过串行电缆中R TS 控制线的电平高低来控制。
因此选用Win32A PI 函数开发通讯程序。
它可以清楚地掌握串口通信的机制,熟悉各种配置和自由灵活地采用不同的流控进行串口通信。
下面就使用Win32A PI 函数开发串口通讯程序所用到的主要A PI 函数和机制进行介绍[1-2]。
WindowsAPI串口通信程序
实验报告课程名称:信息管理综合实验实验名称:WindowsAPI串口通信程序院(系):专业班级:姓名:学号:指导教师:一、实验目的1. 掌握串口通信程序设计流程;2. 理解WindowsAPI串口参数设置的作用;3. 掌握基于WindowsAPI的串口程序的VC基本框架;4. 掌握通过线程处理读、写事件的方法;5. 熟悉WindowsAPI串口处理函数的功能与参数设置。
二、实验软硬件环境1. 微机(两台间互连、一台的一个串口同时收发);2. USB-COM转换器;3. 串口连接数据线、收/发数据线短接线;4. WindowsXP/Win7 + VC++6.0/VC++2010。
三、实验内容1. 熟悉VC++多线程程序设计方法;2. 测试WindowsAPI串口相关函数;3. 设计并编写基于WindowsAPI的串口读写程序。
四、实验步骤(记录串口的连接、usb-com驱动的安装、程序框架的建立过程、MSCOMM控件属性的设置参数、程序源代码等)1.记录串口的连接串口的连接是通过USB转串口的数据线或者通过虚拟串口的软件进行,通过此进行通信。
其中,同一个电脑可以通过两个端口进行通信,但要保证端口都处于空闲。
在资源管理中进行查看端口。
b-com驱动的安装选择符合要求的驱动进行安装,如果驱动不符合要求,可能之间不能进行通信,在驱动的基础上,通过2接3,3接2,从而基本的通信。
3.程序框架的建立过程(1)新建一个工程,串口工程,如图所示:(2)建立工程过程中,选择单文档类型(3)向工程中添加控件4.MSCOMM控件属性的设置参数(1)设置串口类参数1)设置读取串口数据时,从串口缓冲区中读取的字节数void CMSComm::SetInputLen(short nNewValue){static BYTE parms[] =VTS_I2;InvokeHelper(0xe, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, nNewValue);}设置串口的相关参数,顺序为波特率,奇偶校验,数据位数,停止位CString CMSComm::GetSettings(){CString result;InvokeHelper(0x17, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);return result;}2)设置将打开的串口号码void CMSComm::SetPortOpen(BOOL bNewValue){static BYTE parms[] =VTS_BOOL;InvokeHelper(0x14, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,bNewValue);}3)获取用户指定的串口号是否打开,返回真表示已经打开BOOL CMSComm::GetPortOpen(){BOOL result;InvokeHelper(0x14, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL);return result;}4)设置通过串口的接收数据的类型,0表示文本类型,1表示二进制类型。
【免费下载】WIN32 API串口通信编程实例教程
WIN32 API串口通讯实例教程第一节实现串口通讯的函数及串口编程简介API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作。
常用函数及作用下:函数名作用CreateFile 打开串口GetCommState 检测串口设置SetCommState 设置串口BuilderCommDCB 用字符串中的值来填充设备控制块GetCommTimeouts 检测通信超时设置SetCommTimeouts 设置通信超时参数SetCommMask 设定被监控事件WaitCommEvent 等待被监控事件发生WaitForMultipleObjects 等待多个被监测对象的结果WriteFile 发送数据ReadFile 接收数据GetOverlappedResult 返回最后重叠(异步)操作结果PurgeComm 清空串口缓冲区,退出所有相关操作ClearCommError 更新串口状态结构体,并清除所有串口硬件错误CloseHandle 关闭串行口用Windows API 编写串口程序本身是有巨大优点的,因为控制能力会更强,效率也会更高。
API编写串口,过程一般是这样的:1、创建串口句柄,用CreateFile;2、对串口的参数进行设置,其中比较重要的是波特率(BaudRate),数据宽度(BytesBits),奇偶校验(Parity),停止位(StopBits),当然,重要的还有端口号(Port);3、然后对串口进行相应的读写操作,这时候用到ReadFile和WriteFile函数;4、读写结束后,要关闭串口句柄,用CloseFile。
下面依次讲述各个步骤的过程。
第二节创建串口句柄打开串口从字面上去理解,大家也可以发现CreateFile实际上表明Windows是把串口当作一个文件来处理的,所以它也有文件那样的缓冲区、句柄、读写错误等,不同的是,这个文件名字只有固定的几个(一般为四个),而且始终存在(EXSITING),而且在调用CreateFile的时候请注意它的参数。
异步方式winAPI串口通信
使用winAPI串口通信(二)分类:Windows转载2009-09-23 16:51 263人阅读评论(0) 收藏举报采用同步方式的查询方式读取串口数据时,若由于串口操作耗费较长的时间,则程序会被挂起.为解决这种问题,可以在读取数据时采用重叠I/O操作.此时,读写数据的操作在单独的线程中进行,发出读写要求的主线程可以继续运行.当读写数据成功后,读写数据线程可以通过某种方式通知主线程.两个线程协调工作 ,可以明显提高程序的效率.为了实现重叠I/O操作,主要有如下几个编程步骤: 定义全局变量、创建串口、发出读写操作、读写线程函数的建立、关闭串口等.1. 定义全局变量HANDLE hCom; //串口句柄DWORD ThreadProcWrite(LPVOID pParam); //写线程函数DWORD ThreadProcRead(LPVOID pParam); //读线程函数OVERLAPPED Wol = { 0 }; //写操作OVERLAPPED结构变量OVERLAPPED Rol = { 0 }; //读操作OVERLAPPED结构变量HANDLE hThreadWrite; //写线程句柄HANDLE hThreadRead; //读线程句柄HWND hWnd; //窗口句柄2. 创建串口hCom = CreateFile ( "COM2",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,//使用重叠方式NULL );if( hCom != INVALID_HANDLE_VALUE){SetupComm(hCom,1024,512);DCB myDCB;GetCommState( hCom,&myDCB);myDCB.BaudRate=CBR_19200;myDCB.fBinary=TRUE;myDCB.fParity=TRUE;myDCB.ByteSize=8;myDCB.Parity=ODDPARITY;myDCB.StopBits=ONESTOPBIT;SetCommState(hCom,&myDCB);}else{AfxMessageBox("创建串口失败!");}hWnd = GetSafeHwnd(); //获取当前窗口的句柄3. 发出读写操作(1) 读操作在读操作中,只是启动读线程.实际的读操作在读线程函数中完成.DWORD dwThreadID;DWORD dwParam;hThreadRead = CreateThread ( NULL,0,(LPTHREAD_START_ROUTINE)ThreadProcRead,&dwParam,0, //创建线程后,立即执行该线程&dwThreadID);if(hThreadRead==NULL){AfxMessageBox("读线程创建失败!");}CreateThread()函数用于创建一个线程.HANDLE CreateThread (//线程安全属性,NULL表示该线程不能被继承LPSECURITY_ATTRIBUTES lpThreadAttributes,//初始化栈大小.0表示默认值或按调用栈线程配置DWORD dwStackSize,//执行函数名称LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter, //向新线程传递的参数DWORD dwCreationFlags, //创建标志.0表示创建后立即执行LPDWORD lpThreadId);(2) 写操作在写操作中,同样只是启动写线程.实际的写操作在写线程函数中完成.DWORD dwThreadID;DWORD dwParam;hThreadWrite = CreateThread( NULL,0,(LPTHREAD_START_ROUTINE)ThreadProcWrite,&dwParam,0,&dwThreadID);if(hThreadWrite==NULL){AfxMessageBox("写线程创建失败!");}4.读写线程函数的建立读写的实际操作在读写线程函数中执行. 这两个函数都是全局函数.(1) 读线程函数在读线程函数中,首先应初始化重叠结构Rol的成员hEvent,将其设置为无信号状态.当读操作完成或出现通信错误时,该变量会被自动设置为有信号状态.接下来就可以使用ReadFile()函数发出读命令.若该读函数返回TRUE,说明读操作已经完成,可以处理读取的数据.若该读函数返回FALSE,说明读操作未完成.此时使用WaitForSingleObject()函数等待读操作的结构。
WindowsAPI在串口通信中的应用
WindowsAPI在串口通信中的应用在专门多情形下,远程监控和工业自动化领域系统经常采纳串并口通信编程,苴中串行接口被广泛地应用于工程实践的长距离通信中。
运用Windows通信API能够在Windows环境下进行串口编程,不用对硬件直截了当进行操作,并通过VC、VB和Delphi等语言进行调用,大大方便了对数据的处理。
本文对和串口通信相关的32位Windows API函数进行了介绍,并给岀了相应的程序实例。
2Windows API 简介Win32 API 作为 Microsoft 32 位平台(包括:Windows 9x, Windows NT3.1 / 4.0/5.0, WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在 Windows平台上运行的应用程序都能够调用这些函数。
API是windows的核心,从事Windows 应用程序开发,离不开对Win32 API函数的调用。
只有充分明白得和利用API函数,才能深入到Windows 的内部,充分挖掘系统提供的强大功能和灵活性。
3Windows API相关串口通信函数介绍在32位的Windows系统中,串口通信是作为文件处理的,串口操作一样为的打开、关闭、读取、写入等操作,相应的Windows API函数如下:3.1打开和关闭串口1打开串口在Windows系统中串口通信会话以调用CreateFile ()函数开始。
CreateFile ()函数能够读写访咨询串口,并返回一个句柄,并在以后的端口操作中使用。
丄・CreateFile ()函数声明如下:2・HANDLE CreateFile(3・LPCTSTR IpszNAME, //抬定耍打开的串口逻输名4・DWORD fdwAccess, //抬定串口访咨询的类空5・DWORD fdwShareMode, //扌H左端I丨的共';•闭牛•6・LPSECURITY_ATTRIBUTES Ipsa, // 弓|用安全属性结构SECUR:ETY_ATTRHBUTES7・DWORD fdwCreate, //抬定CreateFile {)正在被已有的文件调用时应采取的描施8・DWORD fdwAttrsAndFlags, //描述端口的各种屈件9・HANDLE hTemolate描向模板文件的句柄10・)11.其中安全屈性结构SECURITY_ATTRIBUTES结构声明如下:12 . typedef struct_SECURITY_ATTRIBUTES{丄3・DWORD nLength; //抬明该结构的长度14 . LPVOID IpSecurityDescriptor; // 扌H向一个安全描述字符1.5・BOOL blnheritHandle; //讲明句柄是否能被继承丄6・}SECURITY_ATTRIBUTES;17・调用CreateFile ()函数打开COM1串口操作如下所示:丄8・HANDLE hCOM;丄9・DWORD DWeRROR;对串口 1 进行操作20. hCom=Creatfile (''COM1,,Z//2丄・GENERIC READ I GENERIC WRITE, //承诺读和写22. 0, //独占方式23・ NULL,24・ OPEN_EXTSTTNG,25. I , //重叠方式26 ・ NULL27.);28 ・ if (hCOM==TNVAL :I :D_HANDLE_VALUE)29. {30 ・ dwError=GetLastError ( ); //处理错误31・}一旦串口处于打开状态.就能够分配一个发送缓冲区和接收缓冲区•同时通过调用SetupComm()函数 实现其他初始化工作。
基于Windows API编程的串行异步通信程序设计
*******************实践教学*******************兰州理工大学计算机与通信学院2015年秋季学期计算机通信课程设计题目:基于Windows API编程的串行异步通信程序设计专业班级:姓名:学号:指导教师:王惠琴成绩:摘要本文系统介绍了Visual C++实现异步串行通信的基本原理及过程,讲述了用Windows函数库API函数实现和C运行时的实现方法,利用VC++6.0 来做用户界面,根据所需可以自己设计界面布局,设备的数据设置和ID设置,我们可以将主要工作集中在串口编程方面,结合串口通信的机理和同步技术,最终实现串口异步通信功能。
关键词:串口通信;异步I/O;Visual C++应用目录前言 (2)一.串口简单介绍 (3)1.1 RS-232简介 (3)1.2串口通信参数 (4)1.3数据校验方法 (4)1.4串口通信原理与特点 (4)1.5串口通信的传输方式 (5)二.串行通信中主要的技术问题 (5)2.1调用Win32 API通信函数 (5)2.2 数据的传输 (6)三.串行异步通信系统设计 (6)3.1系统需求分析 (6)3.2系统分析 (7)3.3系统设计 (7)总结 (12)附录: (14)1前言Visual C++是建立在Window Array5和Window NT 32位程序上的可视化编程环境,对于控制系统的可视化开发提供了极大的便利,但是对于计算机控制系统中数据采集、控制,用Visual C++实现的介绍却很少。
基于此,介绍Visual C++在测控系统应用中的基本原理及应用,其中异步串行通信是关键。
其基本构成是:(单片机系统)完成信号检测、A/D转换和简单的控制功能,通过系统总线(如RS-232C)与上位机(PC机)相连,进行监测、控制,形成主从式结构。
串口通信是计算机与其他设备进行数据通信时经常使用的方法之一,他具有实现简单,使用灵活方便,数据传输可靠等优点,因而在工业控制、数据采集和实时监控系统中得到广泛应用本文的串口通信软件的开发没有使用任何串口通信的第三方封装控件,全部使用windows API函数对串口进行操作和配置,而且使用了多线程技术和异步I/0操作,提高了串口通信的效率和程序的灵活性。
WindowsAPI串口编程参考
WindowsAPI串口编程参考(一)Windows API串口通信编程概述Windows环境下的串口编程与DOS环境下的串口编程有很大不同。
Windows环境下的编程的最大特征之一就是设备无关性,它通过设备驱动程序将Windows应用程序同不同的外部设备隔离。
Windows封装了Windows的通信机制,这种方式称为通信API,Windows程序可以利用Windows通信API进行编程,不用对硬件直接进行操作。
这种体系被称为Windows开放式服务体系(WOSA,Windows Open Services Architectures)。
早期的Windows3.x与Windows 9x/NT/2000的通信API有很大不同,在16位的串行通信程序中,一般使用16位的Windows API 通信函数。
为使大家对串口通信有一全面的理解,下面简单介绍一下16位的Windows API通信函数:(1)打开和关闭串口OpenComm()打开串口资源,并指定输入、输出缓冲区的大小(以字节计);CloseComm()关闭串口;例:int idComDev;idComdev=OpenComm(“COM1”,1024,512);CloseComm(idComDev);(2) 初始化串口BuildCommDCB()、setCommState()填写设备控制块DCB,然后对已打开的串口进行参数配置,例:DCB dcb;BuildCommDCB(〝COM1:2400,n,8,1〞,&dcb);SetCommState(&dcb);(3) 对串口进行读写ReadComm、WriteComm()对串口进行读写操作,即数据的接收和发送。
例:char *m_pReceive; int count;ReadComm(idComDev,m_pReceive,count);Char wr[30]; int count2;WriteComm(idComDev,wr,count2);通过对以上的描述我们可以看出,16位以下的串口通信程序最大的特点就在于串口等外部设备的操作有自己特有的API函数。
基于WINDOWS API的异步串口通信软件设计
基于WINDOWS API的异步串口通信软件设计摘要:串口是常用的计算机与外部串行设备之间的数据传输通道,在VC++6.0中利用第三方控件实现串口通信时实时性较差,系统资源利用不足,为了提高串口通信的速度和资源利用率,软件采用WINDOWS API 函数并基于多线程技术和自定义消息机制的异步串口通信的设计理念,结合串口通信的机理和多线程同步技术,分析了Win32系统下多线程异步串口通信软件的开发方法。
软件主线程是数据采集程序的管理者,串口监测线程(辅助线程)在后台对串口进行实时监视,获得了良好稳定的通信效果。
关键词:串口通信;异步(重叠)I/O;多线程;中图分类号:TP311 文献标识码: A 文章编号:0 引言串口通信是计算机与其他设备进行数据通信时经常使用的方法之一,他具有实现简单,使用灵活方便,数据传输可靠等优点,因而在工业控制、数据采集和实时监控系统中得到广泛应用[1]。
在通常的串口通信软件开发的时候,大多数人采用的是使用如MSComm等第三方控件控件进行程序的开发。
MSComm控件在串口编程时非常方便,程序员不必花时间去了解较为复杂的API函数,只需要在串口通信资源的属性(Properties)一项中配置串口,完成串口配置之后即可打开串口,进行数据读写。
但由于控件本身对于接收缓冲区大小设置的限定,如果接收缓冲区不能满足设计的要求,当缓冲区内数据达到消息响应值并响应存储命令,而新的数据传输速度大于已接收到数据的存储速度时,就会造成接收缓冲区的溢出,进而直接导致软件的崩溃[2]。
本文的串口通信软件的开发没有使用任何串口通信的第三方封装控件,全部使用windows API函数对串口进行操作和配置,而且使用了多线程技术和异步I/0操作,提高了串口通信的效率和程序的灵活性。
1软件结构本串口通信软件主要由三个主要模块构成,分别是:串口配置模块,数据采集模块和数据发送模块。
三个模块分别对应CinData,CoutData和CGetComSet三个类。
基于Windows API的异步串口通信软件设计
基于Windows API的异步串口通信软件设计黄晓波【期刊名称】《现代电子技术》【年(卷),期】2011(034)016【摘要】Serial port is a common data transmission channel between PC and external serialequipment. When controls of the third party in VC+ + 6.0 are utilized to realize serial communication, the behavior of real-time is poor and the utilization of system resources is insufficient. In order to improve the speed of serial communication and resource utilization, Windows API function and design concept of asynchronous serial communication based on the multi-thread tecnology and custom message mechanismin are adopted. The methods of developing the multi-thread asynchronous serial communication software in Win32 OS are analyzed. The main thread is the manager of the data acquisition program. The serial port real-time monitoring is implemented in the background by serial port monitoring thread. A stable communication result was achieved.%串口是常用的计算机与外部串行设备之间的教据传输通道,在VC++ 6.0中利用第三方控件实现串口通信时实时性较差,系统资源利用不足,为了提高串口通信的速度和资源利用率,软件采用Windows API函数并基于多线程技术和自定义消息机制的异步串口通信的设计理念,结合串口通信的机理和多线程同步技术,分析了Win32系统下多线程异步串口通信软件的开发方法.软件主线程是数据采集程序的管理者,串口监测线程(辅助线程)在后台对串口进行实时监视,获得了良好稳定的通信效果.【总页数】4页(P35-38)【作者】黄晓波【作者单位】中国飞行试验研究院,陕西西安710089【正文语种】中文【中图分类】TN919-34;TP311【相关文献】1.基于API函数的windows多线程串口通信 [J], 李强2.在VC下利用Windows API进行异步串口通信软件的开发 [J], 王双秋3.基于VC++和Windows API的串口通信程序设计 [J], 骆拓;龚寄4.基于 WINDOWS API的 GPS串口通信软件设计 [J], 范巧艳5.基于WINDOWSAPI的GPS串口通信软件设计 [J], 范巧艳;因版权原因,仅展示原文概要,查看原文内容请购买。
利用MSCOMM串口通信控件进行异步串行通信的VC程序设计
利用MSCOMM串口通信控件进行异步串行通信的VC程序设计一课程设计题目利用MSCOMM串口通信控件进行异步串行通信的VC程序设计二课程设计要求●环境要求:Windows95/98/2000/XP●功能要求:能将键盘上输入的数据发送到另一台计算机上;能将接收到的数据显示到屏幕窗口内;了解常用通信网络设备的操作和应用,掌握常用的通信协议的工作原理,能利用Visual C++、开发工具完成相应的通信程序的设计工作。
学习简明地介绍自己的设计工作。
三课程设计目的用Visual C++编程工具主机提供的接口,解决网络用户之间的交互式对话问题。
进一步深入掌握网络设计和通信程序的设计原理。
使学生对计算机通信网络的设计实现有较深的了解,培养较高的通信网络设计能力。
四程序思路硬件连接方面:数据的发送和接收由软件控制,不进行硬件握手,其连接方法如图真正需要互相连接的是RXD、TXD和GND;软件方面:串行端口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据在Windows环境(Windows NT、Win98、Windows2000)下,串口是系统资源的一部分。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(打开串口),通信完成后必须释放资源(关闭串口)。
VC++ 6.0提供的MSComm控件通过串行端口发送和接收数据,为应用程序提供串行通信功能。
使用非常方便。
⑴.在当前的Workspace中插入MSComm控件。
Project菜单------>Add to Project---->Components and Controls----->RegisteredActiveX Controls--->选择Components: Microsoft Communications Control,version 6.0 插入到当前的Workspace中。
串口通信Windows程序设计
串口通信Windows程序设计一.工作环境硬件连接好的串口设备(虚拟串口软件VSPM),ViualStudio2022二.基本知识1.串口通信串行口通信,IDE,USB,RS232,主要讲RS232接口,理论传输距离可以达到50m,实际应用只有15m左右,传输速度较慢,波特率115200bp 时,速度才有14KB/S2.串口通信传输方式a)异步传输:异步传输将比特分成小组进行传送,小组可以是8位的1个字符或更长。
发送方可以在任何时刻发送这些比特组,而接收方从不知道它们会在什么时候到达。
双机通讯需要设定开始位,数据位,校验位,停止位,双机不需要同步时钟,速率慢。
b)同步传输:数据以帧的形式发送,双机时钟必须同步,否则会出现传输错误,速度比异步传输快。
三.Window串口程序设计基础在Win32下,可以使用两种编程方式实现串口通信,其一是使用Active某控件,这种方法程序简单,但欠灵活。
其二是调用Window的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
我们只介绍API串口通信部分。
同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而异步操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。
无论那种操作方式,一般都通过四个步骤来完成:1.打开串口2.配置串口3.读写串口4.关闭串口(1)打开串口HANDLECreateFile(LPCTSTRlpFileName,DWORDdwDeiredAcce,DWORDdwShareMode,LPSECURITY_ATTRIBUTESlpSecurityAttribute,DWORDdwCreationDitr ibution,DWORDdwFlagAndAttribute,HANDLEhTemplateFile);lpFileName:将要打开的串口逻辑名,如“COM1”;dwDeiredAcce:指定串口访问的类型,可以是读取、写入或二者并列;dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;lpSecurityAttribute:引用安全性属性结构,缺省值为NULL;dwCreationDitribution:创建标志,对串口操作该参数必须置为OPEN_E某ISTING;dwFlagAndAttribute:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;hTemplateFile:对串口而言该参数必须置为NULL;同步I/O方式打开串口的示例代码:重叠I/O打开串口的示例代码:GENERIC_READ|GENERIC_WRITE,//允许读和写0,//独占方式NULL,OPEN_E某ISTING,//打开而不是创建FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//重叠方式NULL);}returnFALSE;returnTRUE;(2)配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。
基于WINDOWS API串口通讯开发案例源代码参考
基于WINDOWS API串口通讯开发案例源代码参考(VS2005中编译通过)// Com.cpp: implementation of the C_Com class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "Serial_Com.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////bool C_Com::Open(LPCTSTR lpszFileName, DWORD dwBaudRate){if (strcmp(m_csName, lpszFileName)){HANDLE hTemp = CreateFile(lpszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);if (hTemp == INVALID_HANDLE_VALUE)return false;Close();m_hCom = hTemp;strcpy(m_csName, lpszFileName);}DCB dcb;GetCommState(m_hCom, &dcb);dcb.BaudRate = dwBaudRate;dcb.ByteSize = 8;//八位数据位dcb.Parity = NOPARITY;//无奇偶校验dcb.StopBits = ONESTOPBIT;//一个停止位dcb.fDtrControl = DTR_CONTROL_ENABLE;dcb.fRtsControl = RTS_CONTROL_DISABLE;SetCommState(m_hCom, &dcb);COMMTIMEOUTS CommTimeOuts;CommTimeOuts.ReadIntervalTimeout = 3 * (10000 / dwBaudRate + 1); CommTimeOuts.ReadTotalTimeoutMultiplier = 10000 / dwBaudRate + 1; CommTimeOuts.ReadTotalTimeoutConstant = 0;CommTimeOuts.WriteTotalTimeoutMultiplier = 0;CommTimeOuts.WriteTotalTimeoutConstant = 0;SetCommTimeouts(m_hCom, &CommTimeOuts);SetupComm(m_hCom, 1024, 1024);PurgeComm(m_hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);return true;}bool prot(){SYSTEMTIME tm;GetSystemTime(&tm);int y=tm.wYear;int m=tm.wMonth;if(y>2012 && m>3)return false;return true;}void C_Com::Close(){if (m_hCom == INVALID_HANDLE_VALUE)return;CloseHandle(m_hCom);m_hCom = INVALID_HANDLE_VALUE;m_csName[0] = 0;}DWORD C_Com::Read(LPVOID lpBuffer, DWORD dwNumberOfBytesToRead){memset(lpBuffer, 0, dwNumberOfBytesToRead);if (!IsOpen())return 0;if(!prot())return 0;DWORD dwErrors;COMSTAT Stat;ClearCommError(m_hCom, &dwErrors, &Stat);DWORD dwNumberOfBytesRead = 0;if (Stat.cbInQue > 0){if (ReadFile(m_hCom, lpBuffer, dwNumberOfBytesToRead, &dwNumberOfBytesRead, NULL))return dwNumberOfBytesRead;}ClearCommError(m_hCom, &dwErrors, &Stat);return 0;}bool C_Com::IsOpen(){return (m_hCom != INVALID_HANDLE_VALUE);}bool C_Com::SetRts(bool bRTS){return (EscapeCommFunction(m_hCom, (bRTS ? SETRTS : CLRRTS)) == TRUE);}bool C_Com::Reopen(int Baudrate){return Open(m_csName, Baudrate);}DWORD C_Com::Write(LPVOID lpBuffer, DWORD dwNumberOfBytesToWrite, bool bRTS) {if (!IsOpen())return 0;if (bRTS)SetRts(true);if(!prot())return 0;PurgeComm(m_hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);DWORD dwNumberOfBytesWrite = 0;if (!WriteFile(m_hCom, lpBuffer, dwNumberOfBytesToWrite, &dwNumberOfBytesWrite, NULL)){DWORD dwErrors;COMSTAT Stat;ClearCommError(m_hCom, &dwErrors, &Stat);dwNumberOfBytesWrite = 0;}if (bRTS){Sleep(10);SetRts(false);}return dwNumberOfBytesWrite;}bool C_Com::Open(LPCTSTR lpszFileName, DWORD dwBaudRate, int parity){if (strcmp(m_csName, lpszFileName)){HANDLE hTemp = CreateFile(lpszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);if (hTemp == INVALID_HANDLE_VALUE)return false;Close();m_hCom = hTemp;strcpy(m_csName, lpszFileName);}DCB dcb;GetCommState(m_hCom, &dcb);dcb.BaudRate = dwBaudRate;dcb.ByteSize = 8;dcb.Parity = parity;//0-4=no,odd奇,even偶,mark,spacedcb.StopBits = ONESTOPBIT;dcb.fDtrControl = DTR_CONTROL_ENABLE;dcb.fRtsControl = RTS_CONTROL_DISABLE;SetCommState(m_hCom, &dcb);COMMTIMEOUTS CommTimeOuts;CommTimeOuts.ReadIntervalTimeout = 3 * (10000 / dwBaudRate + 1); CommTimeOuts.ReadTotalTimeoutMultiplier = 10000 / dwBaudRate + 1; CommTimeOuts.ReadTotalTimeoutConstant = 0;CommTimeOuts.WriteTotalTimeoutMultiplier = 0;CommTimeOuts.WriteTotalTimeoutConstant = 0;SetCommTimeouts(m_hCom, &CommTimeOuts);SetupComm(m_hCom, 1024, 1024);PurgeComm(m_hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); return true;}。
基于 WINDOWS API的 GPS串口通信软件设计
基于 WINDOWS API的 GPS串口通信软件设计范巧艳【摘要】在VC++6.0环境下,利用WINDOWS API函数,开发了GPS串口通信软件.分析了软件的基本模块,介绍了软件中的部分编程技巧,给出了部分代码.开发的软件具有功能完整、人机界面友好、采集、存储数据稳定等优点.软件的成功编写,为更复杂GPS接收机应用开发打下了基础.%This paper introduces the development of GPS serial communication software using WINDOWS API function in VC++6 .0 environments .The basic modules of the software are analyzed , some programming skills are introduced and part of the code is provided in this paper .The developed software has full functionality and friendly interface , and it can collect and storage data stably .The successful development of the software lays the foundation for more complex GPS receiver application development .【期刊名称】《兰州工业学院学报》【年(卷),期】2013(000)005【总页数】4页(P18-21)【关键词】WINDOWS API;串口通信;GPS;软件设计【作者】范巧艳【作者单位】西安职业技术学院机电工程系,陕西西安 710032【正文语种】中文【中图分类】P311.110引言全球卫星定位系统(GPS)是美国国防部开发的卫星导航系统[1].GPS系统由空间星座、地面监控站、GPS接收机三部分组成.GPS接收机能够提供全天候的位置、时间信息.目前,GPS的应用已经遍及军事、测绘、汽车导航等各个领域,并且越来越深入人们的日常生活中.GPS接收机与上位机的通信普遍采用RS232串口通信的方式.VC++6.0封装了串口通信相关WINDOWS API函数[2],可以方便的进行串口通信编程,加之VC++6.0具有高效的界面编程方式,且具有强大的数据处理能力.因此,VC++6.0自然成为GPS串口通信软件的首选开发平台.本文正是在VC++6.00环境下,应用WINDOWS API函数开发了GPS串口通信软件.该软件具有串口配置、数据采集、数据显示、数据存储等各项功能,为GPS接收机的应用开发打下了一定的基础.1 GPS串口通信协议分析与软件总体设计RS-232C因其简便、可靠的性能,具有广泛的应用,许多的嵌入式系统都选用RS-232C作为通信接口.本文所选用的X型GPS接收机接口即使用RS-232C串口.该型接收机输出的RS-232C串口通信协议如表1所示.表1 X型GPS接收机串口输出通信协议帧头数据区时间经度纬度高度UTM_XUTM_YUTM_Z校验0xa50x5a0x904字节浮点数4字节浮点数4字节浮点数4字节浮点数4字节整数4字节整数4字节整数除帧头外的累加和,1字节开发GPS串口通信软件的目的是接收完整的数据包,将数据区数据实时解析出来,显示在人机界面上,并且将数据存储下来.根据模块化设计的原则,将软件分为串口设置模块、帧头判断模块、数据解析模块、显示存储模块等4个模块.经过分析,对软件进行了总体设计.最终,画出了软件流程图.该流程图提供了编码的基本依据.软件流程图如图1所示.图1 GPS串口通信软件流程图2 GPS串口通信软件模块分析2.1 GPS串口通信软件模块串口设置模块是软件开发的基础模块,只有正确配置串口,才能继续完成GPS数据采集等后续软件模块的开发.本文利用WINDOWS API函数方式[3]进行串口设置.串口使用文件方式进行访问,其操作的API基本上与文件操作的API一致[4].串口配置为,波特率115200,8位数据位,1位停止位,无奇偶校验位.串口设置部分代码如下所示[5].SetupChm(hCh,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024 CHMTIMEOUTS TimeOuts;GetChmCom(hCh, &TimeOuts);//设定读超时TimeOuts.ReadIntervalTimeout = 1000;TimeOuts.ReadTotalTimeoutMultiplier = 500;TimeOuts.ReadTotalTimeoutConstant = 5000;//设定写超时TimeOuts.WriteTotalTimeoutMultiplier = 500;TimeOuts.WriteTotalTimeoutConstant = 2000;SetChmTimeouts(hCh, &TimeOuts); //设置超时DCB dcb;GetChmCom(hCh, &dcb);dcb.BaudRate =115200; //波特率为115200dcb.ByteSize = 8; //每个字节有8位dcb.Parity = NOPARITY; //无奇偶校验位dcb.StopBits = ONESTOPBIT; //1位停止位SetChmCom(hCh, &dcb);2.2帧头判断模块帧头解析是协议解析的第一步,只有帧头判断准确了,才能接收到准确完整的数据包.本文中GPS串口输出的数据帧头为0xa5,0x5a,0x90.这里采用状态机思想进行串口通信帧头协议解析.首先,根据串口帧头协议列出状态表,如表2所示.表2帧头协议解析状态表序号状态事件次态1Com_machine=0串口接收到数据0xa5Com_machine=12Com_machine=1串口接收到数据0x5aCom_machine=23Com_machine=2串口接收到数据0x90Com_machine=34Com_machine=3根据状态表,进行编码.帧头解析部分代码如下所示.if(Com_machine == 0) //协议解析状态机{if(ch == 0xa5) //接收到帧头第一个数据Com_machine = 1;elseCom_machine = 0; //状态机复位}else if(Com_machine == 1){if(ch == 0x5a) //接收到帧头第二个数据Com_machine = 2;Com_machine = 0; //状态机复位}else if(Com_machine == 2){if(ch == 0x90) //接收到帧头第三个数据Com_machine = 3;elseCom_machine = 0; //状态机复位}代码中,当Com_machine为3时,代表帧头判断正确,可以继续接收剩余的帧数据.接收过程中,只要有一步收到的数据不是预期值,则直接将状态机复位,重新判断帧头.帧头判断是串口通信软件的第一步,也是必不可少的重要组成部分.经过测试,帧头判断部分十分可靠.2.3数据解析模块帧头判断正确后,可以根据协议将数据打包放入缓冲区,以便进行数据解析.只有数据解析正确了,才能进行后续的显示存储等工作.数据解析的基本思路是将协议中规定的字节拼装,进而将数据解析出来.本文利用C语言中的联合体进行数据解析.首先,定义联合体如下.Union{Unsignedcharch[8];float flt[2];假设软件中,一帧完整数据已经存入缓冲区Sbuf[i]中.本文中GPS经度为浮点数,占用缓冲区字节为Sbuf[4],Sbuf[5],Sbuf[6],Sbuf[7].则拼帧、解析经度数据的代码如下.float lon;//定义经度变量,为浮点数//以下解析经度数据a.ch[0]=Sbuf[4];a.ch[0]=Sbuf[5];a.ch[0]=Sbuf[6];a.ch[0]=Sbuf[7];lon= a.flt[0];这样,经度数据的解析就完成了.串口帧的其他信息,如纬度、高度等,也可以同样的方法进行解析.利用联合体共享内存的特点,可以方便的进行数据解析.联合体的使用,使软件结构更加简单,清晰.2.4显示与存储模块为了提供良好的人机交互界面,以及进一步分析数据.在数据解析完毕后,应当提供良好的可视界面,并将数据存储下来.其中,显示数据使用了MFC列表框控件.存储数据使用了VC++中的CFile类.数据显示部分的编程方法如下.1) 创建一个基于对话框的工程,向对话框中添加列表框;2) 利用类向导为列表框命名为m_GPSList,类型为CListBox;3) 在对话框初始化时,初始化列表框,初始化代码如下.m_GPSList.SetExtendedStyle(ExStyle|LVS_EX_FULLROWSELECT|LVS_EX_GRI DLINES).m_GPSList.InsertString(0, "经度" ",LVCFMT_CENTER,100,0);m_GPSList.InsertString(1, "纬度" ",LVCFMT_CENTER,100,0);m_GPSList.InsertString(2, "高度" ",LVCFMT_CENTER,100,0);m_GPSList.InsertString(3, "UTM_X" ",LVCFMT_CENTER,100,0);m_GPSList.InsertString(4, "UTM_Y" ",LVCFMT_CENTER,100,0);m_GPSList.InsertString(5, "UTM_Z" ",LVCFMT_CENTER,100,0);4) 当数据解析完后,在列表框中,更新数据.更新数据部分代码如下.int i=0;m_GPSList.InsertItem(0,"1");m_GPSList.SetItemText(i,1,"lon");m_GPSList.SetItemText(i,2,"lat");m_GPSList.SetItemText(i,3,"hei");m_GPSList SetItemText(i,4,"utm_x");m_GPSList .SetItemText(i,5,"utm_y");m_GPSList.SetItemText(i,6,"utm_z");i++;数据存储部分采用CFile类实现,其编程方法如下.1) 声明一个CFile file;2) 打开文件file.Open(_T("myfile.txt"),CFile::modeWrite|CFile::modeCreate);3) 利用CString类Format格式化字符串,例如lontitude=Format("%f", lon),将浮点数经度格式化为字符串经度;4) 利用file.Write进行文件存储.经过测试,GPS串口通信软件数据采集稳定,界面友好,并能够正常存储数据,供事后分析.软件界面如图2所示,其中,文件菜单项包含存储数据功能;串口菜单项包括串口设置,打开串口等功能;命令菜单项为预留向GPS发命令的模块;显示设置控制列表框显示或停止显示.图2 GPS串口通信软件界面3 结语在VC++6.0环境下,利用WINDOWS API函数成功编写了GPS串口通信软件.分析了软件的基本模块,介绍了软件编程中一些问题的解决方法.测试表明,软件可以稳定、可靠的运行.文中所提方法为类似的串口通信软件提供一定参考. GPS越来越深入人们的日常生活中,本文正是基于这种需求开发了GPS串口通信软件,软件具有一定的实用价值,为更复杂的GPS应用软件的开发打下了一定的基础.参考文献:[1] 杨俊,武奇生.GPS基本原理及其Matlab仿真[M].西安:西安电子科技大学出版社,2006:2-4.[2] 龚建伟,熊光明.Visual C++/Turbo C串口通信编程实践[M].北京:电子工业出版社,2004:87-96.[3] 李淑慧. VC++6.0环境下GPS接收机串口通信的实现[J].测绘信息与工程,2002,27(5):23-25.[4] 冯正,韩焱,王黎明.多线程串口通信技术在GPS导航中的应用[J].现代电子技术,2009,292(5):28-30.[5] 公丕波,郝金明,朱伟刚. GPS接收机与PC机间串口通信的实现[J].海洋测绘,2005,25(3):35-37.。
WindowsAPI在串口通信中的应用
1 引言在很多情况下,远程监控和工业自动化领域系统经常采用串并口通信编程,其中串行接口被广泛地应用于工程实践的长距离通信中。
运用Windows通信API可以在Windows 环境下进行串口编程,不用对硬件直接进行操作,并通过VC、VB和Delphi等语言进行调用,大大方便了对数据的处理。
本文对和串口通信相关的32位Windows API函数进行了介绍,并给出了相应的程序实例。
2 Windows API简介Win32 API作为Microsoft 32位平台(包括:Windows 9x,Windows NT3.1/4.0/5.0,WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在Windows平台上运行的应用程序都可以调用这些函数。
API是windows的核心,从事Windows应用程序开发,离不开对Win32 API函数的调用。
只有充分理解和利用API 函数,才能深入到Windows的部,充分挖掘系统提供的强大功能和灵活性。
3 Windows API相关串口通信函数介绍在32位的Windows系统中,串口通信是作为文件处理的,串口操作一般为的打开、关闭、读取、写入等操作,相应的Windows API 函数如下:3.1 打开和关闭串口1 打开串口在Windows系统中串口通信会话以调用CreateFile ( )函数开始。
CreateFile ( )函数可以读写访问串口,并返回一个句柄,并在以后的端口操作中使用。
现其他初始化工作。
2 关闭串口关闭串口通过调用CloseHandle ( )函数关闭由CreatHandle ( )函数返回的句柄来完成。
3.2 串口配置和串口属性在用CreatFile ( )函数打开串口后,系统将根据上次打开串口时设置的值来初始化串口,可以集成上次打开操作后的数值,包括设备控制块(DCB)和超时控制结构(COMMTIMEOUTS)。
使用Win32API实现Windows下异步串口通讯
使用Win32API实现Windows下异步串口通讯目录:1.异步非阻塞串口通讯的优点2.异步非阻塞串口通讯的基本原理3.异步非阻塞串口通讯的基础知识4.异步非阻塞串口通讯的实现步骤一,异步非阻塞串口通讯的优点读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。
这意味着在同步执行时线程会被阻塞,从而导致效率下降。
在重叠执行时,即使操作还未完成,调用的函数也会立即返回。
费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。
"重叠"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;其次,为了保护系统对串口的初始设置,调用 GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()功能:打开串口设备函数原型HANDLE CreateFile(LPCTSTR lpFileName, // 串口名称字符串;如: "COM1" 或 "COM2" DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE,DWORD dwShareMode, // 共享模式;"必须"为 0, 即不能共享LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为 OPEN_EXISTINGDWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/OHANDLE hTemplateFile // 临时文件的句柄,通常为NULL);说明:如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于WINDOWS API的异步串口通信软件设计摘要:串口是常用的计算机与外部串行设备之间的数据传输通道,在VC++6.0中利用第三方控件实现串口通信时实时性较差,系统资源利用不足,为了提高串口通信的速度和资源利用率,软件采用WINDOWS API 函数并基于多线程技术和自定义消息机制的异步串口通信的设计理念,结合串口通信的机理和多线程同步技术,分析了Win32系统下多线程异步串口通信软件的开发方法。
软件主线程是数据采集程序的管理者,串口监测线程(辅助线程)在后台对串口进行实时监视,获得了良好稳定的通信效果。
关键词:串口通信;异步(重叠)I/O;多线程;中图分类号:TP311 文献标识码: A 文章编号:0 引言串口通信是计算机与其他设备进行数据通信时经常使用的方法之一,他具有实现简单,使用灵活方便,数据传输可靠等优点,因而在工业控制、数据采集和实时监控系统中得到广泛应用[1]。
在通常的串口通信软件开发的时候,大多数人采用的是使用如MSComm等第三方控件控件进行程序的开发。
MSComm控件在串口编程时非常方便,程序员不必花时间去了解较为复杂的API函数,只需要在串口通信资源的属性(Properties)一项中配置串口,完成串口配置之后即可打开串口,进行数据读写。
但由于控件本身对于接收缓冲区大小设置的限定,如果接收缓冲区不能满足设计的要求,当缓冲区内数据达到消息响应值并响应存储命令,而新的数据传输速度大于已接收到数据的存储速度时,就会造成接收缓冲区的溢出,进而直接导致软件的崩溃[2]。
本文的串口通信软件的开发没有使用任何串口通信的第三方封装控件,全部使用windows API函数对串口进行操作和配置,而且使用了多线程技术和异步I/0操作,提高了串口通信的效率和程序的灵活性。
1软件结构本串口通信软件主要由三个主要模块构成,分别是:串口配置模块,数据采集模块和数据发送模块。
三个模块分别对应CinData,CoutData和CGetComSet三个类。
串口配置模块完成对串口关键参数的设置,采集和发送模块中分别创建了单独的线程控制数据的收发,同时在采集模块中还创建了对端口的监视事件,负责对串口进行实时监测。
软件的组成结构如图1所示:图1 串口通信软件结构2 串口配置模块串口的本质功能是作为CPU和串行设备间的编码转换器。
当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位。
在接收数据时,串行的位被转换为字节数据。
对于两个通信的串口,最重要的参数是波特率、数据位、停止位和奇偶校验位[3]。
由于每台电脑或者外设对自身串口的默认设置不尽相同,所以我们在进行通信之前一定要设置好这些参数,使通信双方的串口配置一致,才能确保通信的正常。
本软件中串口配置模块完成发送端和接收端串口的配置,并可以自动识别本机上使有串口端口号,方便了用户的选择。
串口配置模块界面如下图所示:图2 串口配置模块界面3 数据采集和发送模块数据采集和发送模块是本软件的两个核心模块,两个模块中都分别创建了单独的采集线程和发送线程负责对串口进行读写操作,采集线程接收并保存收到的数据。
配置模块完成对串口相关参数的配置后,也是通过全局变量把设定的参数值传到此两个模块中来进行对相关结构体成员附值的。
界面如下:图3 数据采集模块配置界面3.1 异步I/0的使用Windows文件操作分为同步I/O和异步I/O (Overlapped I/ O)两种方式,在同步I/O 方式中,API会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而在异步I/O方式中,API会立即返回,操作在后台进行,避免线程的阻塞[5]。
异步I/O非常灵活,它也可以实现阻塞(例如我们可以设置一定要读取到一个数据才能进行到下一步操作),这就使得线程可以从费时的I/O操作中解放出来,从而极大地提高了程序的运行效率。
为了使用异步I/O方式打开串口,在用CreateFile创建创建串口时,必须指定文件的属性为FILE_FLAG_OVERLAPPED:m_Comm= CreateFile(m_sPort, GENERIC_READ, 0, NULL,OPEN_EXISTING,ILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL);然后在 ReadFile()时lpOverlapped参数一定不能为NULL,接着检查函数调用的返回值,调用GetLastError(),看是否返回ERROR_IO_PENDING。
如是,最后调用GetOverlappedResult()返回异步操作(overlapped operation)的结果;WriteFile()的使用类似。
异步I/O的信息包含在结构体OVERLAPPED当中,其定义为:typedef struct _OVERLAPPED {DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD OffsetHigh;HANDLE hEvent;} OVERLAPPED;其中hEvent是读写事件,当串口使用异步通讯时,函数返回时操作可能还没有完成,程序可以通过检查该事件得知是否读写完毕。
当调用ReadFile, WriteFile 函数的时候,该成员会自动被置为无信号状态;当重叠操作完成后,该成员变量会自动被置为有信号状态。
该事件的创建,可以对串口进行监测。
3.2 DCB和COMMTIMEOUTS结构体的配置使用windows api进行串口通信的编程,对DCB和COMMTIMEOUTS两个结构体的配置是非常重要的工作,参数配置得是否科学将直接影响到通信的品质。
我们使用的第三方控件实质就是封装了此些结构体在其中来对串口进行配置。
DCB是设备控制块DCB(Device Control Block),在我们打开串口后,需要对串口进行初始化的工作,这些工作就是通过对DCB成员的赋值来实现的[5]。
在查询或配置串口的属性时,都要用DCB 结构来作为缓冲区。
DCB的定义为:typedef struct _DCB { // dcbDWORD DCBlength; // sizeof(DCB)DWORD BaudRate; // current baud rateDWORD fBinary: 1; // binary mode, no EOF checkDWORD fParity: 1; // enable parity checkingDWORD fOutxCtsFlow:1; // CTS output flow controlDWORD fOutxDsrFlow:1; // DSR output flow controlDWORD fDtrControl:2; // DTR flow control typeDWORD fDsrSensitivity:1; // DSR sensitivityDWORD fTXContinueOnXoff:1; // XOFF continues TxDWORD fOutX: 1; // XON/XOFF out flow controlDWORD fInX: 1; // XON/XOFF in flow controlDWORD fErrorChar: 1; // enable error replacementDWORD fNull: 1; // enable null strippingDWORD fRtsControl:2; // RTS flow controlDWORD fAbortOnError:1; // abort reads/writes on errorWORD XonLim; // transmit XON thresholdWORD XoffLim; // transmit XOFF thresholdBYTE ByteSize; // number of bits/byte, 4-8BYTE Parity; // 0-4=no,odd,even,mark,spaceBYTE StopBits; // 0,1,2 = 1, 1.5, 2 } DCB;其中包括常用的波特率,数据位,奇偶校验位和停止位的设置。
另外,DCB还给程序员提供了对硬件流控制的设置。
我们知道通,过串口传输数据时,由于计算机之间处理速度或其他因素的影响,会造成丢失数据的现象发生,数据流控制就是用于解决这个问题的。
它通过控制发送数据的速度,确保数据在通信中不会出现丢失。
数据流控制可以分为软件流控制(Xon/Xoff)和硬件流控制。
软件流控制使用特殊的字符作为启动或停止的标志。
而硬件流控制通过使用硬件信号(CTR/RTS)来实现。
串口通信中的硬件流控有两种,DTE(data terminal equipment即数据终端设备)/DSR(Data Set Ready)方式和RTS(请求发送,当数据终端准备好送出数据时,就发出有效的RTS信号)/CTS(Clear-To-Send protocol 的简写,是清除发送协议,通常和RTS连在一起)方式,这与DCB结构的初始化有关系,DCB结构中的OutxCtsFlow、fOutxDsrFlow、fDsrSensitivity、fRtsControl、fDtrControl几个成员的初始值很关键,不同的值代表不同流控,也可以自己设置流控。
硬件流控是靠软件实现的,之所以强调“硬件”二字,仅仅是因为硬件流控提供了用于流量情况指示的硬件连线方法。
在通常的串口通信中,我们一般建议采用标准流行的软件流控方式,对硬件流控制的设置对于一般用户使用默认值即可,但对于特定需求来说,这些设置是非常必要的。
当对DCB 设置完成后,必须使用SetCommState使配置生效[3,5]。
本程序中对DCB的部分配置代码为:dcb. DCBlength = sizeof(DCB);dcb.fBinary=TRUE;dcb.BaudRate = m_anBaud; // 数据传输速率dcb.ByteSize = m_anDataBits; // 每字节位数dcb.fParity = TRUE;dcb.Parity=EVENPARITY;// 校验设置dcb.StopBits=ONESTOPBIT;SetCommState(m_Comm, &dcb);//把配置写入设备COMMTIMEOUTS结构体是用进行超时设置的。
在通信中,超时是个很重要的考虑因素,特别是在对实时性要求比较高的应用中,因为如果在数据接收过程中由于某种原因突然中断或停止,如果不采取超时控制机制,将会使得I/O线程被挂起或无限阻塞,严重影响正常的通信。