实现异步串口
- 格式:docx
- 大小:31.67 KB
- 文档页数:16
嵌入式编程中的异步串口通信第一章前言嵌入式编程是指在微控制器、单片机、嵌入式处理器等嵌入式系统中开发应用程序的一种软件开发方式。
在嵌入式系统中,串口通信是一种非常常见的通信方式。
而异步串口通信则是一种常用的串口通信方式,并且其在嵌入式系统中应用非常广泛,因此本文将就嵌入式编程中的异步串口通信进行详细的探讨。
第二章异步串口通信的基础知识异步串口通信是指每个字节之间没有固定的时间间隔,而是通过起始位、数据位、校验位、停止位四个元素来标识一个数据帧的开端和结尾,并且每个数据帧之间都是独立的。
异步串口通信相较同步串口通信而言,这种通信方式的实现成本较低,因此应用广泛。
异步串口通信这这四个元素的意义:1. 起始位:表示数据帧的开始,通常为逻辑低电平;2. 数据位:表示每一个字符的长度,一般可以是5、6、7、8位;3. 校验位:用于检测数据传输过程中是否发生错误;4. 停止位:表示数据帧的结束,通常为逻辑高电平。
需要注意的是,异步串口通信不能在两台计算机之间进行通信,因为两台计算机的时钟不同,会产生较多的误差,导致信号解析不准确。
第三章异步串口通信的实现方法在嵌入式编程中要实现异步串口通信,通常需要使用到中断、轮询两种方式,本文将就这两种方式进行详细的介绍。
3.1 中断方式中断方式是指当接收到一个字符之后,CPU会暂停当前正在运行的程序,转而执行中断服务程序。
中断服务程序就是在接收到字符之后,在中断中处理接收到字符的操作。
使用中断方式实现异步串口通信可以大大提升程序的效率,而且还可以减少程序的耦合度。
使用中断方式实现异步串口通信需要调用中断服务函数,并将其注册到对应的中断向量上,以实现中断函数的执行。
3.2 轮询方式轮询方式是指程序通过不断地查询串口缓冲区是否有数据,来实现数据的接收和发送。
这种方式比较容易实现,但是由于需要不断地查询缓冲区,因此会占用较大的CPU时间。
在实时性要求较高的系统中,轮询方式并不适用。
使用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。
UART的异步串口通信VHDL实现UART 的异步串口通信协议的VHDL 语言实现异步串行通信的采用的波特率为9600b/s,外配晶体振荡器的频率为3.6864MHZ ,故采用分频电路package width isconstant N:integer:=8;end width;use work.width.all;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity fredivn isGENERIC (N:integer:=6);port(clkin: in std_logic;clkout: out std_logic);end fredivn;architecture behav of fredivn issignal count : integer;beginprocess(clkin)beginif (clkin'event and clkin=1)thenif(count<n-1)then< p="">count<=count+1;else count<=0;end if;if (count<="" p="">clkout<='1';else clkout<='0';end if;end if;end process;end behav;异步接收模块 RXD 的端口clk 为输入时钟,rx 为串行数据接收,sig1为接收中断标志,q 为并行数据输出程序流程如下:sig1是接收中断标志位,当是低电平时,说明接收过程并未启动,于是检测电平,当rx 电平为低时,sig2开始计数,若连续8次采样rx 都是低电平,则说明是起始位,启动接收过程,每隔16个接收时钟接收1位数据直至11位接收完毕,并行输出口是一个串并转换。
1、基本知识:1、-- 异步串行通信数据帧格式如下:起始位为‘0’,停止位为1-2位‘1’;奇偶校验位为可选,数据为5-8位可选。
2、波特率指的是每秒钟发送的字符(一位数据位)的个数,1B=1b/s。
如波特率为9600B,那么发送一个数据位所需要的时间为1/9600 s;发送/接收时钟的频率与波特率的关系为:发送/接收时钟的频率= n x发送/接收波特率。
其中n = 1 、16、64;我们在这里取n = 16 ;即对每一位数据都采样16次。
2、功能实现-- 本模块的功能是验证实现和PC机进行基本的串口通信的功能。
需要在PC机上安装一个串口调试工具来验证程序的功能。
程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控制器,10个bit是1位起始位,8个数据位,1个结束位。
程序分为三个模块:时钟分频模块,接收数据模块,发送数据模块。
具体程序代码为:library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned values--use IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity uart isport( CLK50M : in std_logic;reset : in std_logic;uart_tx : out std_logic;uart_rx : in std_logic);end uart;architecture Behavioral of uart issignal div_clk50M :std_logic; ----分频后的时钟信号s ignal rx_data : std_logic_vector(7 downto 0); --- 接收数据缓存s ignal tx_data : std_logic_vector(7 downto 0); ----发送数据缓存s ignal data_buf: std_logic_vector(7 downto 0); --- 接收数据存储t ype state_rx is (rx_idle,rx_start,rx_sample,rx_stop); ---接收状态机s ignal rx_state : state_rx := rx_idle;t ype state_tx is (tx_idle,tx_start,tx_send,tx_stop); --发送状态机s ignal tx_state : state_tx := tx_idle;s ignal send_enable : std_logic :='0';begin--- --------CLK_Div module---------------------Bauds = 9600B clk=50M division factor = 50M/(9600x16)=325---------------------------------------------CLK_DIV: process(CLK50M,reset)variable div_count : integer :=0; -----分频系数变量beginif(reset='1') then div_clk50M <='0'; div_count :=0;elsif(rising_edge(CLK50M)) thenif div_count>=325 then div_clk50M <= '0'; div_count :=0;elsif div_count>=162 thendiv_count := div_count + 1;div_clk50M <= '1';else div_count :=0; div_clk50M <= '0';end if;end if;end process CLK_DIV;-----------------------------------------------------------DATA Receive module------------DATA_R : process(div_clk50M,reset)variable rx_count : integer :=0; -- 实现每16个时钟采样一次的中间变量。
自动异步串口通信的实现 The Realization of Serial Communication in Automatic Test System姚文华,秦开宇,李志强(电子科技大学空天科学技术研究院,四川成都 610054)Yao Wen-hua, Qin Kai-yu, Li Zhi-qiang(Institute of Astronautics & Aeronautics, UESTC of China, Sichuan Chengdu 610054)摘要:为了实现自动测试系统软件中常采用的串口通信,采用Labview设计并实现了一个异步通信串口的程序。
该程序主要用VISA实现串口的配置,寻址,进而实现串口的打开、关闭、读和写的功能;在此基础上,该程序对串口读来的数据进行了一些处理,如按帧显示。
从而有一个简单的判断的过程,避免了一些错误的数据。
使得程序有一定的容错功能。
实验表明,该串口程序稳定性好、可重用、易组合、使用方便,具有较高的工程应用价值。
关键词:Labview;按帧显示;异步串口;VISA;CP-132中图分类号:TN915.09 文献标识码:A 文章编号:Abstract:The realization of the serial communication which often used in the software of the automatic test system is introduced.VISA is mainly used to configure, read, write and close the serial port. Based on this, some othrer processes, such as display by frame which is used to avoid some wrong and to make the program more robust are prompted. The serial programing is stable, reusable and easy to mix, easy to use, which is valuable to use in projectKey words:Labview; display by frame; serial port; VISA; CP-132CLC number: TN915.09 Document code: A Article ID:1引言计算机技术、测试系统总线技术、软件技术和人工智能技术的发展,使得自动测试系统从早期的功能单一、扩展和可移植性差、体系架构思想性落后向现代的开放式架构、标准化、模块化和智能化测试系统发展[1][6]-[10]。
嵌入式系统上的异步串口通信的实现
在嵌入式系统中,异步串口(UART)使用非常频繁,可以用于与各种外部系统(帧括PC)之间的通信。
在硬件上UART通过在每个字节的传输中插入开始位和停止位,保证接收端可以正确地找到字节的开始和结束,同时也可以通过插入奇偶校验位,让接收端检验收到的字节是否正确。
而且,由于有开始位和停止位的存在,使得字节之间可以插入任意的空闲位(与停止位同为高电平),而不影响下一个字节的正常传输。
因此,UART硬件保证了每个字节的正确传输,并可以有效检出字节传输的错误。
但并不保证一串字节的正确传输,这需要软件来完成。
从软件的角度来看,所有的通信都是一串字节(叫做数据帧)的连续传输。
软件需要采用适当的机制来保证接收端能够正确识别出一个完整的数据帧、能够检查接收到的数据帧是正确的、在传输发生错误时有合适的恢复机制。
为此就需要定义一个合适的数据帧格式。
数据帧的提取
为了识别出一个完整的数据帧,基本上有两个机制:一是在软件上规定字节之间的间隔最大值,一旦两个字节间的间隔超过某个阈值,就认为一个数据帧结束;另一种机制不对字节间的间隔作规定,而是用特殊的字节来定义数据报的开始和结束,当收到该特殊字节时,就认为一个数据帧的传输已完成。
采用第一种机制的,比如Modbus-RTU。
就是规定了同一个数据帧的字节间隔不能大于1.5个字节的传输时间,一旦大于该间隔,则认为前一个帧的传输已经结束,或者出错。
同时为了保证不同数据帧之间有足够的间隔,还规定了两个数据帧之间最少插入3.5个字节的空闲位。
下第二种机制需要选用一个特殊字节作为帧头帧尾(也可以给帧头帧尾选用不同的字节),比如。
qt串口通信的异步问题
Qt串口通信中的异步问题是指在串口通信过程中,数据的发送
和接收是异步进行的,也就是说发送数据的速度和接收数据的速度
可能不一致,可能会出现数据丢失或者混乱的情况。
为了解决这个
问题,可以采用以下几种方法:
1. 使用信号与槽机制,在Qt中,可以利用信号与槽机制来实
现串口通信的异步处理。
当串口接收到数据时,可以发射一个信号,然后在槽函数中处理接收到的数据。
这样可以保证数据的接收和处
理是异步进行的,不会影响程序的运行。
2. 使用Qt的事件循环,Qt提供了事件循环机制,可以在事件
循环中处理串口通信的数据。
通过在事件循环中添加串口数据的处
理逻辑,可以保证数据的接收和处理是异步进行的,不会阻塞程序
的运行。
3. 使用多线程,另一种处理串口通信异步问题的方法是使用多
线程。
可以将串口通信的接收和处理放在单独的线程中进行,这样
可以保证串口通信不会阻塞主线程的运行,从而实现异步处理。
4. 使用缓冲区,在串口通信过程中,可以使用缓冲区来暂存接收到的数据,然后再进行处理。
这样可以解决数据发送和接收速度不一致时可能出现的问题,确保数据的完整性和准确性。
总的来说,在Qt串口通信中处理异步问题,可以结合使用信号与槽机制、事件循环、多线程和缓冲区等方法,以确保数据的发送和接收是异步进行的,从而提高程序的稳定性和可靠性。
课程名称DSP原理与应用实验序号实验4实验项目异步串口通讯实验地点实验学时实验类型指导教师实验员专业班级学号姓名年月日二、实验原理与内容1、UART 简介TMS320DM6437 集成了UART 控制器,支持2 个UART 外设连接。
UART 支持基于工业标准的TL16C550 异步通信模块,支持FIFO 模式数据传输,最大支持16 字节数据的缓存,从而减轻接收和发送数据时CPU 程序的时钟消耗。
TMS320DM6437 集成的UART 控制器可以扩展2 个UART,其对应的信号线分为两组:其中只有UART0 支持modem 模式控制。
SEED-DEC6437 配置UART0 为RS485 模式,UART1 为RS232 模式。
2、UART 的寄存器说明TMS320DM6437 的UART 的寄存器如表示:3、波特率的设置UART 的位时钟是从固定的27MHz 的时钟获取的,支持最高128 kbps 的数据率。
UART的时钟产生原理如下图:UART 波特率产生原理图UART 包含一个可编程的波特率发生器,将输入时钟经过分频产生需要的位时钟,分频值可以在1-65535。
位时钟的频率是波特率的十六倍频,每一个接收发送的数据位占用16个位时钟,接收时,位采样也在第八个位时钟时采样。
分频器值的计算公式如下:分频数= 当前时钟输入(27MHz)/(16 ×期望的波特率)当输入时钟为27MHz 时,支持的波特率如下图所示三、实验软硬件环境SEED—DTK67实验箱,CCS软件,接口线UART 实验,包含文件1. main.c:实验主程序,包含了系统初始化,外扩接口初始化及配置。
2. linker.cmd:声明了系统的存储器配置与程序各段的连接关系。
3. DEC6437.gel:系统初始化程序。
四、实验过程(实验步骤、记录、数据、分析)1. 将DSP 仿真器与计算机连接好;2. 将DSP 仿真器的JTAG 插头与SEED-DEC6437 单元的J9 相连接;3. 打开SEED-DTK6437 的电源。
异步传输是一种典型的基于字节的输入输出,指数据按每次一个字节进行传输,其传输速度低。
同步传输是把数据字节组合起来一起发送,这种组合称之为帧,其传输速度比异步传输快,同步串口的传送速率高,异步串口实现简单,这是异步串口与同步串口间最主要的区别。
一,异步非阻塞串口通讯的优点读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。
这意味着在同步执行时线程会被阻塞,从而导致效率下降。
在重叠执行时,即使操作还未完成,调用的函数也会立即返回。
费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。
"重叠"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;其次,为了保护系统对串口的初始设置,调用 GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识VC串口通信技术网下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()功能:打开串口设备函数原型1.HANDLE CreateFile(2.LPCTSTR lpFileName, // 串口名称字符串;如: "COM1" 或 "COM2"3.DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE,4.DWORD dwShareMode, // 共享模式;"必须"为 0, 即不能共享5.LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL6.DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为 OPEN_EXISTING7.DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/O8.HANDLE hTemplateFile // 临时文件的句柄,通常为NULL9.);函数说明:如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
异步传输是一种典型的基于字节的输入输出,指数据按每次一个字节进行传输,其传输速度低。
同步传输是把数据字节组合起来一起发送,这种组合称之为帧,其传输速度比异步传输快,同步串口的传送速率高,异步串口实现简单,这是异步串口与同步串口间最主要的区别。
一,异步非阻塞串口通讯的优点读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。
这意味着在同步执行时线程会被阻塞,从而导致效率下降。
在重叠执行时,即使操作还未完成,调用的函数也会立即返回。
费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。
"重叠"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;其次,为了保护系统对串口的初始设置,调用 GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识VC串口通信技术网下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()功能:打开串口设备函数原型1.HANDLE CreateFile(2.LPCTSTR lpFileName, // 串口名称字符串;如: "COM1" 或 "COM2"3.DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE,4.DWORD dwShareMode, // 共享模式;"必须"为 0, 即不能共享5.LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL6.DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为 OPEN_EXISTING7.DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/O8.HANDLE hTemplateFile // 临时文件的句柄,通常为NULL9.);函数说明:如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
例子:1.Handle m_hComm =CreateFile(com1,GENERIC_READ||GENERIC_WRITE,0,NULL,OPEN_EXISTIN G,FILE_FLAG_OVERLAPPED,0);CloseHandle();功能:关闭串口函数原型:1.BOOL CloseHandle(2.HANDLE hObject // handle to object to close3.)使用比较简单,其中参数hObject为需要关闭的串口句柄。
GetCommState()功能:获得串口状态函数原型:1.BOOL GetCommState(2.HANDLE hFile, // handle of communications device3.LPDCB lpDCB // address of device-control block structure4.);SetCommState()功能:设置串口状态1.BOOL SetCommState(2.HANDLE hFile, // handle of communications device3.LPDCB lpDCB // address of device-control block structure4.);函数说明:在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。
这需要通过一个DCB结构来进行。
DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。
在查询或配置置串行口的属性时,都要用DCB结构来作为缓冲区。
调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。
一般在用CreateFile打开串行口后,可以调用 GetCommState 函数来获取串行口的初始配置。
要修改串行口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的 DCB结构来设置串行口。
举例:1.DCB dcb;2.memset(&dec,0,dizeof(dcb));3.if(!GetCommState(HComm,&dcb))//获取当前DCB配置4.return FALSE;5.dcb.BaudRate = CBR_9600;//修改数据传输率6.............7.if(SetCommState(hComm,&dcb))//设置新参数8....... //错误处理BuildCommDCB()功能:初始化DCB结构函数原型:1.BOOL BuildCommDCB(2.LPCTSTR lpDef, // pointer to device-control string3.LPDCB lpDCB // pointer to device-control block4.);示例:1.DCB dcb;2.memset(&dcb,0,sizeof(dcb));3.dcb.DCBlength = sizeof(dcb);4.if(!BuildCommDCb("9600,n,8,1",&dcb))//"baud=9600 parity=N data=8stop=1"5.{6....... //参数修改错误7.return FALSE;8.}9.else10.{11....... //己准备就绪12.}SetupComm()功能:设置I/O缓冲区的大小函数原型:1.BOOL SetupComm(2.HANDLE hFile, // handle to communications device3.DWORD dwInQueue, // size of input buffer4.DWORD dwOutQueue // size of output buffer5.);说明:除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。
Windows用I/O缓冲区来暂存串行口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。
调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
先介绍一个结构:COMMTIMEOUTS1.typedef struct _COMMTIMEOUTS {2.DWORD ReadIntervalTimeout; // 读间隔超时3.DWORD ReadTotalTimeoutMultiplier; // 读时间系数4.DWORD ReadTotalTimeoutConstant; // 读时间常量5.DWORD WriteTotalTimeoutMultiplier; // 写时间系数6.DWORD WriteTotalTimeoutConstant; // 写时间常量7.} COMMTIMEOUTS,*LPCOMMTIMEOUTS;再介绍两个函数GetCommTimeouts功能:读取TimeOut的值函数原型:1.BOOL GetCommTimeouts(2.HANDLE hFile, // handle of communications device3.LPCOMMTIMEOUTS lpCommTimeouts // address of comm. time-outsstructure4.);SetCommTimeouts功能:设置TimeOUt的值函数原型:1.BOOL SetCommTimeouts(2.HANDLE hFile, // handle of communications device3.LPCOMMTIMEOUTS lpCommTimeouts // address of communicationstime-out structure4.);这里顺便介绍一下TimeOut机制的两个性质:超时函数说明:在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。
如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或 WriteFile的操作就会结束。
要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。
调用SetCommTimeouts可以用某一个COMMTIMEOUTS 结构的内容来设置超时。
有两种超时:间隔超时和总超时。
间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。
写操作只支持总超时,而读操作两种超时均支持。
用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为: COMMTIMEOUTS结构的成员都以毫秒为单位。
总超时的计算公式是:总超时=时间系数×要求读/写的字符数 + 时间常量例如,如果要读入10个字符,那么读操作的总超时的计算公式为:读总超时=ReadTotalTimeoutMultiplier×10 + ReadTotalTimeoutConstant可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。
如果所有写超时参数均为0,那么就不使用写超时。
如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。
如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。
在用重叠方式读写串行口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。
在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。