Lazarus实战开发之串口通信(WINCE-WIN32)

合集下载

WIN32 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。

Wince串口通信

Wince串口通信
ltancy Service
串口通信函数介绍
设置接收和发送缓冲区的大小: 设置接收和发送缓冲区的大小: 利用函数SetupComm来设置接收和发送数据的缓 利用函数 来设置接收和发送数据的缓 冲区的大小.这个函数不推荐使用, 冲区的大小.这个函数不推荐使用,系统会推荐一个 合适的默认值. 合适的默认值. 清空串口缓冲区: 清空串口缓冲区: 利用函数PurgeComm来清空串口的发送缓冲区和 利用函数 来清空串口的发送缓冲区和 接收缓冲区. 接收缓冲区. 清除错误并查询状态: 清除错误并查询状态: 中利用ClearCommError函数清除驱动 在WINCE中利用 中利用 函数清除驱动 程序产生的任何错误状态并返回当前窗口状态. 程序产生的任何错误状态并返回当前窗口状态.
Softeem Consultancy Service
串口通信函数介绍
打开关闭串口: 打开关闭串口: 函数中可以通过CreateFile函数打开串口,利用这个 函数打开串口, 在WINCE函数中可以通过 函数中可以通过 函数打开串口 函数打开窗口需要注意的是在串口名之后必须加一个冒号(:), 函数打开窗口需要注意的是在串口名之后必须加一个冒号 ,在 参数中要注意设置共享参数为独占方式( ), ),安全参数和模板 参数中要注意设置共享参数为独占方式(0),安全参数和模板 文件参数也必须被设置成NULL. 文件参数也必须被设置成 当使用完串口后要注意使用CloseHandle函数来关闭串口. 函数来关闭串口. 当使用完串口后要注意使用 函数来关闭串口 配置串口: 配置串口: 在使用串口时,还必须配置好串口的波特率, 在使用串口时,还必须配置好串口的波特率,奇偶检验和数据 位等, 提供了 提供了GetCommState和SetCommState函数分别获 位等,CE提供了 和 函数分别获 取串口的当前参数和设置串口的参数. 取串口的当前参数和设置串口的参数. 读写串口: 读写串口: 程序中使用ReadFile和WriteFile函数读取串口数据和向串口 程序中使用 和 函数读取串口数据和向串口 中写入数据.由于串口读写数据的速度比较慢, 中写入数据.由于串口读写数据的速度比较慢,所以不要在主线 程中读写大量数据, 程中读写大量数据,所以最好的方法是用单独的线程来读写数据

win32串口通信c语言

win32串口通信c语言

w i n 32串口通信c 语言标标题题::W W i i n n 3322下下使使用用C C 语语言言进进行行串串口口通通信信导导言言::串串口口通通信信在在嵌嵌入入式式系系统统和和物物联联网网应应用用中中扮扮演演着着重重要要角角色色。

本本文文将将介介绍绍如如何何使使用用C C 语语言言在在W W i i n n 3322平平台台下下进进行行串串口口通通信信的的基基本本操操作作和和流流程程,,涵涵盖盖串串口口的的初初始始化化、、数数据据读读写写以以及及错错误误处处理理等等方方面面的的内内容容。

#### 11.. 环环境境准准备备在在进进行行串串口口通通信信前前,,需需要要使使用用相相应应的的开开发发环环境境和和工工具具。

以以下下是是环环境境搭搭建建的的基基本本步步骤骤::-- 安安装装合合适适的的C C 编编译译器器,,如如M M i i n n G G W W 或或者者D D e e v v --C C ++++。

-- 确确保保系系统统中中包包含含``w w i i n n d d o o w w s s ..h h ``头头文文件件,,该该头头文文件件包包含含了了W W i i n n 3322 A A P P I I 的的定定义义。

#### 22.. 串串口口初初始始化化在在进进行行串串口口通通信信前前,,需需要要对对串串口口进进行行初初始始化化设设置置,,包包括括波波特特率率、、数数据据位位、、停停止止位位和和校校验验位位等等参参数数的的配配置置。

下下面面是是一一个个简简单单的的串串口口初初始始化化函函数数示示例例::``````c c##i i n n c c l l u u d d e e <<w w i i n n d d o o w w s s ..h h >>H H A A N N D D L L E E S S e e r r i i a a l l I I n n i i t t ((i i n n t t p p o o r r t t ,, i i n n t t b b a a u u d d r r a a t t e e )){{H H A A N N D D L L E E h h S S e e r r i i a a l l ;;D D C C B B d d c c b b S S e e r r i i a a l l P P a a r r a a m m s s == {{00}};;//// 打打开开串串口口c c h h a a r r p p o o r r t t N N a a m m e e [[1100]];;s s p p r r i i n n t t f f ((p p o o r r t t N N a a m m e e ,, ""C C O O M M %%d d "",, p p o o r r t t ));;h h S S e e r r i i a a l l == C C r r e e a a t t e e F F i i l l e e ((p p o o r r t t N N a a m m e e ,, G G E E N N E E R R I I C C __R R E E A A D D || G G E E N N E E R R I I C C __W W R R I I T T E E ,, 00,, N N U U L L L L ,, O O P P E E N N __E E X X I I S S T T I I N N G G ,,F F I I L L E E __A A T T T T R R I I B B U U T T E E __N N O O R R M M A A L L ,, N N U U L L L L ));;i i f f ((h h S S e e r r i i a a l l ==== I I N N V V A A L L I I D D __H H A A N N D D L L E E __V V A A L L U U E E )) {{p p r r i i n n t t f f ((""无无法法打打开开串串口口!!\\n n ""));;r r e e t t u u r r n n I I N N V V A A L L I I D D __H H A A N N D D L L E E __V V A A L L U U E E ;;}}//// 配配置置串串口口参参数数d d c c b b S Se e r r i i a a l l P P a a r r a a m m s s ..D D C C B B l l e e n n g g t t h h ==s s i i z z e e o o f f ((d d c c b b S S e e r r i i a a l l P P a a r r a a m m s s ));;i i f f ((!!G G e e t t C C o o m m m m S S t t a a t t e e ((h h S S e e r r i i a a l l ,, &&d d c c b b S S e e r r i i a a l l P P a a r r a a m m s s )))) {{p p r r i i n n t t f f ((""无无法法获获取取串串口口参参数数!!\\n n ""));;C C l l o o s s e e H H a a n n d d l l e e ((h h S S e e r r i i a a l l ));;r r e e t t u u r r n n I I N N V V A A L L I I D D __H H A A N N D D L L E E __V V A A L L U U E E ;;}}d d c c b b S Se e r r i i a a l l P P a a r r a a m m s s ..B B a a u u d d R R a a t t e e == b b a a u u d d r r a a t t e e ;;d d c c b b S Se e r r i i a a l l P P a a r r a a m m s s ..B B y y t t e e S S i i z z e e == 88;;d d c c b b S Se e r r i i a a l l P P a a r r a a m m s s ..S S t t o o p p B B i i t t s s == O O N N E E S S T T O O P P B B I I T T ;;d d c c b b S Se e r r i i a a l l P P a a r r a a m m s s ..P P a a r r i i t t y y == N N O O P P A A R R I I T T Y Y ;;i i f f ((!!S S e e t t C C o o m m m m S S t t a a t t e e ((h h S S e e r r i i a a l l ,, &&d d c c b b S S e e r r i i a a l l P P a a r r a a m m s s )))) {{ p p r r i i n n t t f f ((""无无法法设设置置串串口口参参数数!!\\n n ""));;C C l l o o s s e e H H a a n n d d l l e e ((h h S S e e r r i i a a l l ));;r r e e t t u u r r n n I I N N V V A A L L I I D D __H H A A N N D D L L E E __V V A A L L U U E E ;;}}r r e e t t u u r r n n h h S S e e r r i i a a l l ;;}}``````#### 33.. 数数据据读读写写完完成成串串口口的的初初始始化化后后,,可可以以进进行行串串口口数数据据的的读读写写操操作作。

