admin 管理员组

文章数量: 887021


2024年2月24日发(作者:后序线索化二叉树算法)

VC 串口编程基础之如何用 VC 打开串口和关闭串口

在对串口进行操作之前都需要先打开串口,VC 串口编程方法分为利用 VC 串口控件(或 VC 串口类)和直接调用Windows底层API函数(我称之为VC API 串口编程)两种方法,不管哪种方法,其实质都是利用底层API函数对串口进行操作,这里我们来看怎么利用API函数来用 VC 打开串口。

在Windows 32位以上操作系统(Win98以上)中,将串口(包括其它通信设备)作为文件来处理,所以串口的打开、读写和关闭所用API函数与文件操作函数一样。所以打开串口用CreateFile,读串口用ReadFile,写串口用WriteFile,关闭串口用CloseHandle。

一、用VC 打开串口、关闭串口的API函数

1、打开串口用CreateFile,其声明如下:

HANDLE CreateFile(

LPCTSTR lpFileName, // file name

DWORD dwDesiredAccess, // access mode

DWORD dwShareMode, // share mode

LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD

DWORD dwCreationDisposition, // how to create

DWORD dwFlagsAndAttributes, // file attributes

HANDLE hTemplateFile // handle to template file

);

部分参数解释如下:

lpFileName:指定要打开的串口逻辑名,用字符串表示,如“COM1”和“COM2”分别表示串口1和串口2,若要知道您的电脑有哪此串口,可以打开设备管理器查看,如下图所示,或用丁丁串口调试助手,这个工具启动后会枚举系统当前存在的串口。

dwDesiredAccess:访问类型,有读(dwDesiredAccess=GENERIC_READ)、写(dwDesiredAccess=GENERIC_WRITE)或两者兼有((dwDesiredAccess=GENERIC_READ

。 | GENERIC_WRITE)●

dwShareMode:指定端口的共享属性,该参数是为那些由许多应用程序共享的文件提供的,对于串口来说是不能共享的,所以它必须设置为0,这就是通信设备与文件之间的主要差别,如果当前的应用程序调用CreateFile打开一个串口,另外一个程序如果已经打开了该串口,此时CreateFile会返回一个错误代码。然而,同一个应用程序的多个线程可以共享由CreateFile返回的端口句柄,并且根据安全性属性设置,该句柄可以被打开端口的应用程序的子程序所继承。

lpSecurityAttributes:安全属性,此参数为一LPSECURITY_ATTRIBUTES结构,此结构定义了一些属性,如果将该参数设为NULL,该端口将被分配为缺省安全属性,缺省安全属性下端口句柄是不能被继承的。

安全属性LPSECURITY_ATTRIBUTES的结构声明如下:

 typedef struct _SECURITY_ATTRIBUTES {

 DWORD nLength;

 LPVOID lpSecurityDescriptor;

 BOOL bInheritHandle;

 } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

结构成员nLength指明该结构的长度, lpSecurityDescriptor指向一个安全描述符,bInheritHandle表明句柄是否能被继承

dwCreationDisposition:指定当此端口正在被其它程序占用时采取的动作,因为串口总是存在的,所以此处必须被设置为OPEN_EXISTING

,该标志告诉Windows不要创建新端口,而是打开一个

已经存在的端口。

dwFlagsAndAttributes:描述了端口的各种属性,对于文件来说可能有很多种属性,但对于串口来说,唯一有意义的是设置FILE_FLAG_OVERLAPPED属性,当指定该属性时,端口I/O可以在后台进行,这称之为异步I/O重叠结构,更多信息可查看MSDN或其它参考资料。

hTemplateFile:指向模板文件的句柄,对于串口来说,此参数必须设置为0。

用CreateFile函数打开串COM1的例子如下:

 HANDLE hCom;

 DWORD dwError;



 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)

 {

 dwErrow = GetLastError(); //取得错误代码

 }

如果发生错误,您可以根据取得的错误代码查询到底是什么原因引起的错误。

2、关闭串口用CloseHandle,其函数声明如下:

 BOOL CloseHandle(

 HANDLE hObject // handle to object

 );

这个函数很简单,参数只有一个,这个参数就是要关闭的端口句柄,就是用CreateFile打开端口时返回的句柄。

二、用VC 打开串口和关闭串口的实例。

为了直观,程序界面采用MFC编写。创建一个基于对话框MFC应用程序,工程名为OpenCOM,在主对话框中加入两个按钮和组合列表框,如下图所示:

下拉列表框预先填入数据:COM1、COM2、COM3和COM4,如下图所示:

这样在程序运行后,点击组合列表框就会有四个串行端口可供选择,本站将会在另外一篇文章中介绍如何用枚举串口的方法自动查找系统中存在的串口。

编写“打开串口” 按钮“BN_CLICKED”事件响应代码,内容如下:

 CString strSel_COM; //选择想要打开的串口号

 BOOL bComOpened = NULL; //串口已经被打开标志

 void COpenCOMDlg::OnBtnOpencom()

 {



 //取得选定串口号

 ((CComboBox*)GetDlgItem(IDC_COMLIST))->GetWindowText(strSel_COM);



 m_hCom = CreateFile( strSel_COM, //m_hCom的定义为:HANDLE

m_hCom;

 GENERIC_READ | GENERIC_WRITE, //读写模式

 0, //不共享

 NULL, //默认安全模式

 OPEN_EXISTING, //打开方式:打开已经存在的端口

 NULL,

 NULL);



 //验证串口是否被正常打开

 if( m_hCom == INVALID_HANDLE_VALUE )

 {

 CString strMsg;

 strMsg = "串口" + strSel_COM + "打开失败";

 AfxMessageBox(strMsg);

 }

 else

 {

 CString strMsg;

 strMsg = "串口" + strSel_COM + "被成功打开";

 AfxMessageBox(strMsg);



 GetDlgItem(IDC_BTN_OPENCOM)->EnableWindow(FALSE);



 bComOpened = TRUE;

 }



 }

为了程序启动时组合列表框初始状态选定一个串口号,在主对话框的初始化函数OnInitDialog()里加入如下内容:

 ((CComboBox*)GetDlgItem(IDC_COMLIST))->SetCurSel(0);

运行程序,选择一个想要打开的串口号,然后点击“打开串口”按钮,成功则弹出打开成功的对话框,失败则弹出打开失败的对话框,若成功打开串口,“打开串口”按钮将变灰,如下图所示:

选择一个想要打开的串口

打开失败的情况

打开成功的情况

下面来完成关闭串口的功能,编写“关闭串口” 按钮“BN_CLICKED”事件响应代码,内容如下:

 void COpenCOMDlg::OnBtnClosecom()

 {



 if(!bComOpened)

 {

 AfxMessageBox("没有串口被打开");

 return;

 }



 if(CloseHandle(m_hCom) == 0) // 调用该函数关闭串口

 {

 CString strMsg;

 strMsg = "关闭串口" + strSel_COM + "失败";

 AfxMessageBox(strMsg);

 }

 else

 {

 CString strMsg;

 strMsg = "关闭串口" + strSel_COM + "成功";

 AfxMessageBox(strMsg);



 bComOpened = FALSE;



 GetDlgItem(IDC_BTN_OPENCOM)->EnableWindow();

 }

 }

运行程序后,在点击“关闭串口”按钮时,如果没有串口被打开,将出现以下提示框:

如果在已经打开了串口的情况下将出现以下提示,同时变灰的“打开串口”按钮又变得可用。

此实例源码可到VC串口通信源码栏目的《用VC 打开关闭串口简单实例源码》下载。

(责任编辑:admin)


本文标签: 串口 打开 端口 关闭