串口操作——COM

串口通讯可以使用MFC控件,但是vs2010里边默认不带串口控件。
串口通讯也可以通过文件来操作,用的是Win32的API函数。
下边主要讲通过文件操作。
步骤:
一、打开串口

HANDLE hCom;  //串口句柄  
hCom = CreateFile(	s,//COM口  
					GENERIC_READ|GENERIC_WRITE, //允许读和写  
					0, //独占方式,不能共享  
					NULL,//安全属性  
					OPEN_EXISTING, //串口通讯必须为OPEN_EXISTING  
					0, //同步方式,FILE_FLAG_OVERLAPPED异步方式 
					NULL//串口通讯必须为NULL
					);  	
if( hCom==INVALID_HANDLE_VALUE )  
{  
	pDlg->MessageBox("打开串口失败!");     	
	return 0;  
} 

参数:
s:是个字符串,“COM1”,“COM2”,“COM3”,“COM4”,“COM5”等等,大小写均可。
串口操作必须用同步方式打开文件。

二、配置串口

//设置波特率
DCB dcb;
GetCommState(hCom, &dcb);	//先获取
((CComboBox*)pDlg->GetDlgItem(IDC_COMBO_BAUDRATE))->GetWindowText(s);
dcb.BaudRate = atoi(s);
dcb.Parity = 0;//校验方式为无校验
dcb.ByteSize = 8;//数据位为8位
dcb.StopBits = ONESTOPBIT;//停止位为1位
dcb.DCBlength = sizeof(DCB);//必须重新计算长度
SetCommState(hCom, &dcb);	//在设置
//设置接收间隔超时
COMMTIMEOUTS timeouts;
GetCommTimeouts(hCom, &timeouts);//先获取
timeouts.ReadIntervalTimeout = 1;//间隔超时1ms
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hCom, &timeouts);//再设置	

波特率的几个参数:
BaudRate :u32_t类型,比如:9600 ,19200等等
Parity :校验,0-4=None,Odd,Even,Mark,Space
ByteSize :数据位数,一般是8
StopBits :停止位,0,1,2 = 1, 1.5, 2

接收间隔超时的几个参数:
ReadIntervalTimeout:两字符之间最大的延时,毫秒单位。超时读函数立即返回。
ReadTotalTimeoutMultiplier:设置成0。
ReadTotalTimeoutConstant :接收总超时,毫秒单位。发出信息后,读取数据,会阻塞,这段时间内没有收到数据,读函数超时返回。
WriteTotalTimeoutMultiplier :设置成0。不使用写超时
WriteTotalTimeoutConstant :设置成0。不使用写超时

三、发送数据,
三项内容:设置接收总超时,清空内核发送缓冲,发送

//设置接收总超时
GetCommTimeouts(hCom, &timeouts);	
timeouts.ReadTotalTimeoutConstant = 1000;//1秒	
SetCommTimeouts(hCom, &timeouts);
PurgeComm(hCom, PURGE_TXCLEAR|PURGE_TXABORT);//清空内核发送缓冲
WriteFile( hCom, pDlg->m_pbSendBuf, i, &dwBytesWritten, NULL );//发送

参数:待发送数据指针,待发送数据个数,实际已发送数据个数指针(out)

四、接收数据
三项内容:清空内核接收缓冲,清空接收数组,读取串口数据

PurgeComm(hCom, PURGE_RXCLEAR|PURGE_RXABORT);//清空内核接收缓冲	
memset( pDlg->m_pbRecvBuf, 0, BUF_LEN );//清空接收缓冲区
ReadFile( hCom, pDlg->m_pbRecvBuf, BUF_LEN, &nLenOut, NULL);//读取串口,会阻塞,超时返回

参数:接收缓冲区,接收缓冲区长度,实际接收数据个数指针

五、关闭串口