win32API串口通信

win32API串口通信

WIN32API--串口通信[源码]serial.cpp vc++6.0#include<stdio.h>#include<stdlib.h>#include<windows.h>HANDLE 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字段含有串口波特率、数据位数、停止位和奇偶校验控制等信息。

手把手教你labview串口通信

手把手教你labview串口通信

我也是一个labview的初学者,这个例子介绍了一个最最简单的串口通信的上位机的例子.单片机不竭向串口发送数据.上位机之显示串口发来的数据.之马矢奏春创作时间:二O二一年七月二十九日一.先在前面板添加一个VISA本钱名称添加上之后前面板会消掉在后面板会消掉一.在后面板添加一个串口设备的控件接下来对对串口设备控件进行设备1.“启用终止符”------------设备布尔型变量“T”,就是取真.2.“终止符”------------我们不合错误其进行设备,选择默认终止符——“\n”3.’’超时’----------为其设备10000的常量4.本钱名称与“VISA本钱名称“控件相连接5.波特率这里我们为其设备大小为“115200“的常量6.其余各项不进行设备,默认系统设置上图为设备完成的成果二.接下来创建一个平铺式机关2.在平铺式次序机关中添加一个延时控件3.把串口设备控件的“错误输出“端、VISA本钱名称输出端辨别连接在平铺式次序机关的两边上.并给延时控件设备大小为100的常量.如下图三. 1.创建一个前提机关控件2.在前提机关控件中添加一个VISA读取控件3.添加一个“VISA串口字节数“控件4.将VISA串口字节数“控件”的“错误输入“端与上一环节中引出的”暗示错误输出“的黄线连接.5.将VISA串口字节数“控件”的“引用”端与上一环节中引出的代表VISA本钱名称的线连接6.将VISA串口字节数“控件”的“错误输出“端与“VISA读取”控件的“错误输入”连接7.将VISA串口字节数“控件”的“引用输出“与“VISA读取”控件的“VISA本钱名称“的线连接.8.字节数设备常量4,读者可按照本身数据大小随便率性设备.四. 1.在前提机关外侧建立一个“VISA封锁“控件2.将VISA封锁“控件的错误输入、VISA本钱名称端辨别于“VISA读取”控件的对应端连接.3.建立一个简单单纯错误处理器,将其错误输入端与串口封锁控件的错误输出端连接,如图,3.选择天剑机关控件“假”4.添加一个“VISA串口字节数“控件,一个VISA读取控件“VISA串口字节数“控件引用输出端与VISA读取控件”VISA本钱名称”端连接“VISA串口字节数“控件错误输出端与VISA读取控件错误输入端连接“VISA串口字节数“控件“串口字节数”(英文)端与“VISA读取控件”的“字节总数”端连接VISA读取控件的“VISA本钱名称输出”与“VISA封锁“控件的本钱名称端连接VISA读取控件的错误输出端与“VISA封锁“控件的错误输入端连接5.在前面板创建一个开关控件在后面板中将开关空间连接到前提机关控件的前提判断接口6创建一个while轮回机关,如图红色的就是while轮回机关创建一个布尔型的变量“T”,连接到轮回前提处如图7.VISA读取控件的“读取缓存区”创建一个显示控件.六1.把单片机串口通信程序调好之后,是单片机运行,不竭向单片机中发送数据.打开前面板点击单次运行按钮,这时可能会报错,没紧要,点击中止.只是因为电脑还没辨认到硬件,中止几回单次运行之后会辨认到串口.如图2.这时点击中止运行,就可以接收数据了如图假如你的串口发送的信息收到乱码,请本身调节波特率,“VISA读取”的字节总数选项.你的程序成功了吗?时间:二O二一年七月二十九日。

wince串口

wince串口

WinCE中串口通讯的调试方法串口是嵌入式系统中应用很广的一种通讯接口。

在WinCE中,通常会有一个串口供调试使用,另外的串口可与外围设备连接,如GSM和GPS等模块,以获取相应的信息并进行处理。

在WinCE中,为了使用串口,必须有相应的串口驱动程序,一般在BSP 中都有实现。

串口驱动是典型的流驱动。

应用程序中可通过CreateFile()、ReadFile()和WriteFile()等文件系统的操作函数来访问串口,从而实现串口数据的收发。

虽然串口操作相对简单,但在实际调试时依然会碰到很多问题,譬如如何监视串口收发的数据。

在调试GSM模块时,如果WinCE不能正确控制模块,我们就需要确认是发送还是接收的问题,是模块还是开发板的问题。

在调试GPS模块时,经常需要监视GPS数据又不能影响固有GPS软件的运行。

这些都要求我们能内建虚拟串口,以将物理串口收到的数据分发到不同的虚拟串口上,相反,发送则是由不同的虚拟串口往物理串口转发的过程。

Serial Splitter Mobile就是这样一款专业软件,它能满足上述要求。

以前曾用它调试过一个串口设备。

当时用的是一个试用版,单次连接只能收发1M Bytes,超过1M就不工作了。

开始没在意,以为是串口驱动和自己软件的问题,后来发现是Serial Splitter试用版的限制。

调试手段引入的错误,是最让人郁闷的。

为了方便使用,今天到其官网下载了最新的版本,并破解之,去除了收发数据的限制和应用程序中的注册信息。

破解前的截图如下:破解后的截图如下:使用截图:该软件使用很方便,简单测试了一下,效果还是可以的,有需要的请到这里下载:/we-hjb/WINCE_SERIAL.rar,其中包括WinCE6.0下的Splitter Mobile破解版、WinCE串口调试助手和使用参考视频。

用Win32 API 实现串行通信

用Win32 API 实现串行通信

用Win32 API 实现串行通信南京航空航天大学牛新庄--------------------------------------------------------------------------------串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。

我们可以利用Windows API 提供的通信函数编写出高可移植性的串行通信程序。

在Win16中,可以利用OpenComm、CloseComm和WriteComm等函数打开、关闭和读写串口。

但在Win32中,串口和其他通信设备均被作为文件处理,串口的打开、关闭和读写等操作所用的API函数与操作文件的函数相同。

可通过CreateFile函数打开串口,通过CloseFile函数关闭串口,通过CommProp、DCB结构、GetCommProperties、SetCommProperties、GetCommState及SetCommState等函数设置串口状态,通过函数ReadFile和WritFile读写串口。

VC++ 6.0是Windows应用程序开发的主流语言之一,它具有良好的图形设计界面并支持面向对象的程序设计方法。

