赞
踩
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。
SerialInterface.h
#ifndef __SerialInterface_H_ #define __SerialInterface_H_ #include <Windows.h> #include <string> using namespace std; class SerialInterface { private: /* data */ HANDLE hCom; string last_error; public: SerialInterface(); ~SerialInterface(); public: //同步方式打开串口,并配置默认信息 bool openSyn(string serial_name,unsigned char baud_rate,unsigned char parity, unsigned char byte_size, unsigned char stop_bits); //同步方式打开串口(需自己配置串口参数) bool openSyn(string serial_name); //设置推荐的缓冲大小 bool setBufferSize(DWORD inputBuff,DWORD outBuffer); //设置超时 bool setTimeouts(COMMTIMEOUTS &timeouts); //设置串口信息 bool setDCB(DCB& dcb); //刷新缓冲区 bool purgeBuff(DWORD flags); //刷新缓冲区 bool flushBuff(); //写数据 DWORD writeData(char *buffer,int length); //读数据 DWORD readData(char *buffer,int length); //写字符串 DWORD writeStr(string str); //关闭串口 void closeComm(); //判断串口是否打开 bool isOpened(); //得到最后一次失败的错误信息 string getSerialLastError(); private: //设置最后一次的错误信息 void setSerialLastError(string error_msg); //清chu最后一次的错误信息 void clearSerialLastError(); }; #endif /*__SerialInterface_H_*/
SerialInterface.cpp
#include "SerialInterface.h" /******************************************************************* * 名称: openSyn * 功能: 同步方式打开串口,并配置默认信息 * 参数: serial_name:串口名称 baud_rate :波特率,取值如下 ...... CBR_9600 9600bps CBR_14400 14400bps ...... parity :校验方式 EVENPARITY 偶校验 MARKPARITY 标号校验 NOPARITY 无校验 ODDPARITY 奇校验 SPACEPARITY 空格校验 byte_size :数据位大小 4,5,6,7,8 stop_bits :停止位 ONESTOPBIT 1个停止位 ONE5STOPBITS 1.5个停止位 TWOSTOPBITS 2个停止位 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::openSyn(string serial_name, unsigned char baud_rate, unsigned char parity, unsigned char byte_size, unsigned char stop_bits) { if (!openSyn(serial_name)) return false; DCB dcb; if (false == GetCommState(hCom, &dcb))//获得当前串口的配置信息 { setSerialLastError("SerialInterface::open() : GetCommState Error"); return false; } dcb.DCBlength = sizeof(DCB); dcb.BaudRate = baud_rate; dcb.Parity = parity; dcb.ByteSize = byte_size; dcb.StopBits = stop_bits; if (false == SetCommState(hCom, &dcb))//用DCB结构重新配置串行端口信息 { setSerialLastError("SerialInterface::open() : SetCommState Error"); return false; } //超时处理 COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD; //读间隔超时 // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作 timeouts.ReadTotalTimeoutMultiplier = 0; //读时间系数 timeouts.ReadTotalTimeoutConstant = 0; //读时间常量 timeouts.WriteTotalTimeoutMultiplier = 50; // 写时间系数 timeouts.WriteTotalTimeoutConstant = 2000; //写时间常量 //总的读/写超时时间 = Read(Write)TotalTimeoutMultiplier x 要读/写的字节数 + Read(Write)TotalTimeoutConstant. if (false==SetCommTimeouts(hCom, &timeouts)) { setSerialLastError("SerialInterface::open() : SetCommTimeouts Error"); return false; } //清空缓冲区,为读写串口做准备 if (false == PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT)) { setSerialLastError("SerialInterface::open() : PurgeComm Error"); return false; } return true; } /******************************************************************* * 名称: openSyn * 功能: 同步方式打开串口(需自己配置串口参数) * 参数: serial_name:串口名称 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::openSyn(string serial_name) { hCom = CreateFileA( serial_name.data(),//普通文件名或者设备文件名,这里是串口名 GENERIC_READ | GENERIC_WRITE,//访问模式,读和写 0,//共享模式,独占模式 NULL,//指向安全属性的指针,不使用,传NULL OPEN_EXISTING,//如何创建,在串口中必须设置为OPEN_EXISTING。表示不能创建新端口只能打开已有的端口。 FILE_ATTRIBUTE_NORMAL,//文件属性,使用默认属性FILE_ATTRIBUTE_NORMAL。 NULL//用于复制文件句柄,通常这个参数设置为NULL,为空表示不使用模板 ); if (INVALID_HANDLE_VALUE == hCom)//出错判断 { hCom = NULL; setSerialLastError("open():CreateFileA Error!"); return false; } return true; } /******************************************************************* * 名称: closeComm * 功能: 关闭串口 * 参数: 无 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ void SerialInterface::closeComm() { if(NULL==hCom) return; CloseHandle(hCom); hCom=NULL; } /******************************************************************* * 名称: closeComm * 功能: 判断串口是否打开 * 参数: 无 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::isOpened() { return NULL == hCom ? false : true; } DWORD SerialInterface::readData(char *buffer,int length) { DWORD writeSize=0; bool ret=false; ret=ReadFile(hCom,buffer,length,&writeSize,NULL); if(false==ret) return 0; return writeSize; } DWORD SerialInterface::writeData(char *buffer,int length) { DWORD writeSize=0; bool ret=false; ret=WriteFile(hCom,buffer,length,&writeSize,NULL); if(false==ret) return 0; return writeSize; } DWORD SerialInterface::writeStr(string str) { bool ret = false; DWORD writeSize = 0; ret = WriteFile(hCom, str.data(), str.length(), &writeSize, NULL); if (0 == ret) { last_error = "Error By writeStr(string str)"; return 0; } last_error = ""; return writeSize; } /******************************************************************* * 名称: setTimeouts * 功能: 设置超时 * 参数: timeouts:超时配置的COMMTIMEOUTS结构体 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::setTimeouts(COMMTIMEOUTS &timeouts) { if (false == SetCommTimeouts(hCom, &timeouts)) { setSerialLastError("SerialInterface::setTimeouts() : SetCommTimeouts Error"); return false; } return true; } /******************************************************************* * 名称: setDCB * 功能: 设置串口信息 * 参数: dcb:串口信息配置的DCB结构体 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::setDCB(DCB& dcb) { if (false == SetCommState(hCom, &dcb)) { setSerialLastError("SerialInterface::setDCB() : SetCommState Error"); return false; } return true; } /******************************************************************* * 名称: purgeBuff * 功能: 刷新缓冲区 * 参数: flags:需要完成的操作,取值如下 PURGE_RXABORT 终止所有未完成的重叠读取操作并立即返回,即使读取操作尚未完成。 PURGE_RXCLEAR 清除输入缓冲区(如果设备驱动程序有一个)。 PURGE_TXABORT 终止所有未完成的重叠写操作并立即返回,即使写操作尚未完成。 PURGE_TXCLEAR 清除输出缓冲区(如果设备驱动程序有一个)。 * 返回: 正确返回为ture,错误返回为false * 提示:PurgeComm()函数可以在读写操作的同时,清空缓冲区。当应用程序在读写操作时 调用PurgeComm()函数,不能保证缓冲区内的所有字符都被发送。 *******************************************************************/ bool SerialInterface::purgeBuff(DWORD flags) { if (false == PurgeComm(hCom, flags)) { setSerialLastError("SerialInterface::purgeBuff() : PurgeComm Error"); return false; } return true; } /******************************************************************* * 名称:flushBuff * 功能:刷新缓冲区 * 参数:无 * 返回:正确返回为ture,错误返回为false * 提示:该函数只受流量控制的支配,不受超时控制的支配,它在所有的写操作完成后才返回。 *******************************************************************/ bool SerialInterface::flushBuff() { if(FlushFileBuffers(hCom)) { setSerialLastError("SerialInterface::flushBuff() : FlushFileBuffers Error"); return false; } return true; } /******************************************************************* * 名称: setBufferSize * 功能: 设置推荐的缓冲大小 * 参数: inputBuff:输入缓冲大小 outBuffer:输出缓冲大小 * 返回: 正确返回为ture,错误返回为false *******************************************************************/ bool SerialInterface::setBufferSize(DWORD inputBuff,DWORD outBuffer) { if(inputBuff<=0||outBuffer<=0) return false; return SetupComm(hCom,inputBuff,outBuffer); } /******************************************************************* * 名称: getSerialLastError * 功能: 得到最后一次失败的错误信息 * 参数: 无 * 返回: 数据类型:string,错误信息 *******************************************************************/ string SerialInterface::getSerialLastError() { return last_error; } void SerialInterface::setSerialLastError(string error_msg) { last_error = error_msg; } void SerialInterface::clearSerialLastError() { last_error = ""; } SerialInterface::SerialInterface() { hCom=NULL; } SerialInterface::~SerialInterface() { }
注意:这两个串口是连通的,给COM1发数据,COM2可以收到,反之亦然。
## 用串口调试助手连接COM2来接数据
代码如下所示:
#include <iostream> #include <cstdlib> #include "SerialInterface.h" #include <windows.h> #include <tchar.h> using namespace std; int main() { SerialInterface com; if(!com.openSyn("COM1", CBR_9600, NOPARITY,8, ONESTOPBIT)) { cout << com.getSerialLastError() << endl; getchar(); return 0; } //测试发送 if (com.writeStr("Hello World!")) { cout << "send success" << endl; } else { cout << "send fail" << endl; } com.closeComm(); //getchar(); return 0; }
注意串口信息的配置要一致
参数的取值在函数的开头有详细的讲解,例如:
因为时间关系,只详细写了同步的串口操作,异步的情况后续有空会慢慢更新
此项目以经挂到GitHub:
https://github.com/LairdXavier/MyTool.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。