我是一个初学者,由于工作需要编写一个使用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;
}