CloseHandle(hCom);//关闭串口
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 C++ 中,我们可以使用串口类来进行串口通信。这里我们将自定义一个串口类,以便更好地理解串口通信的原理和实现。 首先,我们需要引入一些头文件: ```c++ #include <windows.h> #include <iostream> ``` 接着,我们定义一个串口类,其中包含了串口的打开、关闭、读取和写入等操作: ```c++ class SerialPort { public: SerialPort(); ~SerialPort(); bool Open(int portNo, int baudRate); bool Close(); int ReadData(char *buffer, unsigned int nbChar); bool WriteData(char *buffer, unsigned int nbChar); bool IsOpened() const; private: HANDLE m_hComm; bool m_bOpened; }; ``` 其中,m_hComm 是串口的句柄,m_bOpened 表示串口是否打开。 接下来,我们来实现这些操作。 首先是串口的打开操作: ```c++ bool SerialPort::Open(int portNo, int baudRate) { if (m_bOpened) { Close(); } char portName[50]; sprintf_s(portName, "\\\\.\\COM%d", portNo); m_hComm = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); if (m_hComm == INVALID_HANDLE_VALUE) { std::cerr << "Failed to open serial port!\n"; return false; } DCB dcb; GetCommState(m_hComm, &dcb); dcb.BaudRate = baudRate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; if (!SetCommState(m_hComm, &dcb)) { std::cerr << "Failed to set serial port parameters!\n"; CloseHandle(m_hComm); return false; } m_bOpened = true; return true; } ``` 这里我们首先判断串口是否已经打开,如果已经打开则先关闭,然后根据串口号构建串口名称,并使用 CreateFile 函数打开串口。接着,我们设置串口的参数,包括波特率、数据位、校验位和停止位等。如果设置成功,则将 m_bOpened 设置为 true 并返回 true,否则返回 false。 接下来是串口的关闭操作: ```c++ bool SerialPort::Close() { if (!m_bOpened) { return true; } if (CloseHandle(m_hComm)) { m_bOpened = false; return true; } return false; } ``` 这里我们只需要调用 CloseHandle 函数关闭串口,并将 m_bOpened 设置为 false 即可。 接下来是串口的读取操作: ```c++ int SerialPort::ReadData(char *buffer, unsigned int nbChar) { DWORD bytesRead; if (!ReadFile(m_hComm, buffer, nbChar, &bytesRead, nullptr)) { std::cerr << "Failed to read data from serial port!\n"; return -1; } return bytesRead; } ``` 这里我们使用 ReadFile 函数从串口读取数据,并将读取的字节数存储在 bytesRead 变量中,并返回 bytesRead。 最后是串口的写入操作: ```c++ bool SerialPort::WriteData(char *buffer, unsigned int nbChar) { DWORD bytesSent; if (!WriteFile(m_hComm, buffer, nbChar, &bytesSent, nullptr)) { std::cerr << "Failed to write data to serial port!\n"; return false; } return true; } ``` 这里我们使用 WriteFile 函数将数据写入串口,并返回写入是否成功的结果。 最后,我们来实现一个判断串口是否打开的函数: ```c++ bool SerialPort::IsOpened() const { return m_bOpened; } ``` 这里只需要返回 m_bOpened 即可。 至此,我们就完成了一个简单的自定义串口类。可以通过实例化这个类来进行串口通信的操作,具体使用方法可以参考下面的示例代码: ```c++ int main() { SerialPort port; if (!port.Open(1, 9600)) { return -1; } char buffer[1024]; while (true) { int bytesRead = port.ReadData(buffer, sizeof(buffer)); if (bytesRead > 0) { buffer[bytesRead] = '\0'; std::cout << buffer << std::endl; } } port.Close(); return 0; } ``` 在这个示例中,我们首先实例化了一个 SerialPort 类,并通过 Open 函数打开了 COM1 号串口。然后,我们通过 ReadData 函数从串口读取数据,并将读取的数据打印到控制台上。最后,我们通过 Close 函数关闭了串口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值