本文结合一个实例介绍在VC++ 6.0下如何利用Win32 API 实现串行通信程序。

实现原理本文的实例来自一个水泥发货系统,在系统中,需要将通过总量传感器采集到的仓重值传入到计算机中,以便系统做出相应的处理。

这需要使用串行通信来完成采集数据的传递工作。

对于串行通信设备,Win32 API支持同步和异步两种I/O操作。

同步操作方式的程序设计相对比较简单,但I/O操作函数在I/O操作结束前不能返回,这将挂起调用线程,直到I/O操作结束。

异步操作方式相对要复杂一些,但它可让耗时的I/O操作在后台进行,不会挂起调用线程,这在大数据量通信的情况下对改善调用线程的响应速度是相当有效的。

异步操作方式特别适合同时对多个串行设备进行I/O操作和同时对一个串行设备进行读/写操作。

使用Win32API实现Windows下异步串口通讯

使用Win32API实现Windows下异步串口通讯

使用Win32API实现Windows下异步串口通讯关键词:Win32API串口通讯使用Win32API实现Windows下异步串口通讯(上)- -目录:1.异步非阻塞串口通讯的优点2.异步非阻塞串口通讯的基本原理3.异步非阻塞串口通讯的基础知识4.异步非阻塞串口通讯的实现步骤2005.01.05一,异步非阻塞串口通讯的优点读写串行口时,既可以同步执行,也可以重叠(异步)执行。

在同步执行时,函数直到操作完成后才返回。

这意味着在同步执行时线程会被阻塞,从而导致效率下降。

在重叠执行时,即使操作还未完成,调用的函数也会立即返回。

费时的I/O操作在后台进行,这样线程就可以干别的事情。

例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。

"重叠"一词的含义就在于此。

二,异步非阻塞串口通讯的基本原理首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;其次,为了保护系统对串口的初始设置,调用GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。

三,异步非阻塞串口通讯的基础知识下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()功能:打开串口设备函数原型HANDLE CreateFile(LPCTSTR lpFileName, // 串口名称字符串;如:"COM1" 或"COM2"DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRI TE,DWORD dwShareMode, // 共享模式;"必须"为0, 即不能共享LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULLDWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为OPEN_EXIST INGDWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/OHANDLE hTemplateFile // 临时文件的句柄,通常为NULL);说明:如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。

win32下的几种串口通信编程

win32下的几种串口通信编程

类别:技术文章来源:未知作者:冯传玉关键字:串口加入日期:2003-10-29今天阅读:1总共阅读:8918win32下的几种串口通信编程安徽合肥冯传玉---- 要完成串口通信, 在32位模式下, 一般说来有以下四种方法:---- 1. 以文件方式打开串口:---- 这里使用的是Win32 API 函数, 所以无论在BCB或VC下都可以实现. 具体的函数的意义可以参考Win32 API的帮助.这里有一个易于使用的BCB下的类, 可以方便的使用串口.---- 下面给出简要说明:---- (1) 应用CreateFile() 来初始化串口FhFileComm=CreateFile( FCommName.c_str(),GENERIC_READ | GENERIC_WRITE,0, // exclusive access&lpSecurity,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // overlapped I/ONULL );if( FhFileComm == INVALID_HANDLE_VALUE)return false;(2) 应用WriteFile() 和ReadFile() 从串口读写数据bool MyComm::WriteBuffer(unsigned char*buffer,unsigned long length){return WriteFile(FhFileComm,buffer,length,&length,&FgOverLapped);}bool MyComm::ReadBuffer(unsigned char*buffer,unsigned long length){return ReadFile(FhFileComm,buffer,length,&length,&FgOverLapped);}相应的源文件为UsageComm.cpp UsageComm.h---- 2. 使用现成的控件:---- 易于使用的是微软的MS Communication 控件, 它是做为一个.ocx 提供的.---- 在BCB 中可以用Import ActiveX Control 将它加入到BCB 中, 缺省是加载在ActiveX 页中. 就可以作为一个普通的BCB 控件来使用了.(也有不少第三方提供的其它硬件操作控件)---- 3. 直接嵌入汇编法:---- (该方法不能在NT下使用, 由于98的非完全保护,下面的代码可以使用)利用BCB的直接嵌入汇编功能, 可以在BCB中直接对串口操作.---- 如下所示,在BCB中使用汇编代码如下byte __fastcall ReadByte(WORD Address)// eax :address{asm{mov DX,AXin AL,DX}}void __fastcall WriteByte(unsigned char byte, WORD Address)// EAX: BYTE EDX: ADDRESS{asm{out DX,AL}---- 这里必须用__fastcall 调用约定以使在调用该函数时用寄存器传递参数.---- (用在BCB中的汇编指令代码in 和out必须用小写,(其余可以为大写)寄存器名称大小写都可以) ---- 其它的如写多个字节,读多个字节, 同样可以实现.---- 4. 最困难的要数用VxD来实现:---- 这不是一下子能说得清的, 如果要做, 当然要找本书了.。

【免费下载】WIN32 API串口通信编程实例教程

【免费下载】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的时候请注意它的参数。

Windows 32 API在串口通信中的应用

Windows 32 API在串口通信中的应用
杨 洁
( 坊 学 院 , 山东 潍
潍坊
2 16 ) 6 0 1

要 :本 文分析 了Wi o s n w 环境 下 串行通信 的编程技 术 ,并介绍 了在用v + d c +语 言编 写
P C机与单片机 串行通信程序 实现 ,提 出了在实际应用中提 高串行通信性能的方法。 关键词:V + ;Wi 2 P 函数;串行通信;单 片机 c+ n AI 3
维普资讯
第6 卷第4 期
20 0 6年 7月
潍坊学院学报
J u a f W e fn ie s o m l i a Un v ri o a
VO . No4 1 . 6
J1 0 6 u. 0 2
Widw 2 P 在 串E通信 中的应用 no S I 3A l
Mioo c s ̄公 一 的 V + 6 r J C + . 一 种 高级 编 程 语 数据景 的实时通信,大大提高 了通信 的效率,故 0是 言 ,其 基 础类 库 ( C 封 装 了Wi3AP 中 的标 奉程 序 采 用 此种 方 式 进 行 串 行通 信 ,至 于 通 信 的 MF ) n2 l 准通 信 函数 ,可 方 便 地 支 持 串 口通信 。 下面 就 结 可 靠性 可 以通过 软件 设 汁来 保证 。 合 实例 介 绍 在 Wi o 环 境 下 , 用VC + . : 3 串行通信程序 n ws d + 60编 与 . 串行通信 程序 的技 术及 方法 。
序处 理 。
数 、 消息 的集 合 ,它 可 以看 作 是 Wi o s系统 为 n w d 在其 下运 行 的各 种 丌 发 系 统 提供 的 丌放 式 通用 功
在Widws中 , 串行 通 信 有 两 种 T 作 方 式 : no

Win32串口编程(RS485)

Win32串口编程(RS485)

Win32串口编程作者:韩耀旭下载源代码在工业控制中,工控机(一般都基于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_ATTRIBUTESlpSecurityAttributes,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)、配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。

01 Win32 API串口通信编程

01 Win32 API串口通信编程

1、串口通信编程步骤a)打开串口b)配置串口c)读写串口d)关闭串口2、代码实例及解析a)打开串口Windows系统中对于文件的操作进行了扩充,无论是文件、通信设备、命名管道、磁盘和控制台,都是使用CreateFile函数打开或者创建。

