windows串口通信的基本步骤
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//打开串口后,自动接收数据
//向串口发送数据
char* data = "This is a example\n";
int ret = 1;
while(ret != IDNO )
{
serial.SendData(data,strlen(data));
ret = MessageBox(NULL,_T(""),_T("是否向串口发送数据"),MB_YESNO);
{ MessageBox(NULL,_T("设置串口参数失败"),_T("提示"),MB_OK);
return FALSE;
}
//设置串口事件
SetCommMask(m_hComm,EV_RXCHAR);
//在缓存中有字符时产生事件
SetupComm(m_hComm,16384,16384);
//设置串口读写时间
}
}
return 0;
} /******************************************************************************************* *功能:打开串口* port :串口号,如_T("COM1:") * baud_rate:波特率* date_bits:数据位(有效范围4~8)* stop_bit :停止位* parity :奇偶校验。默认为无校验。NOPARITY 0;ODDPARITY 1;EVENPARITY 2;MARKPARITY 3;SPACEPARITY 4 ********************************************************************************************/ BOOL CSerial::OpenSerialPort(TCHAR* port,UINT baud_rate,BYTE date_bits,BYTE stop_bit,BYTE parity)
{
MessageBox(NULL,_T("设置串口时间失败"),_T("提示"),MB_OK); return FALSE;
}
//创建线程,读取数据HANDLE hReadCommThread = (HANDLE)
_beginthreadex(NULL,0,(PTHREAD_START) CommProc,(LPVOID) this,0,NULL); return TRUE;
->在串口调试助手中,手动发送”jarvischu”,程序会读取到该数据并弹出消息框显示。
源码如下:
Serial.h
#pragma once
#include class CSerial {
public:
CSerial(void);
~CSerial(void);
//打开串口
BOOL OpenSerialPort(TCHAR* port,UINT baud_rate,BYTE date_bits,BYTE stop_bit,BYTE parity=NOPARITY);
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(m_hComm,&CommTimeOuts); CommTimeOuts.ReadIntervalTimeout = MAXDWORD; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 10; CommTimeOuts.WriteTotalTimeoutConstant = 1000; if(!SetCommTimeouts(m_hComm,&CommTimeOuts))
//YES继续发送一条数据,NO不发送,退出
}
return 0;
}
CSerial::CSerial(void)
{
m_hComm = INVALID_HANDLE_VALUE;
}
CSerial::~CSerial(void) {
if(m_hComm != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hComm);
}
} /********************************************************************************************* *功能:读串口线程回调函数*描述:收到数据后,简单的显示出来********************************************************************************************/ DWORD WINAPI CommProc(LPVOID lpParam)
{
CSerial* pSerial = (CSerial*)lpParam; //
//清空串口
PurgeComm(pSerial->m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR);
char buf[512];
DWORD dwRead; while(pSerial->m_hComm != INVALID_HANDLE_VALUE)
DWORD dwWrite = 0;
DWORD dwRet = WriteFile(m_hComm,data,len,&dwWrite,NULL);
//清空串口
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR); if(!dwRet)
{
MessageBox(NULL,_T("发送数据失败"),_T("提示"),MB_OK);
//发送数据
BOOL SendData(char* data,int len); public: HANDLE m_hComm; };
Serial.cpp
#include "StdAfx.h"
#include "Serial.h"
#include<process.h>
typedef unsigned (__stdcall *PTHREAD_START) (void *);
dcb.ByteSize = date_bits;
//数据位。范围4-8
dcb.StopBits = ONESTOPBIT;
//停止位
if(parity == NOPARITY)
{
dcb.fParity = FALSE;
//奇偶校验。无奇偶校验
dcb.Parity = parity;
//校验模式。无奇偶校验
//是否使用发送错误协议
dcb.fNull = FALSE;
//停用null stripping
dcb.fRtsControl = RTS_CONTROL_ENABLE;//
dcb.fAbortOnError = FALSE;
//串口发送错误,并不终止串口读写
//设置串口参数
if (!SetCommState(m_hComm,&dcb))
{
if(m_hComm == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,_T("串口未打开"),_T("提示"),MB_OK);
return FALSE;
}
//清空串口
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR);
//写串口
串口通信的基本步骤
(1)通过CreateFile(“COMx:“,…)打开串口
(2)通过配置DCB结构体和SetCommState函数,设置串口的参数。
(3)通过ReadFile()和WriteFile读写串口
Windows串口通信实例
封装了一个串口通信的C++类CSerial,通过CSerial类的OpenSerialPort()可以打开一个串口,串口打开后后自动新建线程读取串口数据,并通过MessageBox简单的显示出数据。通过CSerial类的SendData()方法可以向串口发送数据。
return FALSE;
}
return TRUE;
}
主程序ManipulateCom.cpp
#include<windows.h>
#include "Serial.h"
#include<string.h>
Intmain(int argc, _TCHAR* argv[])
{Fra Baidu bibliotek
CSerial serial; serial.OpenSerialPort(_T("COM2:"),9600,8,1);
DCB dcb;
if(!GetCommState(m_hComm,&dcb))
{
MessageBox(NULL,_T("获取串口当前属性参数失败"),_T("提示"),MB_OK);
}
//配置串口参数
dcb.BaudRate = baud_rate;
//波特率
dcb.fBinary = TRUE;
//二进制模式。必须为TRUE
} /******************************************************************************************** *功能:通过串口发送一条数据********************************************************************************************/ BOOL CSerial::SendData(char* data,int len)
_stprintf(err,_T("打开串口%s失败,请查看该串口是否已被占用"),port); MessageBox(NULL,err,_T("提示"),MB_OK);
return FALSE;
} //
MessageBox(NULL,_T("打开成功"),_T("提示"),MB_OK);
//获取串口默认配置
{
BOOL bReadOK = ReadFile(pSerial->m_hComm,buf,512,&dwRead,NULL); if(bReadOK && (dwRead > 0))
{ buf[dwRead] = '\0';
MessageBoxA(NULL,buf,"串口收到数据",MB_OK);
{
//打开串口m_hComm = CreateFile(port,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
//独占方式打开串口
TCHAR err[512];
if(m_hComm == INVALID_HANDLE_VALUE)
{
主函数中,新建了一个CSerial类对象,打开串口2,然后简单的通过一个消息框循环来控制向串口不断的发送数据。
程序的效果图如下:
使用虚拟串口工具虚拟出串口对COM2和COM3,本实例程序读写COM2,使用串口调试助手打开COM3。
->在“是否向串口发送数据”消息框中,点击”是(Y)”会向串口发送一条”This is a example”数据。如图,在串口调试助手中收到该数据包
//DTR控制
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;//
dcb.fOutX = FALSE;
//是否使用XON/XOFF协议
dcb.fInX = FALSE;
//是否使用XON/XOFF协议
dcb.fErrorChar = FALSE;
}
Else
{
dcb.fParity = TRUE;
//奇偶校验。
dcb.Parity = parity;
//校验模式。无奇偶校验
}
dcb.fOutxCtsFlow = FALSE;
//CTS线上的硬件握手
dcb.fOutxDsrFlow = FALSE;
//DST线上的硬件握手
dcb.fDtrControl = DTR_CONTROL_ENABLE;
//向串口发送数据
char* data = "This is a example\n";
int ret = 1;
while(ret != IDNO )
{
serial.SendData(data,strlen(data));
ret = MessageBox(NULL,_T(""),_T("是否向串口发送数据"),MB_YESNO);
{ MessageBox(NULL,_T("设置串口参数失败"),_T("提示"),MB_OK);
return FALSE;
}
//设置串口事件
SetCommMask(m_hComm,EV_RXCHAR);
//在缓存中有字符时产生事件
SetupComm(m_hComm,16384,16384);
//设置串口读写时间
}
}
return 0;
} /******************************************************************************************* *功能:打开串口* port :串口号,如_T("COM1:") * baud_rate:波特率* date_bits:数据位(有效范围4~8)* stop_bit :停止位* parity :奇偶校验。默认为无校验。NOPARITY 0;ODDPARITY 1;EVENPARITY 2;MARKPARITY 3;SPACEPARITY 4 ********************************************************************************************/ BOOL CSerial::OpenSerialPort(TCHAR* port,UINT baud_rate,BYTE date_bits,BYTE stop_bit,BYTE parity)
{
MessageBox(NULL,_T("设置串口时间失败"),_T("提示"),MB_OK); return FALSE;
}
//创建线程,读取数据HANDLE hReadCommThread = (HANDLE)
_beginthreadex(NULL,0,(PTHREAD_START) CommProc,(LPVOID) this,0,NULL); return TRUE;
->在串口调试助手中,手动发送”jarvischu”,程序会读取到该数据并弹出消息框显示。
源码如下:
Serial.h
#pragma once
#include class CSerial {
public:
CSerial(void);
~CSerial(void);
//打开串口
BOOL OpenSerialPort(TCHAR* port,UINT baud_rate,BYTE date_bits,BYTE stop_bit,BYTE parity=NOPARITY);
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(m_hComm,&CommTimeOuts); CommTimeOuts.ReadIntervalTimeout = MAXDWORD; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 10; CommTimeOuts.WriteTotalTimeoutConstant = 1000; if(!SetCommTimeouts(m_hComm,&CommTimeOuts))
//YES继续发送一条数据,NO不发送,退出
}
return 0;
}
CSerial::CSerial(void)
{
m_hComm = INVALID_HANDLE_VALUE;
}
CSerial::~CSerial(void) {
if(m_hComm != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hComm);
}
} /********************************************************************************************* *功能:读串口线程回调函数*描述:收到数据后,简单的显示出来********************************************************************************************/ DWORD WINAPI CommProc(LPVOID lpParam)
{
CSerial* pSerial = (CSerial*)lpParam; //
//清空串口
PurgeComm(pSerial->m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR);
char buf[512];
DWORD dwRead; while(pSerial->m_hComm != INVALID_HANDLE_VALUE)
DWORD dwWrite = 0;
DWORD dwRet = WriteFile(m_hComm,data,len,&dwWrite,NULL);
//清空串口
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR); if(!dwRet)
{
MessageBox(NULL,_T("发送数据失败"),_T("提示"),MB_OK);
//发送数据
BOOL SendData(char* data,int len); public: HANDLE m_hComm; };
Serial.cpp
#include "StdAfx.h"
#include "Serial.h"
#include<process.h>
typedef unsigned (__stdcall *PTHREAD_START) (void *);
dcb.ByteSize = date_bits;
//数据位。范围4-8
dcb.StopBits = ONESTOPBIT;
//停止位
if(parity == NOPARITY)
{
dcb.fParity = FALSE;
//奇偶校验。无奇偶校验
dcb.Parity = parity;
//校验模式。无奇偶校验
//是否使用发送错误协议
dcb.fNull = FALSE;
//停用null stripping
dcb.fRtsControl = RTS_CONTROL_ENABLE;//
dcb.fAbortOnError = FALSE;
//串口发送错误,并不终止串口读写
//设置串口参数
if (!SetCommState(m_hComm,&dcb))
{
if(m_hComm == INVALID_HANDLE_VALUE)
{
MessageBox(NULL,_T("串口未打开"),_T("提示"),MB_OK);
return FALSE;
}
//清空串口
PurgeComm(m_hComm,PURGE_RXCLEAR|PURGE_TXCLEAR);
//写串口
串口通信的基本步骤
(1)通过CreateFile(“COMx:“,…)打开串口
(2)通过配置DCB结构体和SetCommState函数,设置串口的参数。
(3)通过ReadFile()和WriteFile读写串口
Windows串口通信实例
封装了一个串口通信的C++类CSerial,通过CSerial类的OpenSerialPort()可以打开一个串口,串口打开后后自动新建线程读取串口数据,并通过MessageBox简单的显示出数据。通过CSerial类的SendData()方法可以向串口发送数据。
return FALSE;
}
return TRUE;
}
主程序ManipulateCom.cpp
#include<windows.h>
#include "Serial.h"
#include<string.h>
Intmain(int argc, _TCHAR* argv[])
{Fra Baidu bibliotek
CSerial serial; serial.OpenSerialPort(_T("COM2:"),9600,8,1);
DCB dcb;
if(!GetCommState(m_hComm,&dcb))
{
MessageBox(NULL,_T("获取串口当前属性参数失败"),_T("提示"),MB_OK);
}
//配置串口参数
dcb.BaudRate = baud_rate;
//波特率
dcb.fBinary = TRUE;
//二进制模式。必须为TRUE
} /******************************************************************************************** *功能:通过串口发送一条数据********************************************************************************************/ BOOL CSerial::SendData(char* data,int len)
_stprintf(err,_T("打开串口%s失败,请查看该串口是否已被占用"),port); MessageBox(NULL,err,_T("提示"),MB_OK);
return FALSE;
} //
MessageBox(NULL,_T("打开成功"),_T("提示"),MB_OK);
//获取串口默认配置
{
BOOL bReadOK = ReadFile(pSerial->m_hComm,buf,512,&dwRead,NULL); if(bReadOK && (dwRead > 0))
{ buf[dwRead] = '\0';
MessageBoxA(NULL,buf,"串口收到数据",MB_OK);
{
//打开串口m_hComm = CreateFile(port,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
//独占方式打开串口
TCHAR err[512];
if(m_hComm == INVALID_HANDLE_VALUE)
{
主函数中,新建了一个CSerial类对象,打开串口2,然后简单的通过一个消息框循环来控制向串口不断的发送数据。
程序的效果图如下:
使用虚拟串口工具虚拟出串口对COM2和COM3,本实例程序读写COM2,使用串口调试助手打开COM3。
->在“是否向串口发送数据”消息框中,点击”是(Y)”会向串口发送一条”This is a example”数据。如图,在串口调试助手中收到该数据包
//DTR控制
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;//
dcb.fOutX = FALSE;
//是否使用XON/XOFF协议
dcb.fInX = FALSE;
//是否使用XON/XOFF协议
dcb.fErrorChar = FALSE;
}
Else
{
dcb.fParity = TRUE;
//奇偶校验。
dcb.Parity = parity;
//校验模式。无奇偶校验
}
dcb.fOutxCtsFlow = FALSE;
//CTS线上的硬件握手
dcb.fOutxDsrFlow = FALSE;
//DST线上的硬件握手
dcb.fDtrControl = DTR_CONTROL_ENABLE;