异步重叠操作之串口
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。
MFC串口通信编程详解解析
串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式.同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,
}
return TRUE;
二配置串口
在打开通讯设备句柄后,常需要对串口进行一些初始化配置工作.这需要通过一个DCB结构来进行.DCB结构包含了诸如波特率、数据位数、奇偶校验和停止位数等信息.在查询或配置串口的属性时,都要用DCB结构来作为缓冲区.
一般用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置.要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数设置串口.
//EVENPARITY偶校验NOPARITY无校验
//MARKPARITY标记校验ODDPARITY奇校验
BYTE StopBits;//指定停止位的位数.此成员可以有下列值:
//ONESTOPBIT 1位停止位TWOSTOPBITS 2位停止位
//ONE5STOPBITS 1.5位停止位
………
} DCB;
0,//同步方式
NULL;
if(hCom==(HANDLE-1
{
MessageBox("打开COM失败!";
return FALSE;
}
return TRUE;
重叠I/O打开串口的示例:
HANDLE hCom;//全局变量,串口句柄
hCom =CreateFile("COM1",//串口名称
stm32跑RT-thread之串口操作简介
#define SAMPLE_UART_NAME
"uart2" /* 串口设备名称 */
static rt_device_t serial;
/* 串口设备句柄 */
/* 查找串口设备 */
serial = rt_device_find(SAMPLE_UART_NAME);
/* 以 DMA 接收及轮询发送模式打开串口设备 */
460800
#define BAUD_RATE_921600
921600
#define BAUD_RATE_2000000
2000000
#define BAUD_RATE_3000000 /* 数据位可取值 */
3000000
#define DATA_BITS_5
5
#define DATA_BITS_6
要此位也可以。
•
停止位: 表示一帧数据的结束。电平逻辑为 “1”。
•
波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效
位(bit)数来表示,其单位为每秒比特数 bit/s(bps)。常见的波特率值有
4800、9600、14400、38400、115200 等,数值越大数据传输的越快,波特率为
#define RT_DEVICE_FLAG_STREAM
0x040 /* 流模式
*/
/* 接收模式参数 */
#define RT_DEVICE_FLAG_INT_RX
0x100 /* 中断接收模式 */
#define RT_DEVICE_FLAG_DMA_RX /* 发送模式参数 */ #define RT_DEVICE_FLAG_INT_TX
UART 设备 UART 简介
VC++串口通信编程
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。
串口通信方便易行,应用广泛。
一般情况下,工控机和各智能仪表通过RS485总线进行通信。
RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点。
每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。
在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。
其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
本文我们只介绍API串口通信部分。
串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。
同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。
无论那种操作方式,一般都通过四个步骤来完成:(1)打开串口(2)配置串口(3)读写串口(4)关闭串口(1)打开串口Win32系统把文件的概念进行了扩展。
无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。
该函数的原型为:HANDLE CreateFile( LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);•lpFileName:将要打开的串口逻辑名,如“COM1”;•dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列;•dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;•lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;•dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING;•dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;•hTemplateFile:对串口而言该参数必须置为NULL;同步I/O方式打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom=CreateFile("COM1",//COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建0, //同步方式NULL);if(hCom==(HANDLE)-1){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;重叠I/O打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom =CreateFile("COM1", //COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式NULL);if(hCom ==INVALID_HANDLE_VALUE){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;(2)、配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。
异步串口通讯起始位
异步串口通讯起始位
在现代的信息交流中,串口通讯技术扮演着非常重要的角色。
而异步串口通讯作为其中的一种形式,其起始位更是其关键的一环。
异步串口通讯是一种通过串行传输数据的通讯方式,它不需要在发
送和接收端之间共享时钟信号。
而起始位则是在异步串口通讯中用
来标识数据帧的开始的信号位。
在异步串口通讯中,数据是以数据帧的形式进行传输的。
而数
据帧的开始就是由起始位来标识的。
当数据传输开始时,发送端会
发送一个起始位来告知接收端数据的开始。
这个起始位通常是一个
逻辑低电平的信号,用来告知接收端即将有数据到来。
起始位的作用不仅在于标识数据帧的开始,还可以帮助接收端
进行时钟同步。
因为异步串口通讯中没有共享时钟信号,所以起始
位可以作为接收端的时钟同步信号,帮助接收端正确地解析数据帧。
在实际的应用中,正确地处理起始位对于异步串口通讯的稳定
性和可靠性至关重要。
发送端和接收端必须严格按照协议来发送和
接收起始位,以确保数据的准确传输。
总之,异步串口通讯起始位在串口通讯中扮演着至关重要的角色,它不仅标识数据帧的开始,还可以帮助接收端进行时钟同步,保证数据的稳定传输。
因此,对于从事串口通讯的工程师和技术人员来说,深入理解和正确处理起始位是非常重要的。
基于Windows多线程环境下的串口通信
第46卷 第3期 武汉大学学报(自然科学版) V ol.46 N o.3 2000年6月 J.W uhan U niv.(N at.Sci.Ed.) June,2000,373~375文章编号:0253-9888(2000)03-0373-03基于Windows多线程环境下的串口通信陈淑珍,石 波(武汉大学电子信息学学院,武汉430072) 摘 要:根据串口通信的基本原理,结合W indow s环境下的多任务并发机制,采用Window s的多线程技术来实现串口动态实时通信.有效地解决了在串口通信中的实时响应问题,降低了数据的丢失率,提高了系统的可靠性.同时提出了在Window s环境下实现串口通信的一般方法和步骤.实践证明,这种结合多线程技术的串口通信方法具有很强的实用性.关 键 词:多线程;串行通信;实时查询中图分类号:T P311.11 文献标识码:A 在实际的工程应用中,应用程序经常需要具备与外围设备进行通信的能力.在与串口,调制解调器,或是通过电话线进行通信的应用程序中,异步串行通信是一种重要的通信手段.在单任务的操作系统中,应用程序不能处理通信过程中的突发和并发事件,这种缺陷会引起数据丢失和不可靠性.而Window s基于线程的多任务并发机制使得应用程序能同时执行不同的任务,达到了降低数据丢失率,提高系统可靠性的目的.1 串口通信的原理和机制不论何种通信,背后都需要一个通信协议的支持.串口通信大多采用了美国电子工业协会(EIA)于1969年制定的RS-232标准[1].RS-232标准规定了数据终端设备和数据通信设备之间的连接和通信规则.该协议运用RTS(Request to Send)和(Clear to Send)信号来实现串口和外围设备的硬件“握手”,从而建立通信双方的连接和应答.在通信的连接和应答完成以后,双方就可以在误差允许范围内进行串行通信.由于Window s是一个基于消息驱动的操作系统,它的很多消息是从硬件反馈过来的.Window s 不允许程序开发人员直接和硬件打交道,在串口通信方面提供了一组API系统函数来管理串口,这对减低编程工作量,提高系统的稳定性和安全性都是很有好处的.在Win9x操作系统中,对串行通讯设备的操作如同文件的操作一样:串行通讯设备的打开、读写和关闭等操作均与文件操作相同,这和以前Win3x中的通信方式不同.由于w in9x系统中取消了串行通讯中的特定消息WM_COMM NOTIFY(外围通讯设备一有相应事件发生,该消息就会被传送),使得应用程序工作于“事件驱动”方式时,应创建专用的线程来监视有关的串行通讯设备.●打开和关闭串口.通信会话以调用CreateFile函数开始,为读、写操作打开串口.为实现串口的排他性访问,共享标志应设置成false,创建标志应为o pen_exiting,模板句柄应为null,同时返回串口句柄.通信会话通过调用CloseHandle函数来关闭串口占用的内存句柄,释放相应的串口资源.●初始化和配置串口.一旦串口处于打开状态,Window s就可以给串口分配接受和发送缓冲区.缓冲区的大小既可以缺省,也可以指定(调用SetupComm函数).配置串口需要设置串口通讯中特定事件的掩码(调用SetCom mM ask),只要串口中出现特定的消收稿日期:2000-02-22 基金项目:九五国家重点科技攻关项目(204980340)作者简介:陈淑珍(1946-),女,教授,现从事计算机网络与多媒体研究.息,相应的事件掩码就会返回.配置串口还需要设置串口通讯参数(调用SetCom mState(dcb)),例如波特率,数据位,校验位等,其中dcb是特有的参数数据控制模块.dcb可以预先通过GetCo mmState得到缺省值.●读、写串口.在读写串口之前,一定要进行超时设置(调用SetCo mmT imeOuts),因为在读、写过程中可能发生许多不可预见的事件.通过设置超时,能在通讯过程中避免意外发生,保障通讯的安全性.对串行的读写操作(调用ReadFile和WriteFile)就如同对文件的操作一样,在读写串口前需要清理串口通信中的错误信息,并返回当前串口设备的状态.Window s为串口通讯提供了异步I/O的通讯模式.当串口是通过重叠机制打开时,串口就具备了异步I/O的功能,使得应用程序可以后台读、写串口,在前台处理其他任务.这对节省CPU 的运行时间,提高系统的工作效率很有好处.●事件驱动响应.由于Window s是一个基于消息驱动的操作系统.它的许多事件来源于硬件设备,Window s设备驱动程序只是将这些事件进行处理,转换成相应的消息放到Windo w s消息队列中去.由于W in9x取消了串口通讯中的专有消息响应WM_COM M NOTIFY,使得用户进程需要自觉查询串口状态,并对相应事件作出响应[2].Win32API 提供了两个函数来完成这一功能:SetCom mM ask(hcomm,dwM ask),设置串口通讯中特定事件的掩码.不同的掩码对应不同的事件消息.WaitCom mEvent(hComm,&dw Event, &overlapped),在用SetComm Mask指定特定事件以后,就可以调用该函数来等待事件发生.一旦串口有事件发生,参数dw Event会返回相应事件的掩码,用户进程就可以作出相应的处理.同时WaitCom mEvent可以在同步或异步模式下运行.在异步模式下,WaitCommEv en在后台监视串口的状态,直到有事件发生返回(推荐采用).在实际的应用中,这一过程是用专有的监视线程来完成的.监视线程在捕获到特定串口事件以后,应通知主线程作出相应的处理.2 Windows的多线程技术多进程、多线程是Window s等占先式操作系统的一个重要特征.由于有了这种技术支持,使得提高系统的效率,完成多任务并发处理成为可能.进程是应用程序的执行实例,每个进程都具有自己私有的虚拟地址空间、代码、数据和其他系统资源.线程是进程中的一个独立的执行路径[3],一个进程可以拥有多个线程,它们共享同一进程的虚拟地址空间和进程资源.由于共享进程的虚拟地址空间,使得线程间的切换和通信非常便捷、迅速,适合应用程序并发处理的要求.在串口通信过程中,接收的通信请求往往是突发性的.而Windo ws在接收到串口通信请求后,只是和通信缓冲区进行交互,并不给应用程序反馈相应事件消息.应用程序必须自觉查询串口通信状态并作出相应的处理,基于Window s多任务环境下的线程技术,对于解决上述问题是一个很好的途径.操作系统会将CPU时间划分成许多时间片段,并按一定的优先级将时间片段分配给各个线程.各线程在各自的时间片段内共享CPU,从而实现了微观上轮次执行,宏观上并发运行的多任务机制.用户可以根据实际需要创建多个线程来完成系统功能.在支持多线程机制的操作系统中,多线程结构一般分为两个层次来实现,一是工作者线程,一是用户界面线程.工作者线程只具备相应的线程数据结构,对外表现为函数调用;而用户界面线程是线程执行的实体,是系统内核调用的单位,拥有独立的消息循环,两者有着明显的区别.多线程应用系统的设计包含创建线程、线程同步、终止线程3部分,其中关键是要处理好线程之间的同步问题,以避免线程之间出现资源竞争而引起几个线程甚至整个系统的死锁.通常线程中会有访问共享数据区的需求,由于线程运行的时间是不确定的,变量就会出现随机性.Window s提供了几种同步对象,来实现多线程间的同步[4].1)M utex互斥对象:在同一时间允许至多一个线程访问共享数据区.可以在多线程或多个进程间同步.2)Semapho re信号灯:允许一定数量的线程访问共享数据区,适合多个线程共享数据的同步.3)Event事件:事件对象是靠自身是否处于有信号状态以表明共享数据是否可访问,从而达到多线程间同步的目的.3 事件驱动的多线程串口通信在开发多媒体监控系统的实际应用中,由于既要实时监控外部串口的状态,又要及时读写串口的数据,还不能使进程一直等待,所以要产生一个查询374武汉大学学报(自然科学版)第46卷子线程来实时监控串口,另外产生一个处理子线程来读\写串口,而主线程进行正常的Window s 消息处理.主线程在初始化时,要完成串口的打开和初始设置工作,同时创建一个实时监控子线程和一个读写处理子线程.监控子线程一旦发现串口有信号,就会发送一个自定义消息给外部处理子线程,处理线程根据该消息即可判断在串行通讯过程中发生的事件,进而实时处理该信号.两个子线程之间以事件同步对象来实现同步,形成监视串口与读写串口的协调一致.下面介绍本文在开发多媒体监控系统时采用的实际串行通讯方法:●初始化串口和创建监视、读写子线程hcomm =CreateFile(“COM 1”,…);打开串口,返回串口资源句柄.SetupComm (hcom m ,4096,4096);分配串口缓冲区.DWORD dw EvtM ask=EV _RXCHA R;SetCo mmM ask (hcomm ,dw EvtM ask );设置串口通讯事件掩码.DCB dcb;//设备控制模块…;SetCo mmState (hcomm ,&dcb );设置串口通讯参数.m _pMT rd=AfxBeg inT hread(M pro c,…);m _pRT rd=Afx Beg inT hr ead(Mproc,…);创建并启动串口监视线程和读写处理线程●事件响应并在监视和读写子线程间切换在串口监视线程中设置串口通讯事件掩码及重叠机制,允许程序在后台等待串口通讯事件.W indo ws 提供了一个很重要的API 函数W aitComm Event,通过它可以检测到特定的串行通讯事件.当串口监视线程检测到指定通讯事件后,要实现与读写子线程的同步,并同时通过线程间消息传送机制通知读写子线程对串口作相应的操作.4 结束语在现代的操作系统中,支持多线程,提供多任务的并发机制是其一个很重要的特征.本文针对实际应用中对串口通信实时性的要求,提出了运用W indo ws 的多线程技术来实现异步串行通信的方法和步骤,有效的解决了在串口通信中出现的数据丢失和不稳定问题,提高了系统的效率和可靠性,实践证明这是一种有效的途径.参考文献:[1] Charlesa M .W indow s 95T elecom P rogr amming .Beijing :T sing hua U niver sity Pr ess,1998(Ch).[2] Go fton P W.M adter Ser ial Communication .Beijing :Electr ical Industr y P ress ,1995(Ch ).[3] Dav id J K .V isual C ++ 6.0T echnology I nside .Beijing :Hope elect rical P ress.1999(Ch).[4] M U ling -sheng.V isual C ++ 5.0U se A nd Develop .Beijing :T sing hua U niver sity Pr ess ,1998(Ch ).The Serial Communication Based on MultithreadingTechnique of WindowsCHEN Shu -zhen ,SHI Bo(Co llege o f Electr onic I nfo rma tio n,Wuhan U niver sity ,W uha n 430072,China )Abstract :Present a kind of method w hich is used to comm unicate betw een serial serial port and peripheral equipment dy namicly and real-time using m ultithreading technique based on the basic principle of comm unication and multitasking mechanism in the circumstance o f Window s.This method reso lves the questio n of Real -time answ ering in the serial com munication validly ,reduces lo sing rate of data and improves reliability of system .T his article pr esents a general metho d used in the serial com munication w hich is practical.Key words :multithreading;serial com munication;r eal-time query375第3期 陈淑珍等:基于W indo ws 多线程环境下的串口通信。
VC 串口编程基础之如何用 VC 打开串口和关闭串口
VC 串口编程基础之如何用VC 打开串口和关闭串口在对串口进行操作之前都需要先打开串口,VC 串口编程方法分为利用VC 串口控件(或VC 串口类)和直接调用Windows底层API函数(我称之为VC API 串口编程)两种方法,不管哪种方法,其实质都是利用底层API函数对串口进行操作,这里我们来看怎么利用API函数来用VC 打开串口。
在Windows 32位以上操作系统(Win98以上)中,将串口(包括其它通信设备)作为文件来处理,所以串口的打开、读写和关闭所用API函数与文件操作函数一样。
所以打开串口用CreateFile,读串口用ReadFile,写串口用WriteFile,关闭串口用CloseHandle。
一、用VC 打开串口、关闭串口的API函数1、打开串口用CreateFile,其声明如下:1HANDLE CreateFile(2LPCTSTR lpFileName, // file name3DWORD dwDesiredAccess, // access mode4DWORD dwShareMode, // sha re mode5LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD6DWORD dwCreationDisposition, // how to create7DWORD dwFlagsAndAttributes, // file attributes8HANDLE hTemplateFile // handle to template file9);部分参数解释如下:●lpFileNam e:指定要打开的串口逻辑名,用字符串表示,如“COM1”和“COM2”分别表示串口1和串口2,若要知道您的电脑有哪此串口,可以打开设备管理器查看,如下图所示,或用丁丁串口调试助手,这个工具启动后会枚举系统当前存在的串口。
●dwDesiredAccess:访问类型,有读(dwDesiredAccess=GENERIC_READ)、写(dwDesiredAccess=GENERIC_WRITE)或两者兼有((dwDesiredAccess=GENERIC_READ | GENERIC_WRITE)。
串口通讯方法的三种实现
串口基本信息用一台电脑实验串口自发自收,实验前要将串口(以9针为例)的发送引脚(2脚)和接受引脚(3脚)短接。
三线连接:适用于计算机之间尤其是PC机和单片机之间的数据通信。
其连接信号对为(TxD,RxD)、(RxD,TxD)、(SG,SG)。
即发送数据TxD端和接受数据RxD端交叉连接,信号地SG对应连接。
七线交叉连接:适用于同型号的计算机之间的连接,如PC机间的数据通信。
其连接信号对为:(TxD,RxD)、(RxD,TxD)、(SG,SG)、(RTS,CTS)、(CTS,RTS)、(DSR.DTR)、(DTR,DSR)。
其中,TxD、RxD、SG与前面信号的含义相同,RTS为请求发送,CTS为准许发送,DSR为数据装置准备好,DTR为数据终端准备好。
在本地连接的微机系统中,RTS、CTS、DTR、DSR用作硬件联络控制信号。
目前使用的串口连接线有DB9和DB25两种连接器,用户可以国家使用的具体机器选择相应的连接器。
一个串口通讯类在/network/serialport.shtml。
PC机的RS-232接口的电平标准是-12V标示“1”,和+12V表示“0”,有些单片机的信号电平时TTL 型,即大于2.4v表示“1”,小于0.5v表示“0”,因此采用RS-232总线进行异步通信是,发送端和接受端要有一个电平转换接口。
串口通讯方法的三种实现串口是计算机上一种非常通用的设备通信协议。
大多数计算机包含两个基于RS232的串口。
串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS一232口。
同时,串口通信协议也可以用于获取远程采集设备的数据。
串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。
串口通信方便易行,应用广泛。
在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
MFC串口通信编程详解
DWORD ReadIntervalTimeout;//读间隔超时 DWORD ReadTotalTimeoutMultiplier;//读时间系数 DWORD ReadTotalTimeoutConstant;//读时间常量 DWORD WriteTotalTimeoutMultiplier;//写时间系数 DWORD WriteTotalTimeoutConstant;//写时间常量 } COMMTIMEOUTS,*LPCOMMTIMEOUTS; COMMTIMEOUTS 结构的成员都以毫秒为单位.总超时的计算公式是: 总超时=时间系数×要求读/写的字符数+时间常量 例如要读入 10 个字符,那么读操作的总超时的计算公式为: 读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant 可以看出:间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置 各种超时. 如果所有写超时参数均为 0,那么就不使用写超时.如果 ReadIntervalTimeout 为 0,那么就不使用读间隔超时.如果 ReadTotalTimeoutMultiplier 和 ReadTotalTimeoutConstant 都为 0,则不使用读总超时.如果读间隔超时被设置成 MAXDWORD 并且读时间系数和读时间常量都为 0,那么在读一次输入缓冲区的内容后 读操作就立即返回,而不管是否读入了要求的字符. 在用重叠方式读写串口时,虽然 ReadFile 和 WriteFile 在完成操作以前就可能返 回,但超时仍然是起作用的.在这种情况下,超时规定的是操作的完成时间,而不是 ReadFile 和 WriteFile 的返回时间.
串口通信原理及操作流程
串口通信原理及操作流程串口通信是计算机与外部设备之间进行数据传输的一种通信方式。
串口通信有很多应用领域,比如打印机、调制解调器、传感器、嵌入式系统等等。
本文将介绍串口通信的原理及操作流程。
一、串口通信原理串口通信是通过串行传输来传送数据的。
串行传输是指将数据位按序列发送,每个数据位连续的传输。
串口通信涉及两个主要部分,即发送端和接收端。
发送端将原始数据转换为串行数据流进行发送,接收端则接受数据流并将其转换为原始数据。
串口通信需要两根线缆来进行传输,分别是数据线和控制线。
数据线用于传输数据位,而控制线用于传输控制信号。
串口通信使用的数据传输格式通常是异步串行传输。
异步传输是指数据位之间没有时间关系,每个数据位之间通过起始位和停止位来进行区分。
起始位用于表示数据传输的开始,而停止位则表示数据传输的结束。
此外,数据位的长度和奇偶校验位的设置也是串口通信中需要注意的参数。
二、串口通信操作流程串口通信的操作流程可以分为以下几步:1.打开串口用户需要先打开串口才能进行通信。
打开串口的过程可能需要设置串口的参数,比如波特率、数据位长度、奇偶校验位等等。
2.发送数据一旦串口打开,用户可以通过向串口写入数据来进行发送。
数据可以是任何形式的,比如字符串、二进制数据等等。
3.接收数据接收数据的过程与发送数据的过程相反,用户可以从串口读取数据。
读取到的数据可以进一步处理或者显示。
4.关闭串口通信结束后,用户需要关闭串口以释放相关资源。
以上是串口通信的基本操作流程。
在实际应用中,可能还需要进行更多的操作,比如设置超时时间、错误处理等等。
三、串口通信的注意事项在进行串口通信时1.波特率的设置需要与外部设备保持一致,否则可能无法正常通信。
2.数据位长度、奇偶校验位以及停止位的设置也需要与外部设备保持一致。
3.在进行数据传输之前,最好先进行握手协议以确保通信的可靠性。
4.在进行数据传输时,需要保证发送端和接收端的数据格式是一致的,否则可能会引发数据解析错误。
qt串口通信的异步问题
qt串口通信的异步问题
Qt串口通信中的异步问题是指在串口通信过程中,数据的发送
和接收是异步进行的,也就是说发送数据的速度和接收数据的速度
可能不一致,可能会出现数据丢失或者混乱的情况。
为了解决这个
问题,可以采用以下几种方法:
1. 使用信号与槽机制,在Qt中,可以利用信号与槽机制来实
现串口通信的异步处理。
当串口接收到数据时,可以发射一个信号,然后在槽函数中处理接收到的数据。
这样可以保证数据的接收和处
理是异步进行的,不会影响程序的运行。
2. 使用Qt的事件循环,Qt提供了事件循环机制,可以在事件
循环中处理串口通信的数据。
通过在事件循环中添加串口数据的处
理逻辑,可以保证数据的接收和处理是异步进行的,不会阻塞程序
的运行。
3. 使用多线程,另一种处理串口通信异步问题的方法是使用多
线程。
可以将串口通信的接收和处理放在单独的线程中进行,这样
可以保证串口通信不会阻塞主线程的运行,从而实现异步处理。
4. 使用缓冲区,在串口通信过程中,可以使用缓冲区来暂存接收到的数据,然后再进行处理。
这样可以解决数据发送和接收速度不一致时可能出现的问题,确保数据的完整性和准确性。
总的来说,在Qt串口通信中处理异步问题,可以结合使用信号与槽机制、事件循环、多线程和缓冲区等方法,以确保数据的发送和接收是异步进行的,从而提高程序的稳定性和可靠性。
同步、异步串口
数据流的发送,在物理上,体现为一个高低电平序列。发送方产生电平序列,接收方进行解码。双方需要约定一个规矩,使得数据能够正确的发送与接收。其中,关键的一条,是接收方如何辨别每个口
对于同步串口,定位信息则通过专门的时钟信号线来实现。发送、接收方根据时钟,将数据流转换为电平信号。
异步串口(ASYNC)主要是应用于Modem或Modem池的连接,用于实现远程计算机通过公用电话网拨入网络。这种异步端口相对于上面介绍的同步端口来说在速率上要求宽松许多,因为它并不要求网络的两端保持实时同步,只要求能连续即可。所以我们在上网时所看到的并不一定就是网站上实时的内容,但这并不重要,因为毕竟这种延时是非常小的,重要的是在浏览网页时能够保持网页正常的下载。如图所示为异步串口。
有两种异步串口,一种是将同/异步串口设置为工作在异步方式,接口名称为Serial;另外一种是专用异步串口,接口名称为Async。
异步串口可以设为专线方式和拨号方式。在应用中更常用的是拨号方式,异步串口外接Modem或ISDN TA(Terminal Adapter,终端适配器)时可以作为拨号接口使用,封装链路层协议SLIP或PPP,支持IP和IPX等网络协议。
支持IP和IPX网络层协议。
可以通过执行show interfaces serial命令查看同步串口的当前外接电缆类型以及工作方式(DTE/DCE)等信息。
异步串口
对于异步串口,定位信息包含在电平序列中。双方先约定好数据帧的格式,例如波特率、数据位、停止位、奇偶校验等。线路空闲时,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后按照约定的格式,接收这一帧的数据。接收完成后,继续检测下一个起始位。也就是说,异步串口的同步,是以帧为单位的。对帧内的各个数据位,则通过约定的波特率来识别。
windows串口
在工业控制中,工控机(一般都基于W indows平台)经常需要与智能仪表通过串口进行通信。
串口通信方便易行,应用广泛。
一般情况下,工控机和各智能仪表通过RS485总线进行通信。
RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点。
每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。
在W in32下,可以使用两种编程方式实现串口通信,其一是使用Activ eX控件,这种方法程序简单,但欠灵活。
其二是调用W indows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
本文我们只介绍API串口通信部分。
串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。
同步操作时,AP I函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。
无论那种操作方式,一般都通过四个步骤来完成:(1)打开串口(2)配置串口(3)读写串口(4)关闭串口(1)打开串口W in32系统把文件的概念进行了扩展。
无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateF ile来打开或创建的。
该函数的原型为:HANDLE CreateF ile( LPCTSTR lpF ileName,DW ORD dwDesired Access,DW ORD dwShareMode,LPSECURITY_ATTR IBUTES lpSecur ity Attributes,DW ORD dwCreationDistr ibution,DW ORD dwFlags AndAttributes,HANDLE hTemp lateF ile);∙lpF ileName:将要打开的串口逻辑名,如“COM1”;∙dwDesir edAccess:指定串口访问的类型,可以是读取、写入或二者并列;∙dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;∙lpSecur ity Attributes:引用安全性属性结构,缺省值为NULL;∙dwCreationDistribut ion:创建标志,对串口操作该参数必须置为OPEN_EXIST ING;∙dwF lagsAndAttr ibutes:属性描述,用于指定该串口是否进行异步操作,该值为F ILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;hTemplateF ile:对串口而言该参数必须置为NULL;同步I/O方式打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom=CreateFile("COM1",//COM1口GENERIC_READ|GENER IC_W RITE, //允许读和写0, //独占方式NULL,OPEN_EXIST ING, //打开而不是创建0, //同步方式NULL);if(hCom==(HANDLE)-1){Afx Mess ageBox("打开COM失败!");return FALSE;}return TRUE;重叠I/O打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom =CreateFile("COM1", //COM1口GENERIC_READ|GENER IC_W RITE, //允许读和写0, //独占方式NULL,OPEN_EXIST ING, //打开而不是创建F ILE_ATTR IBUTE_NORMAL|F ILE_FLAG_OVERLAPPED, //重叠方式NULL);if(hCom ==INVAL ID_HANDLE_VALUE){Afx Mess ageBox("打开COM失败!");return FALSE;}return TRUE;(2)、配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。
异步串口通信原理
异步串口通信原理一、什么是异步串口通信?异步串口通信是指数据传输时,发送方和接收方的时钟信号不同步,数据的传输是不同步的。
在异步串口通信中,数据的传输是以字节为单位进行的,每个字节的传输都包含了一个起始位、数据位、奇偶校验位和一个或多个停止位。
二、异步串口通信的原理异步串口通信的原理是利用串行通信的方式,将数据一位一位地传输,每个字节都包含了一定的控制信息,以保证数据的正确性。
异步串口通信中,数据传输的速率是通过波特率来确定的。
波特率是指每秒钟传输的比特数,常用的波特率有9600、19200、38400等。
在异步串口通信中,发送方和接收方需要事先约定好数据传输的格式,包括数据位、奇偶校验位和停止位等。
数据位表示每个字节中实际的数据位数,通常为8位。
奇偶校验位用于检测数据传输过程中的错误,通常有奇校验和偶校验两种方式。
停止位用于表示数据传输的结束,通常为1个或2个停止位。
三、异步串口通信的应用异步串口通信广泛应用于各种设备之间的数据传输中,例如计算机与打印机、计算机与单片机、计算机与PLC等。
在计算机与单片机之间的数据传输中,常常使用USB转串口的方式进行通信。
由于USB接口具有更高的传输速率和更稳定的传输性能,因此USB转串口的方式已经成为了现代计算机与单片机之间的主要通信方式。
四、异步串口通信的优缺点异步串口通信的优点是传输速率较慢,但传输距离较远,且传输稳定可靠。
由于异步串口通信是以字节为单位进行传输的,因此可以保证数据的完整性和正确性。
同时,异步串口通信的传输距离可以达到几十米甚至上百米,因此非常适合用于远距离数据传输。
异步串口通信的缺点是传输速率较慢,无法满足大量数据的传输需求。
同时,由于异步串口通信是以字节为单位进行传输的,因此在传输大量数据时,会产生较大的传输延迟,影响传输效率。
五、总结异步串口通信是一种基于串行通信的数据传输方式,具有传输距离远、传输稳定可靠等优点。
在计算机与单片机、计算机与PLC等设备之间的数据传输中,异步串口通信已经成为了一种常用的通信方式。
串口通讯—异步通信方式
1/2
2015/10/23
串口通讯—异步通信方式
图3 (1)开始通信时,信号线为空闲(逻辑1),当检测到由1到0的跳变时,开始对“接收时钟”计数。 (2)当计到8个时钟时,对输入信号进行检测,若仍为低电平,则确认这是“起始位”B,而不是干扰信 号。 (3)接收端检测到起始位后,隔16个接收时钟,对输入信号检测一次,把对应的值作为D0位数据。若为逻 辑1, 作为数据位1;若为逻辑0,作为数据位0。 (4)再隔16个接收时钟,对输入信号检测一次,把对应的值作为D1位数据。….,直到全部数据位都输入。 (5)检测校验位P(如果有的话)。 (6)接收到规定的数据位个数和校验位后,通信接口电路希望收到停止位S(逻辑1),若此时未收到逻辑1, 说明出现了错误,在状态寄存器中置“帧错误”标志。若没有错误,对全部数据位进行奇偶校验,无校验错 时,把数据位从移位寄存器中送数据输入寄存器。若校验错,在状态寄存器中置奇偶错标志。 (7)本幀信息全部接收完,把线路上出现的高电平作为空闲位。 (8)当信号再次变为低时,开始进入下一幀的检测。 3、异步通信的发送过程
逻辑0
逻辑1
正逻辑 低电平
高电平
负逻辑 高电平
低电平
异步通信的信息格式如下边的表所示
起始 位
逻辑0
1位
数 据 逻辑0 位 或1
5位、6位、7位、8位
校 验 逻辑0 位 或1
1位或无
停止
逻辑
1位,1.5位或2位
位
空闲
逻辑1 任意数量
位
注:表中位数的本质含义是信号出现的时间,故可有分数位,如1.5。 例:传送8位数据45H(0100,0101B),奇校验,1个停止位,则信号线上的波形象图2所示那样:异 步通信的速率:若9600bps,每字符8位,1起始,1停止,无奇偶,则实际每字符传送10位,则960字符/秒。
【设置】串口的读写和缓冲区数据的显示
【关键字】设置第5章串口的读写和缓冲区数据的显示利用WIN32API读写串口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直接操作完成后才返回。
这意味着同步执行时线程会被阻塞,从而导致效率降低,在重叠执行时,即使操作未完成,调用的函数也会立即返回。
费时的I/O操作在后台进行这样线程就可以做其他工作。
例如.线程可以在不同的句柄上执行I/O操作,甚至可以在同一句柄上同时进行读写操作。
“重叠”一词含义就在于此。
5.1 读串口操作程序可以使用WIN32API ReadFile()函数从串口读取数据。
ReadFile()函数声明如下:BOOL ReadFile(HANDLE hFile, //指向标记的句柄LPVOID lpBuffer, //指向一个缓冲区DWORD nNumberOfBytesToRead, //读取的字节数LPDWORD lpNumberOfBytesRead, //指向调用该函数读出的字节数LPOVERLAPPED lpOverlapped //一个OVERLAPPED的结构)其中主要参数介绍如下:hFile:指向标记的句柄。
对串口来说,就是由CreateFile()函数返回的句柄。
该句柄需拥有GENERIC—READ的权限。
lpBuffer:指向一个缓冲区、该缓冲区主要用于存放从串口设备中读取的数据。
nNumberOfBytesToRead:指定要从串口设备读取的字节数lpNumberOfBytesRead:指向调用该函数读出的字节数。
ReadFile()在读操作前,首先将其设置为0。
Windows NT/2000中当lpOverlapped没有设置时,lpNumberOfBytesRead 必需设置。
当lpOverlapped设置时,lpNumberOfBytesRead可以不设置。
这是可以调用GetOverlappedResult()函数获取实际的读取数值。
Windows9x 中这个参数一定要设置.lpOverlapped :是一个0VERLAPPED的结构,如果hFile以FILE_FLAG_OVERLAPPED方式常见, 则需要此结构; 否则, 不需要此结构。
异步串行UART协议详解中文版
异步串行UART协议详解中文版UART代表通用异步接收发送器,是一种将数据以串行bit的形式在计算机和外设之间传输的技术。
异步串行通信意味着数据位不需要在时钟信号的同步下传输,而是以不同的速率进行传输。
这种通信方式常见于串口通信和单线通信。
在异步串行UART协议中,数据传输以帧为单位进行。
每个帧由起始位、数据位、校验位和停止位组成。
起始位用于指示一帧的开始,数据位用于存储要传输的数据,校验位用于确保数据的正确性,停止位用于指示一帧的结束。
串口通信通常使用RS-232电平标准,其中逻辑1由负电平表示,逻辑0由正电平表示。
数据位的长度可以是5、6、7或8位,校验位可以是奇校验、偶校验或不使用校验,停止位通常是一个或两个位。
在异步串行UART协议中,计算机和外设之间的数据传输是通过发送和接收操作进行的。
发送操作用于将数据从计算机发送到外设,接收操作用于从外设接收数据并传输到计算机。
在发送操作中,计算机将待发送的数据写入发送缓冲区。
UART控制器将逐位地从发送缓冲区读取数据,并将其转换为适当的电平,然后在传输线上发送。
在接收操作中,UART控制器从传输线上读取电平,并将其转换为相应的位。
一旦接收到足够的位数,UART控制器将数据存储在接收缓冲区中,然后通知计算机该数据已准备好。
除了数据传输外,异步串行UART协议还定义了其他控制信号,如RTS(请求发送)、CTS(清除发送)、DSR(数据设备准备好)、DTR(数据终端准备就绪)、RI(振铃指示)和CD(载波检测)等。
这些信号用于指示通信的状态和控制通信流程。
总结起来,异步串行UART协议是一种用于计算机和外设之间进行数据传输的通信协议。
它定义了数据传输的格式、速率和控制信号,通过发送和接收操作实现数据的可靠传输。
该协议在计算机硬件和软件之间建立了一种可靠的通信接口,被广泛应用于串口通信和单线通信等领域。
异步串口通信VC++
异步串口通信VC++//MyComm.h 多机控制异步串口通信class CMyComm{public:CMyComm();virtual ~CMyComm();void PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue);// size of input buffer, size of output bufferBOOL Open(int nPort, int nBaud);// 默认无校验,每个字节发送11 个bit ,异步方式。
// 若设置校验后,校验错则字节被替换为0x7EBOOL SetupQueue(DWORD dwInQueue, DWORD dwOutQueue);// size of input buffer, size of output bufferBOOL ResetParity(char Parity);//parity = 'N', 'O', 'E', 'M', 'S'不区分大小写// 分别表示no, odd, even, mark, space// 在Open() 前设置无效。
BOOL SendData(LPCVOID lpBuf, DWORD dwToWrite);DWORD ReadData(LPVOID lpBuf, DWORD dwToRead);void Close();protected:HANDLE m_hCom;BOOL m_bOpened;OVERLAPPED m_osReader;OVERLAPPED m_osWriter;DWORD m_dwInBuf;DWORD m_dwOutBuf;};////////////////////////////////////////////////////////////MyComm.cpp#include "stdafx.h"#include "MyComm.h"///////////////////////////////////////////CMyComm::CMyComm(){m_bOpe ned = FALSE;m_dwl nBuf = 512;m_dwOutBuf = 512;m_hCom = NULL;void CMyComm::PreOpe nSetupQueue(DWORD dwI nQueue, DWORD dwOutQueue) {m_dw In Buf = dwln Queue;m_dwOutBuf = dwOutQueue;}BOOL CMyComm::Ope n(int nPort, i nt nBaud){ASSERT (n Port > 0 || n Port < 5 || nBaud >= 110 || n Baud <= 128000);if( m_bOpe ned ) return TRUE;char szPort[15];char lpDef[15];DCB dcb = {0};dcb.DCBle ngth = sizeof(dcb);wspri ntf(szPort, "COM%d", nPort);wsprintf(lpDef, "%d,n,8,1", nBaud);m_hCom = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);if( m_hCom == INVALID_HANDLE_VALUE ) return FALSE;FillMemory(&m _osReader, sizeof(OVERLAPPED), 0);FillMemory(&m _osWriter, sizeof(OVERLAPPED), 0);m_osReader.hEve nt = CreateEve nt(NULL, TRUE, FALSE, NULL);m_osWriter.hEve nt = CreateEve nt(NULL, TRUE, FALSE, NULL);int byteUsedTime = 14400 / nBaud +1;COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20}; dcb.fParity = TRUE;dcb.fErrorChar = TRUE;dcb.ErrorChar = '~';if( m_osReader.hEve nt == NULL || m_osWriter.hEve nt == NULL|| !SetCommTimeouts(m_hCom, & timeouts)|| !BuildCommDCB(lpDef, &deb) || !SetupComm(m_hCom, m_dwlnBuf, m_dwOutBuf)) { if( m_osReader.hEve nt != NULL )CloseHa ndle( m_osReader.hEve nt );if( m_osWriter.hEvent != NULL )CloseHa ndle( m_osWriter.hEve nt );CloseHa ndle( m_hCom );return FALSE;m_bOpe ned = TRUE;retur n m_bOpe ned;}BOOL CMyComm::SetupQueue(DWORD dwln Queue, DWORD dwOutQueue) {if (m_hCom == NULL) retur n FALSE;m_dw In Buf = dwln Queue;m_dwOutBuf = dwOutQueue;return SetupComm(m_hCom, m_dw In Buf, m_dwOutBuf);}BOOL CMyComm::ResetParity(ehar Parity){if (m_hCom == NULL) retur n FALSE;DCB deb;deb.DCBle ngth = sizeof( DCB );if (!GetCommState(m_hCom, & deb)) retur n FALSE;BYTE eParity;Parity = tolower(Parity);switeh (Parity) {ease 'o':eParity = 1;break;ease 'e':eParity = 2;break;ease 'm':eParity = 3;break;ease 's':eParity = 4;break;default:eParity = 0;break;}deb.Parity = eParity;return SetCommState(m_hCom, &dcb);}精选文库BOOL CMyComm::Se ndData(LPCVOID IpBuf, DWORD dwToWrite){TRACE("SSSSSSSSSSSSS 00\n");if( !m_bOpened || m_hCom == NULL ) return FALSE;DWORD dwWritte n;if (WriteFile(m_hCom, lpBuf, dwToWrite, & dwWritte n, & m_osWriter)) retur n TRUE;if (GetLastError() != ERROR_IO_PENDING) retur n FALSE;GetOverlappedResult(m_hCom, &m _osWriter, &dwWritte n, TRUE);TRACE("SSSSSSSSSSSSS 11\n");return (dwToWrite == dwWritte n);}DWORD CMyComm::ReadData(LPVOID lpBuf, DWORD dwToRead){TRACE("RRRRRRRRRRRR 00\n");if( !m_bOpened || m_hCom == NULL ) return 0;DWORD dwRead;if (ReadFile(m_hCom, lpBuf, dwToRead, &dwRead, & m_osReader) ) return dwRead;if (GetLastError() != ERROR_IO_PENDING) return 0;if (WaitForSi ngleObject(m_osReader.hEve nt, INFINITE) != WAIT_OBJECT_0 )return 0;if (!GetOverlappedResult(m_hCom, &m _osReader, &dwRead, FALSE))return 0;TRACE("RRRRRRRRRRRR 11\ n");retur n dwRead;}void CMyComm::Close(){if (m_osReader.hEve nt != NULL) CloseHa ndle( m_osReader.hEve nt );if (m_osWriter.hEve nt != NULL) CloseHa ndle( m_osWriter.hEve nt );if (m_hCom != NULL) CloseHa ndle( m_hCom );m_bOpe ned = FALSE;}CMyComm::~CMyComm(){Close();}精选文库// mai n.cppchar Buf[40];int nArray[3];CMyCo mn myCom;UINT Sen dDataProc(LPVOID pParam);void On CommSe ndReceive(){myCom.PreOpe nSetupQueue(12, 12);if (!myCom.Open(2, 4800)) return;//如果想改变校验位,在此位置,如:myCom.ResetParity('m');FillMemory(Buf, 40, 0);n Array[0] = 0;nArray[1] = 17;nArray[2] = 88888;AfxBeginThread(SendDataProc, (LPVOID)(12));TRACE("EEEEEEEE\n");int n Read = myCom.ReadData(Buf, 12);in t* nA = (int*) Buf;TRACE("AAAAAAAAAAAAAA %d, %d %d %d\n", nRead, n A[0], nA[1], nA[1]); }UINT Sen dDataProc(LPVOID pParam){return myCom.Se ndData((LPVOID)nArray, (DWORD) pParam);}。
串行通信与重叠(异步)IO
串行通信与重叠(异步)IOWin 32系统把文件的概念进行了扩展。
无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。
该函数的声明为:HANDLE CreateFile(LPCTSTR lpFileName,// 文件名DWORD dwDesiredAccess,// 访问模式DWORD dwShareMode,// 共享模式LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 通常为NULLDWORD dwCreationDistribution,// 创建方式DWORD dwFlagsAndAttributes,// 文件属性和标志HANDLE hTemplateFile// 临时文件的句柄,通常为NULL);如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INV ALID_HANDLE_V ALUE。
在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。
这需要通过一个DCB结构来进行。
DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。
在查询或配置置串行口的属性时,都要用DCB 结构来作为缓冲区。
调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。
一般在用CreateFile打开串行口后,可以调用GetCommState函数来获取串行口的初始配置。
要修改串行口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串行口。
除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。
Windows用I/O缓冲区来暂存串行口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。
调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。
串口通信知识点详解
串⼝通信知识点详解串⼝通信的基本概念:1.在计算机上进⾏数据的通信有两种⽅式。
串⾏⽅式和并⾏⽅式。
也就是串⼝通信和并⾏通信。
即串⼝通信是计算机传输数据的⼀种通信⽅式。
2.并⾏通信以字节为但是进⾏传输数据,相⽐于串⼝通信,他的速度快,传输距离近。
串⼝通信以⽐特位传输数据,相⽐于并⾏通信,他的传输速度慢,但是传输距离远。
并且串⼝通信是异步通信,因此,端⼝可以在⼀根线上发送数据的同时在另⼀根线上接收数据3.串⼝通信最重要的参数是波特率、数据位、停⽌位和奇偶校验。
对于两个进⾏通信的端⼝,这些参数必须匹配。
(1)波特率:传输速率。
如每秒钟传送240个字符,⽽每个字符格式包含10位(1个起始位,1个停⽌位,8个数据位),这时的波特率为240Bd,⽐特率为10位*240个/秒=2400bps。
(2)数据位:数据包中发送端想要发送的数据(3)停⽌位:⽤于表⽰单个包的最后⼀位,结束标志以及校正时钟同步(4)奇偶校验:检错⽅式。
⼀共有四种检错⽅式:偶、奇、⾼和低。
4.串⼝通信的应⽤场景:串⼝通信是指外设和计算机间,通过数据线按位进⾏传输数据的⼀种通讯⽅式。
这种通信⽅式使⽤的数据线少,在远距离通信中可以节约通信成本,但其传输速度⽐并⾏传输低。
⼤多数计算机(不包括笔记本)都包含两个RS-232串⼝。
串⼝通信也是仪表仪器设备常⽤的通信协议。
Windows下串⼝通信:1.在windows下,串⼝是作为⽂件进⾏处理。
2.串⼝通信分为四⼤步骤:打开串⼝,关闭串⼝,配置串⼝,读写串⼝(1)打开串⼝:使⽤CreateFile函数:HANDLE WINAPI CreateFile(_In_ LPCTSTR lpFileName,//要打开或创建的⽂件名_In_ DWORD dwDesiredAccess,//访问类型_In_ DWORD dwShareMode,//共享⽅式_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,//安全属性_In_ DWORD dwCreationDisposition,//指定要打开的⽂件已存在或不存在的动作_In_ DWORD dwFlagsAndAttributes,//⽂件属性和标志_In_opt_ HANDLE hTemplateFile//⼀个指向模板⽂件的句柄);参数说明:1).lpFileName:要打开或创建的⽂件名2).dwDesiredAccess:访问类型。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
异步重叠操作之串口
在工控行业,目前总线型通信依然占据半壁江山。
常用的如485,CAN等。
而面对小型系统时,尤其监控区域遍布在两公里范围内时,通过485-232或者CAN-232转换模块,使用上位机的串口与下属硬件通信组成系统便成了相对节约的一种设计方案。
本文的重点在于讲解异步重叠操作串口的思想以及过程。
所有的IO设备的操作都遵循:创建、读写、关闭三个步骤。
第一步:设计类的成员,其中成员此处不详细讲解,之后方法中用到时再谈
View Code
第二步:创建串口通道,在WINDOWS下,一切都表现得那么像文件操作
m_hPort = CreateFile((LPCWSTR)Device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
其中CreateFile为API函数,其细节如下:
// 作用: CreateFile函数可用来打开或创建文件和端口,它返回该设备的句柄
// 原型:
// HANDLE CreateFile(
// LPCTSTR lpFileName, // 指向文件名的指针
// DWORD dwDesiredAccess, // 访问模式
(GENERIC_WRITE/GENERIC_READ)。
0表示仅允许获得与一个设备有关的信息
// DWORD dwShareMode, // 共享模式
(FILE_SHARE_READ/FILE_SHARE_WRITE)。
0表述独占
// LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向安全属性的指
针
// DWORD dwCreationDisposition, // 创建属
性 CREATE_NEW 创建如果已经存在则冲突
// CREATE_ALWAYS 总是创建,存在则改写
// OPEN_EXISTING 打开现有,由设备提出要求
// OPEN_ALWAYS 打开,不存在则创建
// TRUNCATE_EXISTING 将现有文件缩短为0长度
// DWORD dwFlagsAndAttributes, // 文件属
性 FILE_ATTRIBUTE_ARCHIVE 标记归档属性
// FILE_ATTRIBUTE_COMPRES SED 将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
// FILE_ATTRIBUTE_NORMA L 默认属性
// FILE_ATTRIBUTE_HIDDE N 隐藏文件或目录
// FILE_ATTRIBUTE_READO NLY 文件为只读
// FILE_ATTRIBUTE_SYSTE M 文件为系统文件
// FILE_FLAG_WRITE_THRO UGH 操作系统不得推迟对文件的写操作
// FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作
// FILE_FLAG_NO_BUFFERIN G 禁止对文件进行缓冲处理。
文件只能写入磁盘卷的扇区块
// FILE_FLAG_RANDOM_AC CESS 针对随机访问对文件缓冲进行优化
// FILE_FLAG_SEQUENTIAL_ SCAN 针对连续访问对文件缓冲进行优化
// FILE_FLAG_DELETE_ON_ CLOSE 关闭了上一次打开的句柄后,将文件删除
// HANDLE hTemplateFile // 用于复制文件句柄,文件模板。
如果不为零,则新文件将从这个文件中复制扩展属性
// );
// 返回:
// HANDLE 句柄 INVALID_HANDLE_VALUE 表示出错
此处因为使用异步重叠,所以dwFlagsAndAttributes赋值为
FILE_FLAG_OVERLAPPED。
其中Device为设备名称,串口的话直接就是串口号
CHAR Device[80];
sprintf(Device, "COM%d", Port);
第三步:设置串口相关参数:
GetCommState(m_hPort, &dcb); // 读取当前端口的DCB设置
dcb.BaudRate = CBR_9600;
dcb.ByteSize = SERIALPORT_DATABITS_EIGHT; // 库中的选择结
果是5-8,表示5-8位长
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT; // 该参数如果开放,则设置不成功
SetCommState(m_hPort, &dcb); // 设置当前端口的DCB设置
//typedef struct _COMMTIMEOUTS {
// DWORD ReadIntervalTimeout; // 读间隔超时
// DWORD ReadTotalTimeoutMultiplier; // 读时间系数
// DWORD ReadTotalTimeoutConstant; // 读时间常量
// DWORD WriteTotalTimeoutMultiplier; // 写时间系数
// DWORD WriteTotalTimeoutConstant; // 写时间常量
// } COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS comTimeouts;
GetCommTimeouts(m_hPort, &comTimeouts);
comTimeouts.ReadIntervalTimeout = MAXDWORD;
comTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD; comTimeouts.ReadTotalTimeoutConstant = SERIALPORT_READ_TIMEOUT; comTimeouts.WriteTotalTimeoutMultiplier = MAXDWORD;
comTimeouts.WriteTotalTimeoutConstant = SERIALPORT_WRITE_TIMEOUT;
// 指定一组事件监控通信设备
// 原
型 BOOL WINAPI SetCommMask(__in HANDLE hFile, __in DWORD dwEvtMas k);
// 参数:
// __in HANDLE hFile 通信设备句柄
// __in DWORD dwEvtMask 可以触发的事件
// EV_BREAK 输入中断
// EV_CTS CTS清除发送信号改变。