打开串口的方式有两种——同步I/O方式打开、重叠I/O方式打开。

同步I/O方式,发出I/O操作请求的API函数将一直被阻塞,直到I/O操作完成后,才能继续向下执行,在采用多线程进行编程时,要注意避免线程被阻塞。

重叠I/O 方式,发出I/O操作请求,的API可以立即返回,系统在后台运行I/O操作,这样可以避免API函数被阻塞。

同步I/O方式打开HANDLE hCom;hCom = CreateFile(“COM1”, //串口名称GENERIC_READ | GENERIC_WRITE, //允许读写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建0, //同步方式NULL);if( hCom == (HANDLE)-1){MessageBox(“打开COM失败!”);return FALSE;}MessageBox(“打开COM成功!”);return TRUE;重叠I/O方式打开HANDLE hCom;hCom = CreateFile(“COM1”, //串口名称GENERIC_READ | GENERIC_WRITE, //允许读写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠I/O方式打开NULL);if( hCom == INVALID_HANDLE_VALUE){MessageBox(“打开COM失败!”);return FALSE;}MessageBox(“打开COM成功!”);return TRUE;b)配置串口串口打开后,还要进行相应的配置,这里主要讨论:DCB配置、I/O缓冲区设置、超时设置。

visualbasic串口通信及编程实例

visualbasic串口通信及编程实例

visualbasic串口通信及编程实例Visual Basic串口通信及编程实例在实际的工业控制、机器人控制、智能家居等领域中,使用串口通信是一种非常广泛的方式。

Visual Basic (VB) 是一种微软公司开发的高级编程语言,它不仅易于学习,而且拥有丰富的图形界面设计和数据处理功能。

在本篇文章中,我们将深入介绍如何使用VB实现串口通信。

1. 建立串口通信首先,我们需要在VB中创建一个新的窗口(Form),然后打开工具箱,从中拖拽出一个SerialPort(串口)控件。

在控件属性中,我们需要为其指定相关的参数,例如串口名称、波特率、数据位、停止位、校验位等。

通常情况下,这些参数需要根据硬件设备的配置来进行调整。

在VB中实现串口通信的核心部分是对于SerialPort控件的事件监控。

具体来讲,当SerialPort收到一个数据包时,它会触发一个DataReceived事件。

对于这个事件,我们可以在程序中编写回调函数进行处理。

例如:Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e AsSystem.IO.Ports.SerialDataReceivedEventArgs) HandlesSerialPort1.DataReceived'在这里实现对于数据包的解析和处理End Sub2. 数据读取和发送在SerialPort控件中,有几种方法可以实现数据的读取和发送。

下面我们将介绍其中两种方法:(1) ReadExisting这个方法可以从串口中读取所有现有的数据,例如:Dim data As String = SerialPort1.ReadExisting()(2) Write这个方法可以向串口发送数据,例如:SerialPort1.Write("Hello World")注意,这个函数只能发送字符串数据。

Lazarus实战开发之数据库SQLite(WIN32WINCE)

Lazarus实战开发之数据库SQLite(WIN32WINCE)

Lazarus实战开发之数据库SQLite(WIN32WINCE)本⽂来⾃/hellogv/SQLite是⼀个轻量级的嵌⼊式数据库,在PC上⼤可不⽤它,但是在WINCE上,他就起很⼤作⽤了(ACCESS在WINCE上停⽌升级,SQL CE⼜太庞⼤)。

在Lazarus for WIN32上使⽤SQLite1. 安装SQLite for WIN32: VC2005编译SQLite, /hellogv/archive/2008/05/06/2399700.aspx ,把编译后的sqlite3.dll放在Windows系统⽂件夹之下;也可以直接到 下载现有的sqlite3.dll。

2.3. 安装LAZARUS的SQLite控件:/lazarus/components/sqlite/sqlite3laz.lpk在WIN32编写好SQLite数据库程序,然后修改编译器,从⽽⽣成WINCE平台下的数据库程序,这样可以⼤⼤减少交叉编译~调试所浪费的时间!在Lazarus for WINCE上使⽤SQLite1. 编译得到SQLite3.dll for wince2.3. 先进LAZARUS Application⼯程,添加SQLITE3DATASET控件4.5. 您必须先设定项⽬的编译器属性,请点选选单项⽬: Project > Compiler options...,点选Path分页,并把LCL Widget改编为Wince;点选Code分页,并把target platform改变为arm-wince。

6.7. 编译时会提出Fatal: Can't find unit PropEdits used by registersqlite3 这样的错误,这时就需要修改/lazarus/components/sqlite/registersqlite3.pas的代码8.9. 把PropEdits,ComponentEditors,SqliteComponentEditor 注释掉; 把RegisterComponentEditor(TSqlite3Dataset,TSqliteEditor) ;RegisterPropertyEditor(TypeInfo(String),TSqlite3Dataset,'FileName',TFileNamePropertyEditor);注释掉10.11. 重新编译即可通过。

win32_API串口通讯详解

win32_API串口通讯详解

WIN32API串口通讯实例教程第一节实现串口通讯的函数及串口编程简介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的时候请注意它的参数。

Win32中的串口通讯详细介绍

Win32中的串口通讯详细介绍

