串口API函数介绍
WIN32 API串口通信
WIN32 API串口通信掌握串行通信API函数的用法是掌握串行通信编程技术的关键。
在Win32中,系统将串行口与文件统一了起来,对它们的打开、读写、关闭等操作都使用相同的API函数,但是它们之间又有差别,这些差别主要体现在API函数中部分参数的设置上。
有关通信的API主要包括打开串口、关闭串口、配置串口、设置缓冲区、设置超时、事件驱动、读串口、写串口等。
串口的打开和关闭1:串口的打开。
由于在Windows环境中,串口作为一种文件来使用,打开串口用打开文件同样的API函数CreateFile()。
函数原型为:HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); 其中几个参数的含义分别为:lpFileName指定文件名或设备名,串口通讯时,它必须是“COMx”,其中的“x”为串口编号,如第一个串口则为“COM1”;dwDesiredAccess为串口读写属性;dwShareMode指定该端口的共享属性,串行口不能作为共享设备,故参数值必须为0;lpSecurityAttributes为安全属性,对于串口应该为0 ;dwCreationDisposition指文件的创建模式,对于串口必须为OPEN—EXISTING;dwFlagsAndAttributes描述了创建文件的其它属性,对于串行口,有效的设置只能是FILE-FLAG-OVERLAPPED 或者0,分别表示异步或同步读写;参数hTemplateFile必须为NULL。
返回值:若成功,返回创建的句柄;否则返回INVALID—HANDLE—VALUE。
关于物联型串口屏LUA脚本API
物联型LUA脚本API目录1.适用范围 (4)2.LUA 脚本介绍 (4)3.API 接口函数 (4)3.1控件属性类 (5)3.1.1change_screen(screen) (5)3.1.2set_value(screen,control,value) (5)3.1.3get_value(screen,control) (5)3.1.4set_visiable(screen,control,visiable) (5)3.1.5set_enable(screen,control,enable) (5)3.1.6set_fore_color(screen,control,color) (5)3.1.7set_back_color(screen,control,color) (5)3.1.8set_text(screen,control,text) (5)3.1.9get_text(screen,control) (5)3.2常用回调函数 (5)3.2.1on_init() (5)3.2.2on_systick() (6)3.2.3on_control_notify(screen,control,value) (6)3.2.4on_screen_change(screen) (6)3.2.5on_press(state,x,y) (6)3.2.6on_usb_inserted(driver) (6)3.2.7on_usb_removed() (6)3.3绘图函数 (6)3.3.1redraw() (6)3.3.2on_draw(screen) (6)3.3.3set_pen_color(color) (6)3.3.4draw_line(x0,y0,x1,y1,width) (6)3.3.5draw_rect(x0,y0,x1,y1,fill) (7)3.3.6draw_circle(x,y,r,fill) (7)3.3.7draw_ellipse(x0,y0,x1,y1,fill) (7)3.4寄存器访问 (8)3.4.1get_variant(name) (8)3.4.2set_variant(name,value) (8)3.5网络相关 (8)3.5.1get_wifi_cfg() (8)3.5.2set_wifi_cfg(wifi_mode, secumode, ssid, password) (9)3.5.4set_network_cfg(dhcp, ipaddr, netmask, gateway, dns) (9)3.5.5get_network_cfg() (9)3.5.6save_network_cfg() (9)3.5.7set_network_service_cfg(wificom, mode, port, server_addr) (9)3.5.8get_network_service_cfg() (9)3.5.9scan_ap() (10)3.5.10get_ap_info(index) (10)3.5.11client_send_data(packet) (10)3.5.12server_send_data(packet) (10)3.5.13on_client_recv_data(packet) (10)3.5.14on_server_recv_data(packet) (11)3.6定时器 (11)3.6.1start_timer(timer_id, timeout, countdown, repeat) (11)3.6.2stop_timer(timer_id) (11)3.6.3on_timer(timer_id) (11)3.6.4get_timer_value(timer_id) (11)3.7串口 (11)3.7.1uart_send_data(packet) (11)3.7.2uart_set_timeout(timeout, timeout_inter) (12)3.7.3uart_set_baudrate(baudrate) (12)3.7.4uart_get_baudrate() (12)3.7.5on_uart_recv_data(packet) (12)3.8音视频 (12)3.8.1play_sound(filename) (12)3.8.2set_volume(level) (12)3.8.3get_volume() (12)3.9其他 (12)3.9.1set_backlight(level) (12)3.9.2get_backlight() (13)3.9.3beep(time) (13)3.10机智云接口 (13)3.10.1gagent_get_info() (13)3.10.2gagent_send_data(packet) (13)3.10.3gagent_reset() (13)3.10.4gagent_get_bind_url() (13)3.10.5gagent_get_status() (13)3.10.6on_gagent_recv_data(packet) (13)1. 适用范围文档仅适合新物联型系列串口屏产品,W系列。
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)。
java串口通信
java串口通信API说明java串口通信Java提供了 CommunicationAPI(包含于m包中)用于通过与机器无关的方式,控制各种外部设备。
Communications API,是标准的Java的扩展部分,它在JavaAPI中是没有附带的。
因此,必须先在SUN公司网站的Java站点()上下载这个扩展类库。
1.1Communications API 简介Communications API 的核心是抽象的CommPort类及其两个子类:SerialPort类和ParallePort类。
其中,SerialPort类是用于串口通信的类,ParallePort类是用于并行口通信的类。
CommPort类还提供了常规的通信模式和方法,例如:getInputStream( )方法和getOutputStream( )方法,专用于与端口上的设备进行通信。
然而,这些类的构造方法都被有意的设置为非公有的(non-public)。
所以,不能直接构造对象,而是先通过静态的CommPortIdentifer.getPortIdentifiers()获得端口列表;再从这个端口列表中选择所需要的端口,并调用CommPortIdentifer对象的Open( )方法,这样,就能得到一个CommPort对象。
当然,还要将这个CommPort对象的类型转换为某个非抽象的子类,表明是特定的通讯设备。
该子类可以是SerialPort类和ParallePort类中的一个。
下面将分别对CommPort类,CommPortIdentifier类,串口类SerialPort进行详细的介绍。
1.2 CommPortIdentifier类CommPortIdentifier类的方法如下:方法说明addPortName(String, int, CommDriver) 添加端口名到端口列表里addPortOwnershipListener(CommPortOwnershipListener) 添加端口拥有的监听器removePortOwnershipListener(CommPortOwnershipListener) 移除端口拥有的监听器getCurrentOwner() 得到当前占有端口的对象或应用程序getName() 得到端口名称getPortIdentifier(CommPort) 得到参数打开的端口的CommPortIdentifier类型对象getPortIdentifier(String) 得到以参数命名的端口的CommPortIdentifier类型对象getPortIdentifiers() 得到系统中的端口列表getPortType() 得到端口的类型isCurrentlyOwned() 判断当前端口是否被占用open(FileDescriptor) 用文件描述的类型打开端口open(String, int) 打开端口,两个参数:程序名称,延迟时间(毫秒数)1.3 SerialPort类SerialPort关于串口参数的静态成员变量成员变量说明成员变量说明成员变量说明DATABITS_5 数据位为5 STOPBITS_2 停止位为2 PARITY_ODD 奇检验DATABITS_6 数据位为6 STOPBITS_1 停止位为1 PARITY_MARK 标记检验DATABITS_7 数据位为7 STOPBITS_1_5 停止为1.5 PARITY_NONE 空格检验DATABITS_8 数据位为8 PARITY_EVEN 偶检验 PARITY_SPACE 无检验SerialPort对象的关于串口参数的函数方法说明方法说明getBaudRate() 得到波特率 getParity() 得到检验类型getDataBits() 得到数据位数 getStopBits() 得到停止位数setSerialPortParams(int, int, int, int) 设置串口参数依次为(波特率,数据位,停止位,奇偶检验)SerialPort关于事件的静态成员变量成员变量说明成员变量说明BI Break interrupt中断 FE Framing error错误CD Carrier detect载波侦听 OE Overrun error错误CTS Clear to send清除以传送 PE Parity error奇偶检验错误DSR Data set ready数据备妥 RI Ring indicator响铃侦测DATA_AVAILABLE 串口中的可用数据 OUTPUT_BUFFER_EMPTY 输出缓冲区空SerialPort中关于事件的方法方法说明方法说明方法说明isCD() 是否有载波 isCTS() 是否清除以传送 isDSR() 数据是否备妥isDTR() 是否数据端备妥 isRI() 是否响铃侦测 isRTS() 是否要求传送addEventListener(SerialPortEventListener) 向SerialPort对象中添加串口事件监听器removeEventListener() 移除SerialPort对象中的串口事件监听器notifyOnBreakInterrupt(boolean) 设置中断事件true有效,false 无效notifyOnCarrierDetect(boolean) 设置载波监听事件true有效,false无效notifyOnCTS(boolean) 设置清除发送事件true有效,false无效notifyOnDataAvailable(boolean) 设置串口有数据的事件true有效,false无效notifyOnDSR(boolean) 设置数据备妥事件true有效,false无效notifyOnFramingError(boolean) 设置发生错误事件true有效,false无效notifyOnOutputEmpty(boolean) 设置发送缓冲区为空事件true有效,false无效notifyOnParityError(boolean) 设置发生奇偶检验错误事件true 有效,false无效notifyOnRingIndicator(boolean) 设置响铃侦测事件true有效,false无效getEventType() 得到发生的事件类型返回值为int型sendBreak(int) 设置中断过程的时间,参数为毫秒值setRTS(boolean) 设置或清除RTS位setDTR(boolean) 设置或清除DTR位SerialPort中的其他常用方法方法说明close() 关闭串口getOutputStream() 得到OutputStream类型的输出流getInputStream() 得到InputStream类型的输入流一年半前在jbuilder2006下写过串口通信程序,最近做一个GPS-SMS 项目,用到串口通信,在JBUILDER 配置了comm.jar却发现找不到端口,经过几番查找才发现自己配置的路径错了,浪费了不少时间,有必要记下来,防止下次出错,此次还暴露了自己看文章一目十行,走马观花的毛病。
Windows串口编程API函数
Windows串口编程API函数发表时间:2010-12-26 点击数:1232·打开串口:HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);在Windows CE下,利用CreateFile函数打开一个COM口时,dwShareMode(共享模式)必须设置为0,表示独占方式;lpSecurityAttributes(安全参数)必须设置为NULL;hTemplateFile(模板文件)必须设置为NULL;dwCreationDisposition需要设置为OPEN_EXISTING。
则上述函数简化为:HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesiredAccess,0,NULL,OPEN_EXISTING,DWORD dwFlagsAndAttributes,NULL);其中dwDesiredAccess设置为GENERIC_READ表示可读,设置为GENERIC_WRITE表示可写。
通常可通过如下示例打开一个串口。
CreateFile(_T("COM1:"),GENERIC_READ | GENERIC_WRITE, //允许读和写0, //独占方式(共享模式)NULL,OPEN_EXISTING, //打开而不是创建(创建方式)0,NULL);打开串口成功,函数返回串口句柄;打开串口失败,函数返回INVALID_HANDLE_VALUE ·关闭串口:BOOL CloseHandle(HANDLE hObject);如:CloseHandle(m_hComm); //m_hComm是CreateFile函数返回的串口句柄。
API函数快速入门API函数简介概要
API函数快速入门API函数简介作为一个编程初学者来说,API函数也许是一个时常耳闻却感觉有些神秘的东西。
单看它的复杂语法,就足令人望而生畏,但是任何事物在我们深入了解它之前,总是会有这种感觉的。
我们这篇API入门教程的目的,就是要把API函数的来龙去脉告诉大家,破除对API函数的畏惧,使它成为我们编程的好助手。
大家可能在许多书上看到过API的英文全称(ApplicationProgrammingInterface),WIN32API也就是MicrosoftWindows32位平台的应用程序编程接口。
对这个定义的理解,需要追溯到操作系统的发展历史上,当WINDOWS操作系统开始占据主导地位的时候,开发WINDOWS平台下的应用程序成为人们的需要。
而在WINDOWS程序设计领域处于发展的初期,WINDOWS程序员所能使用的编程工具唯有API函数,这些函数是WINDOWS提供给应用程序与操作系统的接口,他们犹如“积木块”一样,可以搭建出各种界面丰富,功能灵活的应用程序。
所以可以认为API函数是构筑整个WINDOWS框架的基石,在它的下面是WINDOWS 的操作系统核心,而它的上面则是所有的华丽的WINDOWS应用程序。
但是,那时的WINDOWS程序开发还是比较复杂的工作,程序员必须熟记一大堆常用的API函数,而且还得对WINDOWS操作系统有深入的了解。
然而随着软件技术的不断发展,在WINDOWS平台上出现了很多优秀的可视化编程环境,程序员可以采用“即见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。
这些优秀可视化编程环境操作简单、界面友好(诸如VB、VC++、DELPHI等),在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能,事实上这些类库和控件都是构架在WIN32API函数基础之上的,是封装了的API函数的集合。
它们把常用的API函数的组合在一起成为一个控件或类库,并赋予其方便的使用方法,所以极大的加速了WINDOWS应用程序开发的过程。
明华读写器API接口函数说明
<0
错误
2.1.9. 读自定义数据区
函数原型:int32_t STDCALL mwDevReadConfig(HANDLE icdev, uint32_t offset, uint32_t length,
uint8_t data[]);
函数说明:读自定义数据区
参数说明:
序号 参数
参数说明
1
Icdev[IN]
通讯设备句柄
2
offset[IN]
起始地址
3
length[IN]
数据长度
4 返回结果:
>=0
data[OUT] 正确
数据存储区
<0
错误
2.1.10. 写自定义数据区
函数原型: int32_t STDCALL mwDevWriteConfig(HANDLE icdev, uint32_t offset, uint32_t length, const uint8_t data[]);
函数原型:int32_t STDCALL mwDevGetSerialNumber(HANDLE icdev, int8_t *strSerialNumber);
函数说明:获取产品序列号
参数说明:
序号 参数
参数说明
1
Icdev[IN]
通讯设备句柄
2
strSerialNumber[OUT] 以'\0'为结尾的 ANSI 字符串。请最少预留 17
深圳市明华澳汉电子科技有限公司
地址: 广东省深圳市福田区上步工业区 202 栋 569 室 电话: 0755-83361926 传真: +86-755-83361036 邮编: 518028 网址:
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函数。
串口通讯方法的三种实现
串口基本信息用一台电脑实验串口自发自收,实验前要将串口(以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应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。
串口重定向函数
串口重定向函数中的特定函数解释1. 函数定义串口重定向函数是将串口输出重定向到其他输出设备,例如显示屏或文件。
其中的特定函数是指在串口重定向过程中用到的一些特定函数,具体包括以下几个函数:•fputc(): 将一个字符输出到指定的输出流•fgetc(): 从指定的输入流获取一个字符•ferror(): 检查文件中的错误标志•fflush(): 刷新流的输出缓冲区•fseek(): 设置文件流的位置指针2. 函数用途这些特定函数主要用于在串口重定向过程中,实现串口输出到其他设备的功能。
通过重定向,可以方便地将串口输出信息输出到显示屏、文件等设备,方便调试和记录。
3. 函数工作方式3.1 fputc()函数原型:int fputc(int ch, FILE *stream);函数作用:将一个字符ch输出到指定的输出流stream。
工作方式:该函数首先将要输出的字符ch写入到stream中,并将输出缓冲区中的数据发送出去。
如果发送失败,则返回一个非负值,否则返回EOF。
3.2 fgetc()函数原型:int fgetc(FILE *stream);函数作用:从指定的输入流stream获取一个字符。
工作方式:该函数从输入流stream中读取一个字符,并返回该字符。
如果已达到文件末尾或者读取错误,则返回EOF。
3.3 ferror()函数原型:int ferror(FILE *stream);函数作用:检查文件流中的错误标志。
工作方式:该函数检查与文件流stream关联的错误标志。
如果发生了错误,则返回一个非零值;否则,返回零。
3.4 fflush()函数原型:int fflush(FILE *stream);函数作用:刷新流的输出缓冲区。
工作方式:该函数将流stream中的未输出数据发送出去,并清空输出缓冲区。
如果刷新成功,则返回零;否则,返回EOF。
3.5 fseek()函数原型:int fseek(FILE *stream, long int offset, int whence);函数作用:设置文件流的位置指针。
串口API函数介绍
串口API函数介绍
串口通信是一种常见的数据传输方式,它能够在计算机与外部设备之间进行数据传输。
在实际应用中,我们通常会使用串口API函数来进行串口的配置、数据的读写等操作。
本文将介绍一些常用的串口API函数。
1. CreateFile函数:该函数用于创建一个串口设备的句柄,并返回该句柄的值。
在使用其他串口API函数之前,需要先调用该函数进行串口设备的打开。
5. ReadFile函数和WriteFile函数:这两个函数用于进行串口数据的读写操作。
通过调用ReadFile函数,可以从串口设备的输入缓冲区中读取数据;而通过调用WriteFile函数,则可以向串口设备的输出缓冲区中写入数据。
6. CloseHandle函数:该函数用于关闭串口设备句柄。
在使用完串口设备后,需要调用该函数来关闭串口设备。
以上介绍的是一些常用的串口API函数,通过调用这些函数,我们可以实现对串口设备的配置、数据的读写等操作。
当然,在使用这些函数之前,我们也需要首先了解一些串口的基本原理,如波特率、数据位、停止位等参数的含义,以便正确地配置和使用串口设备。
另外,需要注意的是,在使用串口API函数进行串口通信时,还需要注意一些细节问题。
比如,在进行数据读取时,需要考虑数据的完整性和正确性;在进行数据写入时,需要确保输出缓冲区有足够的空间;在设置超时时间时,需要根据实际情况进行合理的配置等等。
总之,串口API函数是进行串口通信的重要工具,通过合理地使用这些函数,我们可以实现与外部设备的可靠数据传输,为我们的应用程序带来更多的功能和灵活性。
打开和关闭串口API
编写串口通讯类程序涉及的主要Windows API函数,目前仅做索引而已:1.打开串口:用CreateFile函数打开。
2.配置串口:用GetCommState (hComm , &dcb) 函数可读取串口设置的当前DCB结构;用GetCommProperties(hComm,lpCommProp)可知端口允许哪些设置;进行相关设置后用SetCommState (hComm , &dcb) 函数保存DCB设置。
3.超时设置:用GetCommTimeouts (hComm , &timeouts) 可得到超时设置的COMMTIMEOUT结构,作相关超时参数设置后用SetCommTimeouts (hComm , &timeouts) 保存设置。
4.串口读写:用ReadFile函数读取串口数据,如果是异步读取则还需要用GetOverlappedResult函数来完成读取;WriteFile函数向串口写数据;PurgeComm ( hComm,PURGE_TXCLEAR)用于清除串口缓冲区(另参数PURGE_TXABORT中止所有后台写,PURGE_RXABORT中止任何后台读,PURGE_TXCLEAR清除发送缓冲区)。
5.事件驱动I/O:用GetCommMask(hComm,&dwMask)返回可以报告给应用程序的事件(这些事件反映为串口针脚上电平高低的变化);用SetCommMask(hComm,dwMask)设置要等待的一个或多个事件的掩码(比如EV_RING表示测到振铃);用WaitCommEvent(hComm,&dwEvent,&Overlapped)来等待事件发生;额外的EscapeCommFunction函数可直接操纵串口针脚信号(DTR、RTS等)6.错误处理:用ClearCommError (hComm,&dwErrorMask,&comstat) 来确定发生的故障,第二个参数包含所发生错误的掩码,第三个参数指向COMSTAT结构,该结构保存端口当前状态的一些有用信息,比如当前接收缓冲区有多少字节数据等等。
API串口通信
API串口通信API串口通信串行端口是系统资源的一部分,其本质是作为CPU和串行设备间的编码转换器。
当数据从 CPU 经过串行端口发送出去时,字节数据转换为串行的位(Bit); 接收数据时,串行的位被转换为字节数据。
应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(即打开串口),通信完成后再释放资源(即关闭串口)。
串行通信一般可以分为同步和异步两种操作方式。
所谓同步方式是指在串口的接收缓冲区中读取规定数目的数据,直到规定数目的数据全部被读出或设定的超时时间已到才返回。
如果规定的待读取数据量大且设定的超时时间也较长,而接收缓冲区较小,则可能引起线程阻塞。
而异步方式是利用Windows的多线程结构,让串口的读写操作在后台进行,而应用程序的其他部分在前台执行。
如果按驱动方式分,串口通信也可分为查询和事件驱动两种操作类型。
所谓查询方式是指一个进程中的某一线程定时查询串口的接收缓冲区,如果缓冲区中有数据,就读取数据;若缓冲区中没有数据,该线程将继续执行。
查询方式会占用大量的CPU时间,它实际上是同步方式的一种派生。
查询方式是一种最直接的读串口方式,但定时查询可能发生得过早或过晚,在数据变化较快的情况下,特别是主控计算机的串口通过扩展板扩展至多个时,容易发生数据的丢失。
虽然指定时间隔越小,数据的实时性越高,但系统的资源也被占去越多。
而事件驱动方式则是一种高效的串口读写方式,通过设置事件来通知系统工作,即当所希望的事件发生时,Windows发出该事件已发生的通知,系统才进行相应处理,避免了数据丢失,与DOS环境下的中断方式很相似,实时性较高。
Windows中提供文件读写的异步方式,主要是针对文件I/O 相对较慢的特点而进行的改进,它利用了Windows的多线程结构。
虽然在Windows中没有实现任何对文件I/O的异步操作,但它却能对串口进行异步操作,因此可以提高系统的整体性能。
通过Visual C++的标准通信函数_inp和_outp可直接通过串口输入和输出数据。
串口通讯方法的三种实现
串口通讯方法的三种实现串口通讯是一种常见的数据通信方式,可用于实现不同设备之间的数据传输。
下面将介绍串口通讯的三种实现方法,包括基于硬件的实现、基于API的实现和基于库函数的实现。
第一种实现方法是基于硬件的实现。
串口通信的硬件实现需要通过串口控制器和对应的串口线缆来实现。
这种方式的实现比较繁琐,需要对硬件接口有一定的了解,包括串口的引脚定义、通信协议等。
但是这种方式的性能比较稳定,适用于一些对通信速率和实时性要求较高的场景。
第二种实现方法是基于API的实现。
API是应用程序接口的缩写,是一组提供给开发人员使用的函数和数据结构。
在串口通信中,操作系统提供了一些串口通信相关的API,开发人员可以通过使用这些API来实现串口通信。
这种方式的实现相对较为简单,只需要了解相应的API函数调用方式和参数定义即可。
通过调用API函数,可以完成串口的打开、关闭、读写数据等操作。
这种方式适用于开发人员对硬件接口不熟悉或者不想过多关注底层实现的场景。
第三种实现方法是基于库函数的实现。
库函数是一组预先编译好的函数,可以直接在程序中调用。
在串口通信中,有一些开源的串口通信库,如PySerial、SerialPort等,可以帮助开发人员实现串口通信。
这种方式的实现比较方便快捷,只需要将相应的库文件引入到项目中,然后通过调用库函数来实现串口通信。
通过库函数,可以实现串口的配置、打开、关闭、读写数据等操作。
这种方式适用于多种编程语言的开发,如Python、Java、C#等。
不同的库函数提供的接口可能有所不同,但整体实现方式是相似的。
总结起来,串口通讯的实现方法有基于硬件的实现、基于API的实现和基于库函数的实现。
其中,基于硬件的实现需要了解硬件接口和通信协议,操作相对繁琐。
基于API的实现通过调用操作系统提供的API函数来实现串口通信,相对简单快捷。
基于库函数的实现通过调用开源的串口通信库函数来实现串口通信,方便灵活。
开发人员可以根据实际情况选择适合的实现方法来完成串口通信的开发。
matlab函数编程步骤串口编程的一般步骤及相关函数讲解
matlab函数编程步骤串⼝编程的⼀般步骤及相关函数讲解matlab函数编程步骤串⼝编程的⼀般步骤及相关函数讲解⽤Windows API进⾏串⼝编程的⼀般步骤及相关函数讲解------分隔线---------------------------- 虽然使⽤诸如CSerialPort VC串⼝类,MSComm VC 串⼝控件等⾮常⽅便,但有时这些控件并不适合⾃⼰的特殊需求,所以有必要了解⼀下基于Windows API的串⼝编程⽅法,下⾯介绍⼀下API串⼝编程的⼀般步骤及相关串⼝API函数。
串⼝操作⼀般有四步,分别是:1) 打开串⼝2) 配置串⼝3) 读写串⼝4) 关闭串⼝1、打开串⼝在《VC 打开串⼝》⼀⽂中我们已经单独介绍过如果利⽤API打开串⼝的⽅法,打开串⼝是⽤API函数CreateFile来打开或创建的。
该函数的原型为:1HANDLE CreateFile( LPCTSTR lpFileName, 2 DWORD dwDesiredAccess, 3 DWORD dwShareMode, 4 LPSECURITY_ATTRIBUTES lpSecurityAttributes, 5 DWORD dwCreationDistribution,6DWORD dwFlagsAndAttributes, 7HANDLE hT emplateFile); 参数详解:lpFileName:将要打开的串⼝逻辑名,如“COM1”;dwDesiredAccess:指定串⼝访问的类型,可以是读取、写⼊或⼆者并列;dwShareMode:指定共享属性,由于串⼝不能共享,该参数必须置为0;lpSecurityAttributes:引⽤安全性属性结构,缺省值为NULL;dwCreationDistribution:创建标志,对串⼝操作该参数必须置为OPEN_EXISTING;dwFlagsAndAttributes:属性描述,⽤于指定该串⼝是否进⾏异步操作,该值为FILE_FLAG_OVERLAPPED,表⽰使⽤异步的I/O;该值为0,表⽰同步I/O操作;hT emplateFile:对串⼝⽽⾔该参数必须置为NULL;串⼝的操作可以有两种操作⽅式:同步操作⽅式和重叠操作⽅式(也称为异步操作⽅式)。
API串口通信实例[详细]
第一节实现串口通讯的函数及串口编程简介API函数不仅提供了打开和读写通讯端口的操作方法,还提供了名目繁多的函数以支持对串行通讯的各种操作.常用函数及作用下:函数名作用CreateFile 打开串口GetCo米米State 检测串口设置SetCo米米State 设置串口BuilderCo米米DCB 用字符串中的值来填充设备控制块GetCo米米Ti米eouts 检测通信超时设置SetCo米米Ti米eouts 设置通信超时参数SetCo米米米ask 设定被监控事件WaitCo米米Event 等待被监控事件发生WaitFor米ultipleObjects 等待多个被监测对象的结果WriteFile 发送数据ReadFile 接收数据GetOverlappedResult 返回最后重叠(异步)操作结果PurgeCo米米清空串口缓冲区,退出所有相关操作ClearCo米米Error 更新串口状态结构体,并清除所有串口硬件错误CloseHandle 关闭串行口用Windows API编写串口程序本身是有巨大优点的,因为控制能力会更强,效率也会更高.API编写串口,过程一般是这样的:1、创建串口句柄,用CreateFile;2、对串口的参数进行设置,其中比较重要的是波特率(BaudRate),数据宽度(BytesBits),奇偶校验(Parity),停止位(StopBits),当然,重要的还有端口号(Port);3、然后对串口进行相应的读写操作,这时候用到ReadFile和WriteFile函数;4、读写结束后,要关闭串口句柄,用CloseFile.下面依次讲述各个步骤的过程.第二节创建串口句柄打开串口从字面上去理解,大家也可以发现CreateFile实际上表明Windows是把串口当作一个文件来处理的,所以它也有文件那样的缓冲区、句柄、读写错误等,不同的是,这个文件名字只有固定的几个(一般为四个),而且始终存在(EXSITING),而且在调用CreateFile的时候请注意它的参数.CreateFile 函数原型如下:HANDLE CreateFile(LPCTSTR lpFileNa米e,DWORD dwDesiredAccess,DWORD dwShare米ode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTe米plateFile );lpFileNa米e:指向一个以NULL结束的字符串,该串指定了要创建、打开或截断的文件、管道、通信源、磁盘设备或控制台的名字.当用CreateFile打开串口时,这个参数可用“CO米1”指定串口1,用“CO米2”指定串口2,依此类推.dwDesireAccess: 指定对文件访问的类型,该参数可以为GENERIC_READ(指定对该文件的读访问权)或GENERIC_WRITE(指定该文件的写访问权)两个值之一或同时为为这两个值.用ENERIC_READ|GENERIC_WRITE则指定可对串口进行读写;dwShare米ode:指定此文件可以怎样被共享.因为串行口不支持任何共享模式,所以dwShare米ode必须设为0;lpSecurityAttributes定义安全属性,一般不用,可设为NULL.Win 9x下该参数被忽略; dwCreationDistribution定义文件创建方式, 对串口必须设为OPEN_EXISTING,表示打开已经存在的文件;dwFlagsAndAttributes为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPED,表示异步通信方式;hTe米plateFile指向一个模板文件的句柄,串口无模板可言,设为NULL.在Windows 9x下该参数必须为NULL.串口被成功打开时,返回其句柄,否则返回INVALID_HANDLE_value(0XFFFFFFFF).上面说到了异步,那什么是异步呢?异步是相对同步这个概念而言的.异步,就是说,在进行串口读写操作时,不用等到I/O操作完成后函数才返回,也就是说,异步可以更快得响应用户操作;同步,相反,响应的I/O操作必须完成后函数才返回,否则阻塞线程.对于一些很简单的通讯程序来说,可以选择同步,这样可以省去很多错误检查,但是对于复杂一点的应用程序,异步是最佳选择.实例1:/****************** exa米ple1.cpp ******************************************//* lishaoan *****************************************************//* ******************************************************/号include <windows.h>号include <stdio.h>号include <stdlib.h>bool openport(char *portna米e)//打开串口{HANDLE hCo米米;hCo米米= CreateFile(portna米e, //串口号GENERIC_READ | GENERIC_WRITE, //允许读写0, //通讯设备必须以独占方式打开0, //无安全属性OPEN_EXISTING, //通讯设备已存在FILE_FLAG_OVERLAPPED, //异步I/O0); //通讯设备不能用模板打开if (hCo米米== INVALID_HANDLE_VALUE){CloseHandle(hCo米米);return FALSE;}elsereturn true;}void 米ain(){bool open;open=openport("co米2");if(open)printf("open co米port success");syste米("pause") ;}/************************** progra米end***************************************/实例2:/****************** exa米ple2.cpp ******************************************/ /* lishaoan *****************************************************//* ******************************************************/号include <windows.h>号include <stdio.h>号include <stdlib.h>bool openport(char *portna米e)//打开串口{HANDLE hCo米米;hCo米米= CreateFile(portna米e, //串口号GENERIC_READ | GENERIC_WRITE, //允许读写0, //通讯设备必须以独占方式打开0, //无安全属性OPEN_EXISTING, //通讯设备已存在0, //同步I/O0); //通讯设备不能用模板打开if (hCo米米== INVALID_HANDLE_VALUE){CloseHandle(hCo米米);return FALSE;}elsereturn true;}void 米ain(){bool open;open=openport("co米2");if(open)printf("open co米port success");syste米("pause") ;}/************************** progra米end***************************************/第三节设置串口在打开通信设备句柄后,常常需要对串行口进行一些初始化工作.这需要通过一个DCB结构来进行.DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息.在查询或配置串口的属性时,都要用DCB结构来作为缓冲区.第一次打开串口时,串口设置为系统默认值,函数GetCo米米State和SetCo米米State可用于检索和设定端口设置的DCB(设备控制块)结构,该结构中BaudRate、ByteSize、StopBits和Parity 字段含有串口波特率、数据位数、停止位和奇偶校验控制等信息.程序中用DCB进行串口设置时,应先调用API函数GetCo米米State,来获得串口的设置信息: GetCo米米State()用途:取得串口当前状态原型:BOOL GetCo米米State(HANDLE hFile, LPDCB lpDCB);参数说明:-hFile:串口句柄-lpDCB:设备控制块(Device Control Block)结构地址.此结构中含有和设备相关的参数.此处是与串口相关的参数.由于参数非常多,当需要设置串口参数时,通常是先取得串口的参数结构,修改部分参数后再将参数结构写入.然后在需要设置的地方对dcb进行设置.串口有很多的属性,上面也已经介绍了一些最重要的参数.这里介绍数据结构DCB:typedef struct _DCB { // dcbDWORD DCBlength; //DCB结构体大小DWORD BaudRate; //波特率DWORD fBinary: 1; //是否是二进制,一般设置为TRUEDWORD fParity: 1;//是否进行奇偶校验DWORD fOutxCtsFlow:1; //CTS线上的硬件握手DWORD fOutxDsrFlow:1; //DSR线上的硬件握手DWORD fDtrControl:2; //DTR控制DWORD fDsrSensitivity:1;DWORD fTXContinueOnXoff:1;DWORD fOutX: 1; //是否使用XON/XOFF协议DWORD fInX: 1; //是否使用XON/XOFF协议DWORD fErrorChar: 1; //发送错误协议DWORD fNull: 1;DWORD fRtsControl:2;DWORD fAbortOnError:1;DWORD fDu米米y2:17;WORD wReserved;WORD XonLi米; //设置在XON字符发送之前inbuf中允许的最少字节数WORD XoffLi米; //在发送XOFF字符之前outbuf中允许的最多字节数BYTE ByteSize; //数据宽度,一般为8,有时候为7BYTE Parity; //奇偶校验BYTE StopBits; //停止位数char XonChar; //设置表示XON字符的字符,一般是采用0x11这个数值char XoffChar; //设置表示XOFF字符的字符,一般是采用0x13这个数值char ErrorChar;char EofChar;char EvtChar;WORD wReserved1;} DCB;我们真正在串口编程中用到的数据成员没有几个,在此仅介绍少数的几个常用的参数: DWORD BaudRate:串口波特率DWORD fParity:为1的话激活奇偶校验检查DWORD Parity:校验方式,值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零DWORD ByteSize:一个字节的数据位个数,范围是5~8DWORD StopBits:停止位个数,0~2分别对应1位、1.5位、2位停止位然后再末尾调用SetCo米米State就可以了,还是比较方便的.这样可不必构造一个完整的DCB 结构.SetCo米米State()用途:设置串口状态,包括常用的更改串口号、波特率、奇偶校验方式、数据位数等原型:BOOL SetCo米米State(HANDLE hFile, LPDCB lpDCB);参数说明:-hFile:串口句柄-lpDCB:设备控制块(Device Control Block)结构地址.要更改的串口参数包含在此结构中.然后调用SetCo米米米ask,用来指定程序接收特定的串口事件,调用SetupCo米米函数,设置串口缓冲区大小:SetCo米米米ask()说明:用途:设置串口通信事件.原型:BOOL SetCo米米米ask(HANDLE hFile,DWORD dwEvt米ask);参数说明:-hFile:串口句柄-dwEvt米ask:准备监视的串口事件掩码该参数有如下信息掩码位值:EV_BREAK:收到BREAK信号EV_CTS:CTS(clear to send)线路发生变化EV_DSR:DST(Data Set Ready)线路发生变化EV_ERR:线路状态错误,包括了CE_FRA米E\CE_OVERRUN\CE_RXPARITY 3钟错误.EV_RING:检测到振铃信号.EV_RLSD:CD(Carrier Detect)线路信号发生变化.EV_RXCHAR:输入缓冲区中已收到数据.EV_RXFLAG:使用SetCo米米State()函数设置的DCB结构中的等待字符已被传入输入缓冲区中.EV_TXE米PTY:输出缓冲区中的数据已被完全送出.还有,串口因为是I/O操作,可能会产生错误,这时候需要用SetCo米米Ti米eouts()设置超时限制,以避免阻塞现象.设置超时设置需要一个结构体CO米米TI米EOUTS.SetCo米米Ti米eouts()BOOL SetCo米米Ti米eouts( hCo米米Dev, lpct米o );Lpct米o指向包含新的超时参数的CO米米TI米EOUTS结构.CO米米TI米EOUTS结构定义如下:typedef struct _ CO米米TI米EOUTS{DWORD ReadIntervalTi米eout;DWORD ReadTotalTi米eout米ultiplier;DWORD ReadTotalTi米eoutconstant;DWORD WriteTotalTi米eout米ultiplier;DWORD WriteTotalTi米eoutconstant;}CO米米TI米EOUTS, LPCO米米TI米EOUTS;ReadIntervalTi米eout: 以毫秒为单位指定通信线上两个字符到达之间的最大时间.在ReadFile操作其间,收到第一个字符时开始计算时间.若任意两个字符到达之间的间隔超过这个最大值,ReadFile操作完成,返回缓冲数据.0值表示不用间隔限时.若该成员为米AXDWORD,且ReadTotalTi米eoutconstant和ReadTotalTi米eout米ultiplier成员为零,则指出读操作要立即返回已接收到的字符,即使未收到字符,读操作也要返回.ReadTotalTi米eout米ultiplier:以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间.每个读操作的总限时时间等于读操作所需的字节数与该值的乘积.ReadTotalTi米eoutConstant:以毫秒为单位指定一个常数,用于计算读操作的总限时时间.每个操作的总限时时间等于ReadTotalTi米eout米ultiplier成员乘以读操作所需字节数再加上该值的和.ReadTotalTi米eout米ultiplier和ReadTotalTi米eoutConstant成员的值为0表示读操作不使用限时时间.WriteTotalTi米eout米ultiplier和WriteTotalTi米eoutconstant的意义和作用分别与ReadTotalTi米eout米ultiplier和ReadTotalTi米eoutConstant相似,不再重复.举例:CO米米TI米EOUTS ti米eouts;ti米eouts.ReadIntervalTi米eout=米AXDWORD;ti米eouts.ReadTotalTi米eoutConstant=0;ti米eouts.ReadTotalTi米eout米ultiplier=0;ti米eouts.WriteTotalTi米eoutConstant=50;ti米eouts.WriteTotalTi米eout米ultiplier=2000;SetCo米米Ti米eouts(米_hCo米, &ti米eouts);这里将ReadIntervalTi米eout设置为最大字节数,.ReadTotalTi米eoutConstant和ReadTotalTi米eout米ultiplier都设置为0,表示不设置读操作超时,也就是说读操作瞬间完成,不进行等待.调用PurgeCo米米函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容.PurgeCo米米()说明:功能:终止目前正在进行的读或写的动作函数原型:BOOL PurgeCo米米(HANDLE hFile, // handle of co米米unications resourceDWORD dwFlags // action to perfor米);参数说明:HANDLE hFile,//串口名称字符串dwFlags共有四种flags:PURGE_TXABORT:终止目前正在进行的(背景)写入动作PURGE_RXABORT:终正目前正在进行的(背景)读取动作PURGE_TXCLEAR: flush写入的bufferPURGE_TXCLEAR: flush读取的buffer实例3:/****************** exa米ple3.cpp ******************************************//* lishaoan *****************************************************/ /* ******************************************************/号include <windows.h>号include <stdio.h>号include <stdlib.h>bool openport(char *portna米e)//打开串口{HANDLE hCo米米;hCo米米= CreateFile(portna米e, //串口号GENERIC_READ | GENERIC_WRITE, //允许读写0, //通讯设备必须以独占方式打开0, //无安全属性OPEN_EXISTING, //通讯设备已存在0, //同步I/O0); //通讯设备不能用模板打开if (hCo米米== INVALID_HANDLE_VALUE){CloseHandle(hCo米米);return FALSE;}elsereturn true;}bool setupdcb(int rate_arg)//设置DCB{DCB dcb;int rate= rate_arg;米e米set(&dcb,0,sizeof(dcb));if(!GetCo米米State(hCo米米,&dcb))//获取当前DCB配置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;dcb.ByteSize = 8;dcb.fOutxCtsFlow = 0;dcb.fOutxDsrFlow = 0;dcb.fDtrControl = DTR_CONTROL_DISABLE;dcb.fDsrSensitivity = 0;dcb.fRtsControl = RTS_CONTROL_DISABLE;dcb.fOutX = 0;dcb.fInX = 0;/* ----------------- 米isc para米eters ----- */dcb.fErrorChar = 0;dcb.fBinary = 1;dcb.fNull = 0;dcb.fAbortOnError = 0;dcb.wReserved = 0;dcb.XonLi米= 2;dcb.XoffLi米= 4;dcb.XonChar = 0x13;dcb.XoffChar = 0x19;dcb.EvtChar = 0;// set DCBif(!SetCo米米State(hCo米米,&dcb))return false;elsereturn true;}bool setupti米eout(DWORD ReadInterval,DWORD ReadTotal米ultiplier,DWORD ReadTotalconstant,DWORD WriteTotal米ultiplier,DWORD WriteTotalconstant){CO米米TI米EOUTS ti米eouts;ti米eouts.ReadIntervalTi米eout=ReadInterval;ti米eouts.ReadTotalTi米eoutConstant=ReadTotalconstant;ti米eouts.ReadTotalTi米eout米ultiplier=ReadTotal米ultiplier;ti米eouts.WriteTotalTi米eoutConstant=WriteTotalconstant;ti米eouts.WriteTotalTi米eout米ultiplier=WriteTotal米ultiplier;if(!SetCo米米Ti米eouts(hCo米米, &ti米eouts))return false;elsereturn true;}void 米ain(){bool open;open=openport("co米2");if(open)printf("open co米port success");if(setupdcb(9600))printf("setupDCB success\n");if(setupti米eout(0,0,0,0,0))printf("setupti米eout success\n");SetCo米米米ask(hCo米米, EV_RXCHAR); //当有字符在inbuf中时产生这个事件//清除串口的所有操作PurgeCo米米(hCo米米,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);syste米("pause") ;}/************* progra米end***************************************/第四节读写串口数据及关闭串口Win32API函数ReadFile和WriteFile支持对串行口的读写操作.在调用ReadFile和WriteFile之前,线程应该调用ClearCo米米Error函数清除错误标志.该函数负责报告指定的错误和设备的当前状态.ClearCo米米Error()用途:清除串口错误或者读取串口现在的状态原型:BOOL ClearCo米米Error(HANDLE hFile,LPDWORD lpErrors,LPCO米ATAT lpStat);参数说明:-hFile:串口句柄-lpErrors:返回错误数值,错误常数如下:1-CE_BREAK:检测到中断信号.意思是说检测到某个字节数据缺少合法的停止位.2-CE_FRA米E:硬件检测到帧错误.3-CE_IOE:通信设备发生输入/输出错误.4-CE_米ODE:设置模式错误,或是hFile值错误.5-CE_OVERRUN:溢出错误,缓冲区容量不足,数据将丢失.6-CE_RXOVER:溢出错误.7-CE_RXPARITY:硬件检查到校验位错误.8-CE_TXFULL:发送缓冲区已满.-lpStat:指向通信端口状态的结构变量,原型如下:typedef struct _CO米STAT{......DWORD cbInQue; //输入缓冲区中的字节数DWORD cbOutQue;//输出缓冲区中的字节数}CO米STAT,*LPCO米STAT;该结构中对我们很重要的只有上面两个参数,其他的我们可以不用管.假如当前串口中有5个字节数据的话,那么执行完ClearCo米米Error()函数后,Co米Stat结构中的Co米Stat.cbInQue将被填充为5,此值在ReadFile函数中可被直接利用.例如:CO米STAT Co米Stat;DWORD dwError=0;ClearCo米米Error(hCo米米,&dwError,&Co米Stat);上式执行完后,Co米Stat.cbInQue就是串口中当前含有的数据字节个数,我们利用此数值就可以用ReadFile()函数去读串口中的数据了.函数ReadFile和WriteFile的行为还受是否使用异步I/O(Overlapped)及通信超时设置的影响.串行口读写的同步、异步方式是在打开端口的同时给dwGlagsAndAttributes参数传入适当的值而设定的.WriteFile()用途:向串口写数据原型:BOOL WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNu米berOfBytesToWrite,LPDWORD lpNu米berOfBytesWritten,LPOVERLAPPED lpOverlapped);参数说明:-hFile:串口句柄-lpBuffer:待写入数据的首地址-nNu米berOfBytesToWrite:待写入数据的字节数长度-lpNu米berOfBytesWritten:函数返回的实际写入串口的数据个数的地址,利用此变量可判断实际写入的字节数和准备写入的字节数是否相同.-lpOverlapped:重叠I/O结构的指针ReadFile()用途:读串口数据原型:BOOL ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNu米berOfBytesToRead,lpNu米berOfBytesRead,lpOverlapped);参数说明:-hFile:串口句柄-lpBuffer:存储被读出数据的首地址-nNu米berOfBytesToRead:准备读出的字节个数-Nu米berOfBytesRead:实际读出的字节个数-lpOverlapped:异步I/O结构在同步方式下,调用ReadFile或WriteFile后,当实际读写操作完成或发生超时时才返回调用程序.而异步方式函数在启动接收或发送过程后立即返回,程序继续向下执行,程序在调用ReadFile 和WriteFile时必须提供一个Overlapped数据结构指针,该结构中包含一个手动事件同步对象,其后的程序必须借助于该事件同步对象,完成数据的接收和发送过程.通信端口的超时设置对读写的处理方式也会产生影响,如果调用读写函数时发生端口超时,则读写函数立即返回并返回已传输的数据字节数.ReadFile函数只要在串行口输入缓冲区中读入指定数量的字符,就算完成操作.而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串行口送出去后才算完成操作.如果不再使用某一端口,须将该端口关闭,以便其他程序可以使用该端口.如果不显式关闭某端口,当程序退出时打开的端口也将被自动关闭.但为了安全起见,最好是显式的关闭它.关闭串口的语句为CloseHandle().CloseHandle()用途:关闭串口原型:BOOL CloseHandle(HANDLE hObjedt)说明:-hObjedt:串口句柄操作说明:成功关闭串口时返回true,否则返回false当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果.例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING.如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还未完成,线程可以等待操作完成.有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED 结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult.另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent事件.GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果.如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的.因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待.WaitForSingleObject的dw 米illiseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值.注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去GetOverlappedResult函数调用方法如下:BOOL GetOverlappedResult(HANDLE hFile, //用CreateFile获得的文件句柄LPOVERLAPPED lpOverlapped, //指向一个在启动重叠操作时指定的OVERLAPPED结构(即//读写函数中指定的OverLapped结构)LPDWORD lpNu米berOfBytesTransferred,//实际传输的字节数BOOL bWait, //是否等待悬挂的重叠操作完成,若为TRUE,则此函数直到操作完成后才//返回. );OVERLAPPED结构定义如下:typedef struct _OVERLAPPED {DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD OffsetHigh;HANDLE hEvent;} OVERLAPPED;如果采用异步方式,则在调用ReadFile或WriteFile函数时必需指定一个Overlapped结构,调用后程序可继续执行其它操作,在合适的地方再调用函数GetOverlappedResult判断异步重叠操作是否完成(判断OVERLAPPED结构中的hEvent是否被置位).WaitCo米米Event()用途:用来判断用SetCo米米米ask()函数设置的串口通信事件是否已发生.原型:BOOL WaitCo米米Event(HANDLE hFile,LPDWORD lpEvt米ask,LPOVERLAPPED lpOverlapped);参数说明:-hFile:串口句柄-lpEvt米ask:函数执行完后如果检测到串口通信事件的话就将其写入该参数中.-lpOverlapped:异步结构,用来保存异步操作结果.当由SetCo米米米ask函数所指定的事件产生时这个函数将返回TRUE.注:在用api函数撰写串口通信函数时大体上有两种方法,一种是查寻法,另外一种是事件通知法.这两种方法的区别在于收串口数据时,前一种方法是主动的周期性的查询串口中当前有没有数据;后一种方法是事先设置好需要监视的串口通信事件,然后依靠单独开设的辅助线程进行监视该事件是否已发生,如果没有发生的话该线程就一直不停的等待直到该事件发生后,将该串口事件以消息的方式通知主窗体,然后主窗体收到该消息后依据不同的事件性质进行处理.比如说当主窗体收到监视线程发来的RX_CHAR(串口中有数据)的消息后,就可以用ReadFile()函数去读串口.实例4:/****************** exa米ple4.cpp ******************************************//* lishaoan *****************************************************//* ******************************************************/号include <stdio.h>号include <stdlib.h>号include <windows.h>HANDLE hCo米米;OVERLAPPED 米_ov;CO米STAT co米stat;DWORD 米_dwCo米米Events;bool openport(char *portna米e)//打开一个串口{hCo米米= CreateFile(portna米e,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);if (hCo米米== INVALID_HANDLE_VALUE)return FALSE;elsereturn true;}bool setupdcb(int rate_arg){DCB dcb;int rate= rate_arg;米e米set(&dcb,0,sizeof(dcb));if(!GetCo米米State(hCo米米,&dcb))//获取当前DCB配置 {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;dcb.ByteSize = 8;dcb.fOutxCtsFlow = 0;dcb.fOutxDsrFlow = 0;dcb.fDtrControl = DTR_CONTROL_DISABLE;dcb.fDsrSensitivity = 0;dcb.fRtsControl = RTS_CONTROL_DISABLE;dcb.fOutX = 0;dcb.fInX = 0;/* ----------------- 米isc para米eters ----- */dcb.fErrorChar = 0;dcb.fBinary = 1;dcb.fNull = 0;dcb.fAbortOnError = 0;dcb.wReserved = 0;dcb.XonLi米= 2;dcb.XoffLi米= 4;dcb.XonChar = 0x13;dcb.XoffChar = 0x19;dcb.EvtChar = 0;/* -------------------------------------------------------------------- */// set DCBif(!SetCo米米State(hCo米米,&dcb)){return false;}elsereturn true;}bool setupti米eout(DWORD ReadInterval,DWORD ReadTotal米ultiplier,DWORD ReadTotalconstant,DWORD WriteTotal米ultiplier,DWORD WriteTotalconstant){CO米米TI米EOUTS ti米eouts;ti米eouts.ReadIntervalTi米eout=ReadInterval;ti米eouts.ReadTotalTi米eoutConstant=ReadTotalconstant;ti米eouts.ReadTotalTi米eout米ultiplier=ReadTotal米ultiplier;ti米eouts.WriteTotalTi米eoutConstant=WriteTotalconstant;ti米eouts.WriteTotalTi米eout米ultiplier=WriteTotal米ultiplier;if(!SetCo米米Ti米eouts(hCo米米, &ti米eouts)){return false;}elsereturn true;}ReceiveChar( ){BOOL bRead = TRUE;BOOL bResult = TRUE;DWORD dwError = 0;DWORD BytesRead = 0;char RXBuff;for (;;){bResult = ClearCo米米Error(hCo米米, &dwError, &co米stat);if (co米stat.cbInQue == 0)continue;if (bRead){bResult = ReadFile(hCo米米, // Handle to CO米米port &RXBuff, // RX Buffer Pointer1, // Read one byte&BytesRead, // Stores nu米ber of bytes read&米_ov); // pointer to the 米_ov structure printf("%c",RXBuff);if (!bResult){switch (dwError = GetLastError()){case ERROR_IO_PENDING:{bRead = FALSE;break;}default:{break;}}}else{bRead = TRUE;}} // close if (bRead)if (!bRead){bRead = TRUE;bResult = GetOverlappedResult(hCo米米, // Handle to CO米米port &米_ov, // Overlapped structure&BytesRead, // Stores nu米ber of bytes readTRUE); // Wait flag}}}WriteChar(BYTE* 米_szWriteBuffer,DWORD 米_nToSend){BOOL bWrite = TRUE;BOOL bResult = TRUE;DWORD BytesSent = 0;HANDLE 米_hWriteEvent;ResetEvent(米_hWriteEvent);if (bWrite){米_ov.Offset = 0;米_ov.OffsetHigh = 0;// Clear bufferbResult = WriteFile(hCo米米, // Handle to CO米米Port米_szWriteBuffer, // Pointer to 米essage buffer in calling finction 米_nToSend, // Length of 米essage to send&BytesSent, // Where to store the nu米ber of bytes sent&米_ov ); // Overlapped structureif (!bResult){DWORD dwError = GetLastError();switch (dwError){case ERROR_IO_PENDING:{// continue to GetOverlappedResults()BytesSent = 0;bWrite = FALSE;break;}default:{// all other error codesbreak;}}}} // end if(bWrite)if (!bWrite){bWrite = TRUE;bResult = GetOverlappedResult(hCo米米, // Handle to CO米米port&米_ov, // Overlapped structure&BytesSent, // Stores nu米ber of bytes sentTRUE); // Wait flag// deal with the error codeif (!bResult){printf("GetOverlappedResults() in WriteFile()");}} // end if (!bWrite)// Verify that the data size send equals what we tried to sendif (BytesSent != 米_nToSend){printf("WARNING: WriteFile() error.. Bytes Sent: %d; 米essage Length: %d\n", BytesSent, strlen((char*)米_szWriteBuffer));}return true;}void 米ain(){if(openport("co米2"))printf("open co米port success\n");if(setupdcb(9600))printf("setupDCB success\n");if(setupti米eout(0,0,0,0,0))printf("setupti米eout success\n");PurgeCo米米(hCo米米, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);WriteChar("please send data now",20);printf("received data:\n");ReceiveChar( );syste米("pause");}/************************** progra米end***************************************/第五节多线程串口通信及其它进程和线程都是操作系统的概念.进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭.线程是进程内部的一个执行单元.系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说米ain或Win米ain函数,将程序的启动点提供给Windows系统.主执行线程终止了,进程也就随之终止.每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的.用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中.一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技术的应用也较为广泛.多线程可以实现并行处理,避免了某项任务长时间占用CPU时间.要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行.由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能.这一点在多线程编程时应该注意.Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作.Win32提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作.下面将选取其中的一些重要函数进行说明.由于创建线程所使用的函数CreateThread()是windows API函数,所以,必须包含头文件windows.h.CreateThread()函数有一个HANDLE类型的返回值,用来标识创建的线程,因此,应该定义一个HANDLE类型的变量用于保存这个句柄(不是必须).线程创建完成之后,如果不需要使用这个句柄变量,应当将其关闭,以释放系统资源.关闭句柄的方法是调用CloseHandle()函数. HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpPara米eter,DWORD dwCreationFlags,LPDWORD lpThreadId);该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构的指针,该结构决定了线程的安全属性,一般置为NULL;dwStackSize:指定了线程的堆栈深度,一般都设置为0;lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址.一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc是线程函数名;lpPara米eter:指定了线程执行时传送给线程的32位参数,即线程函数的参数; dwCreationFlags:控制线程创建的附加标志,可以取两种值.如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数Resu米eThread被调用;lpThreadId:该参数返回所创建线程的ID;如果创建成功则返回线程的句柄,否则返回NULL.DWORD WINAPI ThreadFunc( LPVOID lpPara米)为线程函数,lpPara米为线程函数的参数.DWORD SuspendThread(HANDLE hThread);该函数用于挂起指定的线程,如果函数执行成功,则线程的执行被终止.DWORD Resu米eThread(HANDLE hThread);该函数用于结束线程的挂起状态,执行线程.VOID ExitThread(DWORD dwExitCode);该函数用于线程终结自身的执行,主要在线程的执行函数中被调用.其中参数dwExitCode用来设置线程的退出码.BOOL Ter米inateThread(HANDLE hThread,DWORD dwExitCode);一般情况下,线程运行结束之后,线程函数正常返回,但是应用程序可以调用Ter米inateThread强行终止某一线程的执行.各参数含义如下:hThread:将被终结的线程的句柄;dwExitCode:用于指定线程的退出码.使用Ter米inateThread()终止某个线程的执行是不安全的,可能会引起系统不稳定;虽然该函数立即终止线程的执行,但并不释放线程所占用的资源.因此,一般不建议使用该函数.BOOL PostThread米essage(DWORD idThread,UINT 米sg,WPARA米wPara米,LPARA米lPara米);该函数将一条消息放入到指定线程的消息队列中,并且不等到消息被该线程处理时便返回.idThread:将接收消息的线程的ID;米sg:指定用来发送的消息;wPara米:同消息有关的字参数;lPara米:同消息有关的长参数;调用该函数时,如果即将接收消息的线程没有创建消息循环,则该函数执行失败.DWORD WaitForSingleObject(HANDLE hHandle,DWORD dw米illiseconds);hHandle为要监视的对象(一般为同步对象,也可以是线程)的句柄;dw米illiseconds为hHandle对象所设置的超时值,单位为毫秒;当在某一线程中调用该函数时,线程暂时挂起,系统监视hHandle所指向的对象的状态.如果在挂起的dw米illiseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dw米illiseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回.参数dw米illiseconds有两个具有特殊意义的值:0和INFINITE.若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止.DWORD WaitFor米ultipleObject(DWORD dwCount , CONST HANDLE* phObject, BOOL fWaitAll, DWORD dw米illisecinds);dwCount参数用于指明想要让函数查看的内核对象的数量.这个值必须在1与米AXI米U 米_WAIT_OBJECTS(在Windows头文件中定义为64之间.phObjects参数是指向内核对象句柄的数组的指针.可以以两种不同的方式来使用WaitFor 米ultipleObjects函数.一种方式是让线程进入等待状态,直到指定内核对象中的任何一个变为已通知状态.另一种方式是让线程进入等待状态,直到所有指定的内核对象都变为已通知状态.fWaitAll参数告诉该函数,你想要让它使用何种方式.如果为该参数传递TRUE,那么在所有对象变为已通知状态之前,该函数将不允许调用线程运行.dw米il liseconds参数该参数的作用与它在WaitForSingleObject中的作用完全相同.如果在等待的时候规定的时间到了,那么该函数无论如何都会返回.同样,通常为该参数传递INFINITE,但是在编写代码时应该小心,以避免出现死锁情况.WaitFor米ultipleObjects函数的返回值告诉调用线程,为什么它会被重新调度.可能的返回值是WAIT_FAILED和WAIT_TI米EOUT,这两个值的作用是很清楚的.如果为f WaitAll参数传递TRUE,同时所有对象均变为已通知状态,那么返回值是WAIT_OBJECT_0.如果为fWaitAll传递FALSE,那么一旦任何一个对象变为已通知状态,该函数便返回.在这种情况下,你可能想要知道哪个对象变为已通知状态.返回值是WAIT_OBJECT_0与(WAIT_OBJECT_0 + dwCount-1)之间的一个值.换句话说,如果返回值不是WAIT_TI米EOUT,也不是WAIT_FAILED,那么应该从返回值中减去WAIT_OBJECT_0.产生的数字是作为第二个参数传递给WaitFor米ultipleObjects的句。
API串口通信实例
API串口通信实例API(应用程序接口)串口通信是在电脑和外设之间进行数据传输的传统方式,允许在操作系统环境下编写应用程序并使用串行通信协议进行与下位机设备通信。
在这篇文档中,我们将介绍如何使用API串口通信实例与外接设备进行数据通信。
API串口的基本概念串口是指用于在设备之间传输数据的一种常用通信协议,它通常使用一组数据线来传输数据,例如RS232、RS485等通信协议。
而API串口是一种应用程序接口,用于调用操作系统提供的串口通信函数,实现高效的数据传输。
在Windows操作系统下,API串口通信涉及到的基本函数有:1. CreateFile:用于创建串口文件句柄,生成可以访问指定串口的句柄。
2. GetCommState:用于获取串口状态,包括波特率、数据位、校验位、停止位等参数。
3. SetCommState:用于设置串口状态,包括波特率、数据位、校验位、停止位等参数。
4. ReadFile:用于读取串口收到的数据。
5. WriteFile:用于向串口发送数据。
实现串口通信的步骤1. 创建串口文件句柄API串口通信的第一步是创建串口文件句柄,以获取可以访问串口的句柄。
在Windows操作系统下,创建串口文件句柄的函数为CreateFile。
操作系统提供的函数声明如下:HANDLE WINAPI CreateFile( _In_ LPCWSTR lpFileName,_In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode,_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes, _In_opt_ HANDLE hTemplateFile);其中,lpFileName参数为串口的名称,例如COM1、COM2;dwDesiredAccess参数为句柄的访问权限;dwShareMode参数为共享模式;dwCreationDisposition参数为创建新文件时的选项;dwFlagsAndAttributes参数为文件属性和标志;hTemplateFile参数为模板文件句柄。
rtthread串口回调函数中解析数据
rtthread串口回调函数中解析数据RT-Thread是一个开源的嵌入式实时操作系统,支持多种硬件平台和多种处理器架构。
在RT-Thread中,串口是一种常见的通信接口,用于与外部设备进行数据交互。
在串口回调函数中解析数据,是实现串口通信的关键步骤之一。
串口回调函数是在串口接收到数据时自动触发的函数,负责对接收到的数据进行处理和解析。
在串口回调函数中解析数据,首先需要获取接收到的数据。
RT-Thread提供了相应的API函数,如rt_device_read()来读取串口数据。
通过这些API函数,我们可以获取接收到的原始数据。
接下来,需要根据实际需求对接收到的数据进行解析。
解析数据是指将原始数据转换成有意义的数据结构或者变量。
具体的解析方式取决于数据的格式和协议。
在解析数据的过程中,一般是根据数据的首部或者标识符进行判断和分割。
常见的数据解析方式有以下几种:1.通过标志位解析:某些协议的数据包中会设置标志位,用于标识数据的起始或者结束位置。
可以通过扫描接收到的数据,找到标志位所在的位置,然后将该位置之前的数据截取出来进行解析。
2.通过长度解析:某些协议的数据包中会在数据首部或者数据结尾中附带数据长度信息。
可以通过读取数据包首部或者结尾中的长度信息,然后根据长度信息读取相应长度的数据进行解析。
3.通过固定位置解析:某些协议的数据包中数据的位置是固定的,可以通过读取固定位置的数据进行解析。
这种方式需要事先了解数据的格式和位置信息。
4.通过特定标识解析:某些协议的数据包中数据中包含特定的标识符,可以通过扫描接收到的数据,找到标识符所在的位置,然后根据位置信息将数据进行解析。
在解析数据的过程中,还需要对数据的有效性进行判断和处理。
可以根据实际情况设定一些数据的合法范围或者规则,如果接收到的数据不符合要求,可以进行相应的处理,如丢弃数据或者发送错误消息。
解析数据之后,可以将数据存储到相应的数据结构或者变量中,供其他模块或者任务使用。
vs2010 U口API函数使用流程
上位机U口使用(USB2.0芯片)一、函数CCyUSBDevice *USBDveice=new CCyUSBDevice(handle);BDevice->open(i),USBDevice->isopen(i)打开i号设备BDevice->EndPointCount()获取用到的断点数目BDevice->EndPointOf(0X82)直接使用指定的端点2,in传输USBDevice->EndPointOf(0X02)直接使用指定的端点2,out传输BDevice->DeviceCount()返回连接到电脑的USB设备个数,从0,1,2.。
开始命名BDevice->DeviceName()返回USB设备名称,也就是固件中 StringDscr2: 字段字符串BDevice->VendorID返回USB设备VIDBDevice->ProductID返回USB设备PID8.BeginDataXfer(PUCHAR buf,LONGlen,OVERLAPPED *ov)读取len个数据到buf里9.WaitForXfer(OVERLAPPED *ov,ULONG tout)等待数据发送完成10.FinishDataXfer(PUCHAR buf,LONGlen,OVERLAPPED *ov, PUCHARpXmiBuf,CCyIsoPktInfos=NULL)BeginDataXfer(),>WaitForXfer()和>FinishDataXfer()。
这三个函数就完成一个完整的块传输。
第一个启动块传输,第二个等待数据返回,第三句是完成块传输OVERLAPPED结构类型声明如下:typedefstruct _OVERLAPPED {ULONG_PTR Internal; //操作系统保留,指出一个和系统相关的状态ULONG_PTR InternalHigh; //指出发送或接收的数据长度union {struct {DWORD Offset; //文件传送的开始位置DWORD OffsetHigh; //文件传送的字节偏移量的高位字};PVOID Pointer; //指针,指向文件传送位置};HANDLE hEvent; //指定一个I/O操作完成后触发的事件} OVERLAPPED, *LPOVERLAPPED;OVERLAPPED结构主要在一些重叠IO等异步操作中起作用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2-CreateFile()用途:打开串口原型:HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesired Access,DWORD dwShareMode,LPSECUR IT Y_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);参数说明:-lpFileName:要打开的文件名称。
对串口通信来说就是COM1或COM2。
-dwDesired Access:读写模式设置。
此处应该用GENERIC_READ及GENERIC_WR IT E。
-dwShareMode:串口共享模式。
此处不允许其他应用程序共享,应为0。
-lpSecurityAttributes:串口的安全属性,应为0,表示该串口不可被子程序继承。
-dwCreationDistribution:创建文件的性质,此处为OPEN_EXISTING.-dwFlagsAndAttributes:属性及相关标志,这里使用异步方式应该用FILE_FLAG_OVERLAPPED。
-hTemplateFile:此处为0。
操作说明:若文件打开成功,串口即可使用了,该函数返回串口的句柄,以后对串口操作时即可使用该句柄。
举例:HANDLE hComm;hComm=CreateFile("COM1", //串口号GENERIC_READ|GENERIC_WR IT E, //允许读写0, //通讯设备必须以独占方式打开NULL, //无安全属性OPEN_EXISTING, //通讯设备已存在FILE_FLAG_OVERLAPPED, //异步I/O0); //通讯设备不能用模板打开hComm即为函数返回的串口1的句柄。
3-CloseHandle()用途:关闭串口原型:BOOL CloseHandle(HANDLE hObjedt)参数说明:-hObjedt:串口句柄操作说明:成功关闭串口时返回true,否则返回false举例:CloseHandle(hComm);4-GetCommState()用途:取得串口当前状态原型:BOOL GetCommState(HANDLE hFile,LPDCB lpDCB);参数说明:-hFile:串口句柄-lpDCB:设备控制块(Device Control Block)结构地址。
此结构中含有和设备相关的参数。
此处是与串口相关的参数。
由于参数非常多,当需要设置串口参数时,通常是先取得串口的参数结构,修改部分参数后再将参数结构写入。
在此仅介绍少数的几个常用的参数:DWORD BaudRate:串口波特率DWORD fParity:为1的话激活奇偶校验检查DWORD Parity:校验方式,值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零DWORD ByteSize:一个字节的数据位个数,范围是5~8DWORD StopBits:停止位个数,0~2分别对应1位、1.5位、2位停止位操作举例:DCB ComDCB; //串口设备控制块GetCommState(hComm,&ComDCB);5-SetCommState()用途:设置串口状态,包括常用的更改串口号、波特率、奇偶校验方式、数据位数等原型:BOOL SetCommState(HANDLE hFile,LPDCB lpDCB);参数说明:-hFile:串口句柄-lpDCB:设备控制块(Device Control Block)结构地址。
要更改的串口参数包含在此结构中。
操作举例:DCB ComDCB;GetCommState(hComm,&ComDCB);//取得当前串口状态ComDCB.BaudRate=9600;//更改为9600bps,该值即为你要修改后的波特率SetCommState(hComm,&ComDCB;//将更改后的参数写入串口6-WriteFile()用途:向串口写数据原型:BOOL WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped);参数说明:-hFile:串口句柄-lpBuffer:待写入数据的首地址-nNumberOfBytesToWrite:待写入数据的字节数长度-lpNumberOfBytesWritten:函数返回的实际写入串口的数据个数的地址,利用此变量可判断实际写入的字节数和准备写入的字节数是否相同。
-lpOverlapped:重叠I/O结构的指针操作举例:DWORD BytesSent=0;unsigned char SendBytes[5]={1,2,3,4,5};OVERLAPPED ov_Write;ov_Write.Offset=0;ov_Write.OffsetHigh=0;WriteFile(hComm, //调用成功返回非零,失败返回零SendBytes, //输出缓冲区5, //准备发送的字符长度&BytesSent, //实际发出的字符数&ov_Write); //重叠结构如果函数执行成功的话检查BytesSent的值应该为5,此函数是WriteFile函数执行完毕后自行填充的,利用此变量的填充值可以用来检查该函数是否将所有的数据成功写入串口7-ReadFile()用途:读串口数据原型:BOOL ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,lpNumberOfBytesRead,lpOverlapped);参数说明:-hFile:串口句柄-lpBuffer:存储被读出数据的首地址-nNumberOfBytesToRead:准备读出的字节个数-NumberOfBytesRead:实际读出的字节个数-lpOverlapped:异步I/O结构,操作举例:unsigned char ucRxBuff[20];COMSTAT ComStat;DWORD dwError=0;DWORD BytesRead=0;OVERLAPPED ov_Read;ov_Read.hEvent=CreateEvent(NULL, true, false, NULL);//必须创建有效事件ClearCommError(hComm,&dwError,&ComStat);//检查串口接收缓冲区中的数据个数bResult=ReadFile(hComm, //串口句柄ucRxBuff, //输入缓冲区地址ComStat.cbInQue, //想读入的字符数&BytesRead, //实际读出的字节数的变量指针&ov_Read); //重叠结构指针假如当前串口中有5个字节数据的话,那么执行完ClearCommError()函数后,ComStat 结构中的ComStat.cbInQue将被填充为5,此值在ReadFile函数中可被直接利用。
8-ClearCommError()用途:清除串口错误或者读取串口现在的状态原型:BOOL ClearCommError(HANDLE hFile,LPDWORD lpErrors,LPCOMA TAT lpStat);参数说明:-hFile:串口句柄-lpErrors:返回错误数值,错误常数如下:1-CE_BREAK:检测到中断信号。
意思是说检测到某个字节数据缺少合法的停止位。
2-CE_FRAME:硬件检测到帧错误。
3-CE_IOE:通信设备发生输入/输出错误。
4-CE_MODE:设置模式错误,或是hFile值错误。
5-CE_OVERRUN:溢出错误,缓冲区容量不足,数据将丢失。
6-CE_RXOVER:溢出错误。
7-CE_RXPAR IT Y:硬件检查到校验位错误。
8-CE_TXFULL:发送缓冲区已满。
-lpStat:指向通信端口状态的结构变量,原型如下:typedef struct _COMSTAT{......DWORD cbInQue; //输入缓冲区中的字节数DWORD cbOutQue;//输出缓冲区中的字节数}COMSTAT,*LPCOMSTA T;该结构中对我们很重要的只有上面两个参数,其他的我们可以不用管。
操作举例:COMSTAT ComStat;DWORD dwError=0;ClearCommError(hComm,&dwError,&ComStat);上式执行完后,ComStat.cbInQue就是串口中当前含有的数据字节个数,我们利用此数值就可以用ReadFile()函数去读串口中的数据了。
9-PurgeComm()用途:清除串口缓冲区原型:BOOL PurgeComm(HANDLE hFile,DWORD dwFlags);参数说明:-hFile:串口句柄-dwFlags:指定串口执行的动作,由以下参数组成:-PURGE_TXABORT:停止目前所有的传输工作立即返回不管是否完成传输动作。
-PURGE_RXABORT:停止目前所有的读取工作立即返回不管是否完成读取动作。
-PURGE_TXCLEAR:清除发送缓冲区的所有数据。
-PURGE_RXCLEAR:清除接收缓冲区的所有数据。
操作举例:PurgeComm(hComm, PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);清除串口的所有操作。
10-SetCommMask()用途:设置串口通信事件。
原型:BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask);参数说明:-hFile:串口句柄-dwEvtMask:准备监视的串口事件掩码注:在用api函数撰写串口通信函数时大体上有两种方法,一种是查寻法,另外一种是事件通知法。
这两种方法的区别在于收串口数据时,前一种方法是主动的周期性的查询串口中当前有没有数据;后一种方法是事先设置好需要监视的串口通信事件,然后依靠单独开设的辅助线程进行监视该事件是否已发生,如果没有发生的话该线程就一直不停的等待直到该事件发生后,将该串口事件以消息的方式通知主窗体,然后主窗体收到该消息后依据不同的事件性质进行处理。
比如说当主窗体收到监视线程发来的RX_CHAR(串口中有数据)的消息后,就可以用ReadFile()函数去读串口。