从win32的串口API编程学C++的点、线、面!(1)使用win32API让串口工作!

  我是一个初学者,由于工作需要编写一个使用win32 API的串口通讯程序!这一系列文记录了我学习整个过程和基中C++/C各种知识的点、面,我贴出来是想其中的错漏,请大家指正出,以便重构!(此节为第一篇,就要讲串口打开与写操作)

//第一节内容包括:使用API打开串口 对串口写字符串

编写第一个可以工作的串口程序!

编写环境:win03+vs05

程序流程:打开串口->设置DCB串口属性->写字符串

这个程序非常简单,是我参照网上CDMA发短信程序写的!但是我认为,这是win32 API串口通讯入门的一个好示例!

  我编写程序前,使用2、3交叉线的RS232串口线将COM1和COM2口连接在一起了。不过现在新电脑都取消了串口了,可以使用USB转串口设备替换,效果是一样的。下载一个串口调试助手(我使用的是V2.1.exe),作为测试用例中的工具软件。在VS05中新建C++空console项目,在空项目中加入了一个C++文件。

  源文件很简单,主要串口API的应用,打开串口COM2->设置DCB串口属性(9600,n,8,1)->写字符串"1234567890",使用串口调试助手可以接收到字符串。涉及到C++的点不多,用了iostream和namespace,没用使用C++异常,iostream主是输出错误返回代码。

知识点

打开串口

  什么叫“打开串口”?说白了就是向操作系统申请使用串口资源,告诉操作系统:我(本进程)要使用哪个串口(资源),使用方式是什么。操作系统得到申请后,就帮你分配资源。如果别人用了,就告诉你:不行,有人用了,你不能用了!如果无人,就分配你一个许可证--返回句柄,告诉你:你用吧,这是许可证!具体函数是:CreateFile(),返回值就是句柄(许可证)。

用以下代码分析下CreateFile函数的知识点

HANDLE hCom =::CreateFile(  _T("COM2"),
        GENERIC_READ|GENERIC_WRITE, 
        0,
        0,
        OPEN_EXISTING,
        0,//FILE_FLAG_OVERLAPPED,
        0
         );

使用串口资源时,第三个、第五个和第七个参数必须这样设定。最需要注意的是第六个参数,涉及同步和异步方式。实际应用中同步应用很少,多是异步操作。本例中使用的是同步。也就是说打开串口有两种方式:一种是同步(NonOverlapped),另一种是异步方式(Overlapped)。这其实也告诉操作系统本进程使用串口的方法!当第六个参数为0,即使用同步方法打开,在本例中的意思为:当程序在WriteFile()执中写字符串操作时,不响应任何调度,一直到写操作完成,WriteFile函数返回。其实,你就把这段同步操作理想成DOS下的程序就可以了!函数过程从main开始,一句一句的过程,从头执行到尾。关于同步与异步在后面几节会详细讲述下。


以下源代码

//SerialComm.cpp
#include <iostream>
#include <TCHAR.H>

#include <windows.h>

using namespace std;

int main()
{
 HANDLE hCom =::CreateFile(  _T("COM2"),
        GENERIC_READ|GENERIC_WRITE, 
        0,
        0,
        OPEN_EXISTING,
        0,//FILE_FLAG_OVERLAPPED,
        0
         );
 if(hCom ==INVALID_HANDLE_VALUE){
  DWORD dwError=::GetLastError();
  cout<<dwError<<endl;
  return false;
 }
   
 DCB dcb={0};
 dcb.DCBlength = sizeof(DCB);

 if(!::GetCommState(hCom,&dcb)){
  DWORD dwError=::GetLastError();
  cout<<dwError<<endl;
  return false;
 }

 dcb.BaudRate = 9600;
 dcb.ByteSize = 8;
 dcb.Parity = NOPARITY;
 dcb.StopBits =ONESTOPBIT;

 if(!::SetCommState(hCom,&dcb)){
  DWORD dwError=::GetLastError();
  cout<<dwError<<endl;
  return false;
 }
 if( !::PurgeComm( hCom, PURGE_RXCLEAR ) )    return false;
 DWORD dw;
 ::WriteFile(hCom,"1234567890",10,&dw,NULL);
 ::CloseHandle(hCom);
 return 0;
}

原文地址:https://www.cnblogs.com/scarecrow/p/1330571.html