Serial Communications in Win32Allen DenverMicrosoft Windows Developer SupportDecember 11, 1995Allen seldom eats breakfast, but if he had to pick a favorite, Win32 serial communications would be the top choice.Click to open or copy the files in the MTTTY sample application for this technical article. AbstractSerial communications in Microsoft® Win32® is significantly different from serial communications in 16-bit Microsoft Windows®. Those familiar with 16-bit serial communications functions will have to relearn many parts of the system to program serial communications properly. This article will help to accomplish this. Those unfamiliar with serial communications will find this article a helpful foundation for development efforts.This article assumes the reader is familiar with the fundamentals of multiple threading and synchronization in Win32. In addition, a basic familiarity of the Win32 heap functions is useful to fully comprehend the memory management methods used by the sample, MTTTY, included with this article. For more information regarding these functions, consult the Platform SDK documentation, the Microsoft Win32 SDK Knowledge Base, or the Microsoft Developer Network Library. Application programming interfaces (APIs) that control user interface features of windows and dialog boxes, though not discussed here, are useful to know in order to fully comprehend the sample provided with this article. Readers unfamiliar with general Windows programming practices should learn some of the fundamentals of general Windows programming before taking on serial communications. In other words, get your feet wet before diving in head first.IntroductionThe focus of this article is on application programming interfaces (APIs) and methods that are compatible with Microsoft® Windows NT® and Windows 95; therefore, APIs supported on both platforms are the only ones discussed. Windows 95 supports the Win32® Telephony API (TAPI) and Windows NT 3.x does not; therefore, this discussion will not include TAPI. TAPI does deserve mention, however, in that it very nicely implements modem interfacing and call controlling.A production application that works with modems and makes telephone calls should implement these features using the TAPI interface. This will allow seamless integration with the other TAPI-enabled applications that a user may have. Furthermore, this article does not discuss some of the configuration functions in Win32, such as GetCommProperties.The article is broken into the following sections: Opening a port, reading and writing (nonoverlapped and overlapped), serial status (events and errors), and serial settings (DCB, flow control, and communications time-outs).The sample included with this article, MTTTY: Multithreaded TTY, implements many of the features discussed here. It uses three threads in its implementation: a user interface thread that does memory management, a writer thread that controls all writing, and a reader/status thread that reads data and handles status changes on the port. The sample employs a few different data heaps for memory management. It also makes extensive use of synchronization methods to facilitate communication between threads.Opening a PortThe CreateFile function opens a communications port. There are two ways to call CreateFile to open the communications port: overlapped and nonoverlapped. The following is the proper way to open a communications resource for overlapped operation:HANDLE hComm;hComm = CreateFile( gszPort,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);if (hComm == INVALID_HANDLE_VALUE)// error opening port; abortRemoval of the FILE_FLAG_OVERLAPPED flag from the call to CreateFile specifies nonoverlapped operation. The next section discusses overlapped and nonoverlapped operations.The Platform SDK documentation states that when opening a communications port, the call to CreateFile has the following requirements:∙fdwShareMode must be zero. Communications ports cannot be shared in the same manner that files are shared. Applications using TAPI can use the TAPI functions to facilitate sharing resources between applications. For Win32 applications not using TAPI, handleinheritance or duplication is necessary to share the communications port. Handleduplication is beyond the scope of this article; please refer to the Platform SDK documentation for more information.∙fdwCreate must specify the OPEN_EXISTING flag.∙hTemplateFile parameter must be NULL.One thing to note about port names is that traditionally they have been COM1, COM2, COM3, or COM4. The Win32 API does not provide any mechanism for determining what ports exist on a system. Windows NT and Windows 95 keep track of installed ports differently from one another, so any one method would not be portable across all Win32 platforms. Some systems even have more ports than the traditional maximum of four. Hardware vendors and serial-device-driver writers are free to name the ports anything they like. For this reason, it is best that users have the ability to specify the port name they want to use. If a port does not exist, an error will occur (ERROR_FILE_NOT_FOUND) after attempting to open the port, and the user should be notified that the port isn’t available.Reading and WritingReading from and writing to communications ports in Win32 is very similar to file input/output (I/O) in Win32. In fact, the functions that accomplish file I/O are the same functions used for serial I/O. I/O in Win32 can be done either of two ways: overlapped or nonoverlapped. The Platform SDK documentation uses the terms asynchronous and synchronous to connote these types of I/O operations. This article, however, uses the terms overlapped and nonoverlapped.Nonoverlapped I/O is familiar to most developers because this is the traditional form of I/O, where an operation is requested and is assumed to be complete when the function returns. In the case of overlapped I/O, the system may return to the caller immediately even when an operation is not finished and will signal the caller when the operation completes. The program may use the time between the I/O request and it s completion to perform some “background” work.Reading and writing in Win32 is significantly different from reading and writing serial communications ports in 16-bit Windows. 16-bit Windows only has the ReadComm and WriteComm functions. Win32 reading and writing can involve many more functions and choices. These issues are discussed below.Nonoverlapped I/ONonoverlapped I/O is very straightforward, though it has limitations. An operation takes place while the calling thread is blocked. Once the operation is complete, the function returns and the thread can continue its work. This type of I/O is useful for multithreaded applications because while one thread is blocked on an I/O operation, other threads can still perform work. It is the responsibility of the application to serialize access to the port correctly. If one thread is blocked waiting for its I/O operation to complete, all other threads that subsequently call a communications API will be blocked until the original operation completes. For instance, if one thread were waiting for a ReadFile function to return, any other thread that issued a WriteFile function would be blocked.One of the many factors to consider when choosing between nonoverlapped and overlapped operations is portability. Overlapped operation is not a good choice because most operating systems do not support it. Most operating systems support some form of multithreading, however, so multithreaded nonoverlapped I/O may be the best choice for portability reasons.Overlapped I/OOverlapped I/O is not as straightforward as nonoverlapped I/O, but allows more flexibility and efficiency. A port open for overlapped operations allows multiple threads to do I/O operations at the same time and perform other work while the operations are pending. Furthermore, the behavior of overlapped operations allows a single thread to issue many different requests and do work in the background while the operations are pending.In both single-threaded and multithreaded applications, some synchronization must take place between issuing requests and processing the results. One thread will have to be blocked until the result of an operation is available. The advantage is that overlapped I/O allows a threadto do some work between the time of the request and its completion. If no work can be done, then the only case for overlapped I/O is that it allows for better user responsiveness.Overlapped I/O is the type of operation that the MTTTY sample uses. It creates a thread that is responsible for reading the port’s data and reading the port’s status. It also performs periodic background work. The program creates another thread exclusively for writing data out the port.Note Applications sometimes abuse multithreading systems by creating too many threads. Although using multiple threads can resolve many difficult problems, creating excessive threads is not the most efficient use of them in an application. Threads are less a strain on the system than processes but still require system resources such as CPU time and memory. An application that creates excessive threads may adversely affect the performance of the entire system. A better use of threads is to create a different request queue for each type of job and to have a worker thread issue an I/O request for each entry in the request queue. This method is used by the MTTTY sample provided with this article.An overlapped I/O operation has two parts: the creation of the operation and the detection of its completion. Creating the operation entails setting up an OVERLAPPED structure, creating a manual-reset event for synchronization, and calling the appropriate function (ReadFile or WriteFile). The I/O operation may or may not be completed immediately. It is an error for an application to assume that a request for an overlapped operation always yields an overlapped operation. If an operation is completed immediately, an application needs to be ready to continue processing normally. The second part of an overlapped operation is to detect its completion. Detecting completion of the operation involves waiting for the event handle, checking the overlapped result, and then handling the data. The reason that there is more work involved with an overlapped operation is that there are more points of failure. If a nonoverlapped operation fails, the function just returns an error-return result. If an overlapped operation fails, it can fail in the creation of the operation or while the operation is pending. You may also have a time-out of the operation or a time-out waiting for the signal that the operation is complete.ReadingThe ReadFile function issues a read operation. ReadFileEx also issues a read operation, but since it is not available on Windows 95, it is not discussed in this article. Here is a code snippet that details how to issue a read request. Notice that the function calls a function to process the data if the ReadFile returns TRUE. This is the same function called if the operation becomes overlapped. Note the fWaitingOnRead flag that is defined by the code; it indicates whether or not a read operation is overlapped. It is used to prevent the creation of a new read operation if one is outstanding.DWORD dwRead;BOOL fWaitingOnRead = FALSE;OVERLAPPED osReader = {0};// Create the overlapped event. Must be closed before exiting// to avoid a handle leak.osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (osReader.hEvent == NULL)// Error creating overlapped event; abort.if (!fWaitingOnRead) {// Issue read operation.if (!ReadFile(hComm, lpBuf, READ_BUF_SIZE, &dwRead, &osReader)) {if (GetLastError() != ERROR_IO_PENDING) // read not delayed?// Error in communications; report it.elsefWaitingOnRead = TRUE;}else {// read completed immediatelyHandleASuccessfulRead(lpBuf, dwRead);}}The second part of the overlapped operation is the detection of its completion. The event handle in the OVERLAPPED structure is passed to the WaitForSingleObject function, which will wait until the object is signaled. Once the event is signaled, the operation is complete. This does not mean that it was completed successfully, just that it was completed. The GetOverlappedResult function reports the result of the operation. If an error occurred, GetOverlappedResult returns FALSE and GetLastError returns the error code. If the operation was completed successfully, GetOverlappedResult will return TRUE.Note GetOverlappedResult can detect completion of the operation, as well as return the operation’s failure status. GetOverlappedResult returns FALSE and GetLastError returns ERROR_IO_INCOMPLETE when the operation is not completed. In addition, GetOverlappedResult can be made to block until the operation completes. This effectively turns the overlapped operation into a nonoverlapped operation and is accomplished by passing TRUE as the bWait parameter.Here is a code snippet that shows one way to detect the completion of an overlapped read operation. Note that the code calls the same function to process the data that was called when the operation completed immediately. Also note the use of the fWaitingOnRead flag. Here it controls entry into the detection code, since it should be called only when an operation is outstanding.#define READ_TIMEOUT 500 // millisecondsDWORD dwRes;if (fWaitingOnRead) {dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);switch(dwRes){// Read completed.case WAIT_OBJECT_0:if (!GetOverlappedResult(hComm, &osReader, &dwRead, FALSE))// Error in communications; report it.else// Read completed successfully.HandleASuccessfulRead(lpBuf, dwRead);// Reset flag so that another opertion can be issued.fWaitingOnRead = FALSE;break;case WAIT_TIMEOUT:// Operation isn't complete yet. fWaitingOnRead flag isn't// changed since I'll loop back around, and I don't want// to issue another read until the first one finishes.//// This is a good time to do some background work.break;default:// Error in the WaitForSingleObject; abort.// This indicates a problem with the OVERLAPPED structure's// event handle.break;}}WritingTransmitting data out the communications port is very similar to reading in that it uses a lot of the same APIs. The code snippet below demonstrates how to issue and wait for a write operation to be completed.BOOL WriteABuffer(char * lpBuf, DWORD dwToWrite){OVERLAPPED osWrite = {0};DWORD dwWritten;DWORD dwRes;BOOL fRes;// Create this write operation's OVERLAPPED structure's hEvent.osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (osWrite.hEvent == NULL)// error creating overlapped event handlereturn FALSE;// Issue write.if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {if (GetLastError() != ERROR_IO_PENDING) {// WriteFile failed, but isn't delayed. Report error and abort.fRes = FALSE;}else// Write is pending.dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);switch(dwRes){// OVERLAPPED structure's event has been signaled.case WAIT_OBJECT_0:if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))fRes = FALSE;else// Write operation completed successfully.fRes = TRUE;break;default:// An error has occurred in WaitForSingleObject.// This usually indicates a problem with the// OVERLAPPED structure's event handle.fRes = FALSE;break;}}}else// WriteFile completed immediately.fRes = TRUE;CloseHandle(osWrite.hEvent);return fRes;}Notice that the code above uses the WaitForSingleObject function with a time-out value of INFINITE. This causes the WaitForSingleObject function to wait forever until the operation is completed; this may make the thread or program appear to be “hung” when, in fact, the write operation is simply taking a long time to complete or flow control has blocked the transmission. Status checking, discussed later, can detect this condition, but doesn’t cause the WaitForSingleObject to return. Three things can alleviate this condition:∙Place the code in a separate thread. This allows other threads to execute any functions they desire while our writer thread waits for the write to be completed. This is what the MTTTY sample does.∙Use COMMTIMEOUTS to cause the write to be completed after a time-out period has passed.This is discussed more fully in the “Communications Time-outs” section late r in this article. This is also what the MTTTY sample allows.∙Change the WaitForSingleObject call to include a real time-out value. This causes more problems because if the program issues another operation while an older operation is still pending, new OVERLAPPED structures and overlapped events need to be allocated.This type of recordkeeping is difficult, particularly when compared to using a “job queue” design for the operations. The “job queue” method is used in the MTTTY sample.Note:The time-out values in synchronization functions are not communications time-outs.Synchronization time-outs cause WaitForSingleObject or WaitForMultipleObjects toreturn WAIT_TIMEOUT. This is not the same as a read or write operation timing out.Communications time-outs are described later in this article.Because the WaitForSingleObject function in the above code snippet uses an INFINITE time-out, it is equivalent to using GetOverlappedResult with TRUE for the fWait parameter. Here is equivalent code in a much simplified form:BOOL WriteABuffer(char * lpBuf, DWORD dwToWrite){OVERLAPPED osWrite = {0};DWORD dwWritten;BOOL fRes;// Create this writes OVERLAPPED structure hEvent.osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (osWrite.hEvent == NULL)// Error creating overlapped event handle.return FALSE;// Issue write.if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {if (GetLastError() != ERROR_IO_PENDING) {// WriteFile failed, but it isn't delayed. Report error and abort.fRes = FALSE;}else {// Write is pending.if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, TRUE))fRes = FALSE;else// Write operation completed successfully.fRes = TRUE;}}else// WriteFile completed immediately.fRes = TRUE;CloseHandle(osWrite.hEvent);return fRes;}GetOverlappedResult is not always the best way to wait for an overlapped operation to be completed. For example, if an application needs to wait on another event handle, the first code snippet serves as a better model than the second. The call to WaitForSingleObject is easy to change to WaitForMultipleObjects to include the additional handles on which to wait. This is what the MTTTY sample application does.A common mistake in overlapped I/O is to reuse an OVERLAPPED structure before the previous overlapped operation is completed. If a new overlapped operation is issued before a previous operation is completed, a new OVERLAPPED structure must be allocated for it. A new manual-reset event for the hEvent member of the OVERLAPPED structure must also be created. Once an overlapped operation is complete, the OVERLAPPED structure and its event are free for reuse.The only member of the OVERLAPPED structure that needs modifying for serial communications is the hEvent member. The other members of the OVERLAPPED structure should be initialized to zero and left alone. Modifying the other members of the OVERLAPPED structure is not necessary for serial communications devices. The documentation for ReadFile and WriteFile state that the Offset and OffsetHigh members of the OVERLAPPED structure must be updated by the application, or else results are unpredictable. This guideline should be applied to OVERLAPPED structures used for other types of resources, such as files.Serial StatusThere are two methods to retrieve the status of a communications port. The first is to set an event mask that causes notification of the application when the desired events occur. The SetCommMask function sets this event mask, and the WaitCommEvent function waits for the desired events to occur. These functions are similar to the 16-bit functions SetCommEventMask and EnableCommNotification, except that the Win32 functions do not post WM_COMMNOTIFY messages. In fact, the WM_COMMNOTIFY message is not even part of the Win32 API. The second method for retrieving the status of the communications port is to periodically call a few different status functions. Polling is, of course, neither efficient nor recommended.Communications EventsCommunications events can occur at any time in the course of using a communications port. The two steps involved in receiving notification of communications events are as follows:∙SetCommMask sets the desired events that cause a notification.∙WaitCommEvent issues a status check. The status check can be an overlapped or nonoverlapped operation, just as the read and write operations can be.Note: The word event in this context refers to communications events only. It does not refer to an event object used for synchronization.Here is an example of the SetCommMask function:DWORD dwStoredFlags;dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;if (!SetCommMask(hComm, dwStoredFlags))// error setting communications maskA description of each type of event is in Table 1.Table 1. Communications Event FlagsAfter specifying the event mask, the WaitCommEvent function detects the occurrence of the events. If the port is open for nonoverlapped operation, then the WaitCommEvent function does not contain an OVERLAPPED structure. The function blocks the calling thread until the occurrence of one of the events. If an event never occurs, the thread may block indefinitely.Here is a code snippet that shows how to wait for an EV_RING event when the port is open for nonoverlapped operation:DWORD dwCommEvent;if (!SetCommMask(hComm, EV_RING))// Error setting communications maskreturn FALSE;if (!WaitCommEvent(hComm, &dwCommEvent, NULL))// An error occurred waiting for the event.return FALSE;else// Event has occurred.return TRUE;Note The Microsoft Win32 SDK Knowledge Base documents a problem with Windows 95 and the EV_RING flag. The above code never returns in Windows 95 because the EV_RING event is not detected by the system; Windows NT properly reports the EV_RING event. Please see the Win32 SDK Knowledge Base for more information on this bug.As noted, the code above can be blocked forever if an event never occurs. A better solution would be to open the port for overlapped operation and wait for a status event in the following manner:#define STATUS_CHECK_TIMEOUT 500 // MillisecondsDWORD dwRes;DWORD dwCommEvent;DWORD dwStoredFlags;BOOL fWaitingOnStat = FALSE;OVERLAPPED osStatus = {0};dwStoredFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |\EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;if (!SetCommMask(comHandle, dwStoredFlags))// error setting communications mask; abortreturn 0;osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);if (osStatus.hEvent == NULL)// error creating event; abortreturn 0;for ( ; ; ) {// Issue a status event check if one hasn't been issued already.if (!fWaitingOnStat) {if (!WaitCommEvent(hComm, &dwCommEvent, &osStatus)) {if (GetLastError() == ERROR_IO_PENDING)bWaitingOnStatusHandle = TRUE;else// error in WaitCommEvent; abortbreak;}else// WaitCommEvent returned immediately.// Deal with status event as appropriate.ReportStatusEvent(dwCommEvent);}// Check on overlapped operation.if (fWaitingOnStat) {// Wait a little while for an event to occur.dwRes = WaitForSingleObject(osStatus.hEvent, STATUS_CHECK_TIMEOUT);switch(dwRes){// Event occurred.case WAIT_OBJECT_0:if (!GetOverlappedResult(hComm, &osStatus, &dwOvRes, FALSE))// An error occurred in the overlapped operation;// call GetLastError to find out what it was// and abort if it is fatal.else// Status event is stored in the event flag// specified in the original WaitCommEvent call.// Deal with the status event as appropriate.ReportStatusEvent(dwCommEvent);// Set fWaitingOnStat flag to indicate that a new// WaitCommEvent is to be issued.fWaitingOnStat = FALSE;break;case WAIT_TIMEOUT:// Operation isn't complete yet. fWaitingOnStatusHandle flag// isn't changed since I'll loop back around and I don't want// to issue another WaitCommEvent until the first one finishes.//// This is a good time to do some background work.DoBackgroundWork();break;default:// Error in the WaitForSingleObject; abort// This indicates a problem with the OVERLAPPED structure's// event handle.CloseHandle(osStatus.hEvent);return 0;}}}CloseHandle(osStatus.hEvent);The code above very closely resembles the code for overlapped reading. In fact, the MTTTY sample implements its reading and status checking in the same thread using WaitForMultipleObjects to wait for either the read event or the status event to become signaled.There are two interesting side effects of SetCommMask and WaitCommEvent. First, if the communications port is open for nonoverlapped operation, WaitCommEvent will be blocked until an event occurs. If another thread calls SetCommMask to set a new event mask, that thread will be blocked on the call to SetCommMask. The reason is that the original call to WaitCommEvent in the first thread is still executing. The call to SetCommMask blocks the thread until the WaitCommEvent function returns in the first thread. This side effect is universal for ports open for nonoverlapped I/O. If a thread is blocked on any communications function and another thread calls a communications function, the second thread is blocked until the communications function returns in the first thread. The second interesting note about these functions is their use on a port open for overlapped operation. If SetCommMask sets a new event mask, any pending WaitCommEvent will complete successfully, and the event mask produced by the operation is NULL.CaveatUsing the EV_RXCHAR flag will notify the thread that a byte arrived at the port. This event, used in combination with the ReadFile function, enables a program to read data only after it is in the receive buffer, as opposed to issuing a read that waits for the data to arrive. This is particularly useful when a port is open for nonoverlapped operation because the program does not need to poll for incoming data; the program is notified of the incoming data by the occurrence of the EV_RXCHAR event. Initial attempts to code this solution often produce the following pseudocode, including one oversight covered later in this section:DWORD dwCommEvent;DWORD dwRead;char chRead;if (!SetCommMask(hComm, EV_RXCHAR))// Error setting communications event mask.for ( ; ; ) {if (WaitCommEvent(hComm, &dwCommEvent, NULL)) {if (ReadFile(hComm, &chRead, 1, &dwRead, NULL))// A byte has been read; process it.else// An error occurred in the ReadFile call.break;}else// Error in WaitCommEvent.break;}The above code waits for an EV_RXCHAR event to occur. When this happens, the code calls ReadFile to read the one byte received. The loop starts again, and the code waits for another EV_RXCHAR event. This code works fine when one or two bytes arrive in quick succession. The byte reception causes the EV_RXCHAR event to occur. The code reads the byte. If no other byte arrives before the code calls WaitCommEvent again, then all is fine; the next byte to arrive will cause the WaitCommEvent function to indicate the occurrence of the EV_RXCHAR event. If another single byte arrives before the code has a chance to reach the WaitCommEvent function, then all is。

使用Win32创建串口通讯程式

使用Win32创建串口通讯程式

comcool_code.zip使用Win32創建串口通訊程式作者:konchat翻譯:PowerCPP下載本文示例代碼介紹:本文的目的是介紹如何在Win32中處理串口。

串口通訊可以通過多種技術實現,例如:ActiveX,I/O存取和檔操作。

本文介紹Win32平臺下通過檔操作技術使用串口。

程式師可以使用Microsoft Visual C++ Version 6.0所提供的kernel32.lib。

在Microsoft Windows(2000,Me,XP and 95/98)中,串口作為檔處理。

因此可以通過Windows檔創建函數打開串口。

文章不僅介紹了串口通訊,也介紹了在串口通訊應用程式中實現多工,多工可以使串口通訊應用程式在同一時間處理更多的任務,例如:讀數據任務,發送資料任務,GUI任務等。

以下主題描述了Win32中基本的串口操作:初始化/打開串口通訊•創建埠控制碼•獲取配置(DCB)•修改配置•保存配置•設置通訊超時接收/發送資料•發送資料•接收資料•關閉串口設計步驟:初始化/打開串口打開串口的第一步是初始化或設置串口配置,目的是創建串口代理,整篇文章我們都將用檔案控制代碼作為串口代理。

創建埠控制碼串口控制碼是可以被用來存取的串口物件控制碼,創建串口控制碼的函數是CreateFile,如下代碼所示:handlePort_ = CreateFile(portName, // 埠設備: 默認"COM1" GENERIC_READ | GENERIC_WRITE, // 設備打開模式: 允許讀寫0, // 不共用NULL, // 默認安全設置OPEN_EXISTING, // 打開方式:打開已經存在的埠0, // 默認NULL); // 默認如圖2所示,portName = "COM1": portName 示一個const char*變數,它指定想創建串口控制碼的埠名稱。

利用Win32 API通信函数实现串口通信编程

利用Win32 API通信函数实现串口通信编程

利用Win32 API通信函数实现串口通信编程
李日云;王来禄;刘汇江
【期刊名称】《地球科学与环境学报》
【年(卷),期】2004(26)3
【摘要】测绘仪器与计算机之间的异步串行通信是现代测绘中经常遇到的问题,如何在Windows平台下实现测绘仪器与计算机之间数据通信是测量内、外业一体化的基本问题.在工作经验的基础上,详细研究和分析了利用Win32 API通信函数实现串口通信编程的基本方法以及多线程技术在串口通信中的应用和特点,最后以大地型ASHTECH GPS接收机为研究对象,进行了相应的实验研究.
【总页数】4页(P61-63,68)
【作者】李日云;王来禄;刘汇江
【作者单位】长安大学,地质工程与测绘工程学院,陕西,西安,710054;西安高新开发区,土地储备中心,陕西,西安,710000;甘肃省公路工程总公司,第五分公司,甘肃,兰州,730000
【正文语种】中文
【中图分类】P209
【相关文献】
1.基于API的Win32串口通信编程技术 [J], 崔红志;索岩
2.利用API一232简化串口通信编程 [J], 杨志鸿
3.一种利用Win32 API函数实现串口实时通迅的方法 [J], 罗云虎
4.Win32环境下基于VC++6.0串口通信编程方法 [J], 杨锋;桂卫华;陈峰;冯磊华
5.基于Win32 API函数和多线程技术的串行通信编程 [J], 颜波;谢存禧;张铁因版权原因,仅展示原文概要,查看原文内容请购买。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Lazarus实战开发之串口通信(WINCE/WIN32)Lazarus最吸引人的地方就是她的开发方式类似Delphi,支持超好用的RAD开发方式,并且最厉害的地方是她还支持多个平台,多个CPU,例如ARM9的WINCE。

本文要讲述的就是&ldquo;如何使用LAZARUS开发Wince上的串口程序&rdquo;,并且,本文的串口程序同时支持WINCE和WINXP系统,当然编译时要选择平台啦。

WINCE与WINXP 在本文中的代码区别只是OpenPort(&lsquo;COM1:&rsquo;,CBR_9600,8,NOPARITY,ONESTOPBIT);//wince用COM1:表示串口1;WINXP用COM1表示串口1.一、建立一个可重用的类,文件名为CE_Series.pas:unit CE_Series;interfaceusesWindows,Classes, SysUtils, LResources, StdCtrls,ExtCtrls;typeTCE_Series = class(TObject)privatehComm: THandle;publicFunction OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;procedure Send(str:String);Function Receive():String;procedure ClosePort();end;implementation//============================================================================== =================// 语法格式:OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer)// 实现功能:打开串口// 参数:port,串口号;例如wince下为从COM1:,COM2:。

..。

.win32下为COM1,COM2.。

..。

.. ;其他略,顾名思义哈// 返回值:错误信息//============================================================================== =================function TCE_Series.OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;varcc:TCOMMCONFIG;beginresult:=&lsquo;&rsquo;;hComm:=CreateFile(port, GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING, 0, 0); // 打开COMif (hComm = INVALID_HANDLE_VALUE) then begin // 如果COM 未打开result:=&lsquo;CreateFile Error!&rsquo;;exit;end;GetCommState(hComm,cc.dcb); // 得知目前COM 的状态cc.dcb.BaudRate:=BaudRate; // 设置波特率为BaudRatecc.dcb.ByteSize:=ByteSize; // 字节为 ByteSize(8 bit)cc.dcb.Parity:=Parity; // Parity 为 Nonecc.dcb.StopBits:=StopBits; // 1 个Stop bitif not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态result:=&lsquo;SetCommState Error!&rsquo;;CloseHandle(hComm);exit;end;end;//============================================================================== =================// 语法格式:Send(str:String)// 实现功能:发送数据// 参数:str,数据// 返回值:无//============================================================================== =================procedure TCE_Series.Send(str:String);varlrc:LongWord;beginif (hComm=0) then exit; //检查Handle值WriteFile(hComm,str,Length(str), lrc, nil); // 送出数据end;//=====================================================================//语法格式: Receive()//实现功能:接收串口数据//参数:无//返回值:收到的字符串//=====================================================================Function TCE_Series.Receive():String;varinbuff: array[0..2047] of Char;nBytesRead, dwError:LongWORD ;cs:TCOMSTAT;beginClearCommError(hComm,dwError,@CS); //取得状态// 数据是否大于我们所准备的Bufferif cs.cbInQue 》 sizeof(inbuff) then beginPurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 数据exit;end;ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据//转移数据到变量中result:=Copy(inbuff,1,cs.cbInQue);//返回数据end;//=====================================================================//语法格式: ClosePort()//实现功能:关闭串口//参数:无//返回值:无//=====================================================================procedure TCE_Series.ClosePort();beginSetCommMask(hcomm,$0);CloseHandle(hComm);end;end.二、写调用程序演示如何使用这个类,请自行加入控件,所用的控件不多:unit Unit1;{$mode objfpc}{$H+}interfaceusesWindows,Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,StdCtrls,ExtCtrls,CE_Series;type{ TForm1 }TForm1 = class(TForm)btn_OpenPort: TButton;btn_ClosePort: TButton;btn_Send: TButton;edt_Receive: TMemo;GroupBox1: TGroupBox;edt_Send: TMemo;GroupBox2: TGroupBox;Timer1: TTimer;procedure btn_ClosePortClick(Sender: TObject);procedure btn_OpenPortClick(Sender: TObject);procedure btn_SendClick(Sender: TObject);procedure Timer1Timer(Sender: TObject);private{ private declarations }public{ public declarations }end;varForm1: TForm1;myseries:TCE_Series;implementation{ TForm1 }procedure TForm1.btn_OpenPortClick(Sender: TObject);beginmyseries:=TCE_Series.Create;myseries.OpenPort(&lsquo;COM1:&rsquo;,CBR_9600,8,NOPARITY,ONESTOPBIT); Timer1.Enabled:=true;end;procedure TForm1.btn_SendClick(Sender: TObject);beginmyseries.Send(edt_Send.Text);end;procedure TForm1.Timer1Timer(Sender: TObject); //用Timer定时接收数据varreceive:string;beginreceive:=myseries.Receive();if receive《》&lsquo;&rsquo; thenbeginedt_Receive.Lines.Add(receive); // 将数据显示于edt_Receive 上end;end;procedure TForm1.btn_ClosePortClick(Sender: TObject);beginTimer1.Enabled:=false;myseries.ClosePort();close;end;initialization{$I unit1.lrs}end.。

相关文档
最新文档