⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.cpp

📁 wince 下的串口编程
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
  
//
  
////////////////
#include "stdafx.h"
#include "Serial.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////
// Construction/Destruction
CSerial::CSerial()
{
	m_hPort = INVALID_HANDLE_VALUE;
}

CSerial::~CSerial()
{
	if(m_hPort != INVALID_HANDLE_VALUE) {
		ClosePort();
	}
}

BOOL CSerial::OpenPort(CString lpszPortName)
{
    if(m_hPort != INVALID_HANDLE_VALUE) {		//如果hport为0说明串口没有打开
		MessageBox (NULL, TEXT("You have opened the communication prot!"), 
		TEXT("Error!"), MB_OK);
		return FALSE;
	}

    //打开串口
    m_hPort = CreateFile (lpszPortName, GENERIC_READ|GENERIC_WRITE,
				0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
    //如果打开端口出错, 返回FALSE
    if ( m_hPort == INVALID_HANDLE_VALUE ) {
    //不能打开端口
    CString strError;
    strError.Format(_T("Can't open  %s, Error No.=%d"), 
             lpszPortName, GetLastError());  
	MessageBox (NULL, strError,TEXT("Error!"), MB_OK);
        return FALSE;
	}
    //指定端口监测的事件集
    //SetCommMask (m_hPort, EV_RXCHAR|EV_TXEMPTY);
 
    //配置串行端口
	if(!InitDCB())
		return FALSE;

	//设置端口超时值
    if(!InitCommTimeouts())
		return FALSE;

   //分配设备缓冲区  
    SetupComm(m_hPort, 512, 512);
    //初始化缓冲区中的信息
    PurgeComm(m_hPort, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
	///设置端口上指定信号的状态
	// SETDTR: 发送DTR (data-terminal-ready)信号
	// SETRTS: 发送RTS (request-to-send)信号
	EscapeCommFunction(m_hPort,SETDTR);
	EscapeCommFunction(m_hPort,SETRTS);

#if 0
   //创建一个从串口读取数据的线程
	if (hReadThread = CreateThread (NULL, 0, ReadPortThread, 0, 0,&dwThreadID)) {
		CloseHandle(hReadThread);
	} else {
		//不能创建线程
		MessageBox (NULL, TEXT("Can't create thread!"), 
		TEXT("Error!"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
#endif 
//    m_bConnected=TRUE;//程序返回真时就必是初始化成功,所以这个变量其实不需要,以节省内存
     return TRUE;
}


DWORD CSerial::WritePort(BYTE *pBuf, DWORD dwLen)
{
	DWORD dwWritten = 0;
    //写入数据
	PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
	BOOL ret = WriteFile(m_hPort, pBuf, dwLen, &dwWritten, NULL);
	if(ret == FALSE) {		//不能写数据
		MessageBox(NULL,TEXT("You can't write the data to the port!"),TEXT("Error!"),MB_OK);
		dwWritten =0;
	}
//	CString str;
//	str.Format(_T("write %d bytes \n"), dwWritten);
//	MessageBox(NULL,str,TEXT("Error!"),MB_OK);

//	PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
	return dwWritten;
}

DWORD CSerial::ReadPort(BYTE *pBuf, DWORD dwLen)
{
	DWORD dwRead = 0;

	BOOL ret = ReadFile(m_hPort, pBuf, dwLen, &dwRead, NULL);
	if (ret == FALSE) {
		MessageBox(NULL,TEXT("Can't Read data from the port!"),TEXT("Error!"),MB_OK);
		dwRead =0;
	}
//	PurgeComm(m_hPort, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
	return dwRead;
}

BOOL CSerial::ClosePort()
{
	if (m_hPort != INVALID_HANDLE_VALUE) {
		//结束线程中WaitCommEvent的等待
		SetCommMask(m_hPort,0);
		//阻塞至线程停止

		//清除端口上指定信号的状态
		EscapeCommFunction(m_hPort,CLRDTR);
		EscapeCommFunction(m_hPort,CLRRTS);
		//清除驱动程序内部的发送和接收队列
		PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
		//关闭串口
		CloseHandle (m_hPort);
		m_hPort = INVALID_HANDLE_VALUE;		//使串口句柄恢复到初始状态
	}
	return TRUE;
}

HANDLE CSerial::GetHandle()
{
	return m_hPort;
}

BOOL CSerial::InitDCB()
{
	DCB PortDCB;//声明一个DCB结构
	DWORD dwError;
	PortDCB.DCBlength = sizeof (DCB);//初始化 DCBlength

     //得到端口的默认设置信息
     GetCommState (m_hPort, &PortDCB);

	//改变DCB结构设置
    PortDCB.BaudRate = 9600; //波特率 
    PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE 
	PortDCB.ByteSize = 8;
	PortDCB.fOutxCtsFlow = FALSE;
	PortDCB.Parity =  NOPARITY;
	PortDCB.StopBits = ONESTOPBIT;
	PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
    PortDCB.fOutxCtsFlow = FALSE; //串行端口的输出由CTS线控制
    PortDCB.fOutxDsrFlow = FALSE;//关闭串行端口的DSR流控制
    PortDCB.fDtrControl = DTR_CONTROL_DISABLE; //启用DTR线
 
 #if 0  PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用 
    PortDCB.fTXContinueOnXoff = TRUE;//当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
    PortDCB.fTXContinueOnXoff = FALSE;
    PortDCB.fOutX = FALSE;//设为TRUE指定XON/XOFF控制被用于控制串行输出 
    PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入 
    PortDCB.fErrorChar = FALSE;//WINCE串行驱动程序的默认执行将忽略这个字段 
    PortDCB.fNull = FALSE;//设为TRUE将使串行驱动程序忽略收到的空字节 
    PortDCB.fRtsControl = RTS_CONTROL_ENABLE; //启用RTS线 
    PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段

	PortDCB.fOutxCtsFlow = TRUE;
	PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
    PortDCB.ByteSize = 8; //每字节的位数 
    PortDCB.Parity = NOPARITY;//无奇偶校验 
    PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位 
  #endif   //根据DCB结构配置端口
    if (!SetCommState (m_hPort, &PortDCB)) {	//不能配置串行端口
        MessageBox (NULL, TEXT("Unable to configure the serial port!"), 
             TEXT("Error!"), MB_OK);
        dwError = GetLastError ();//获得错误原因的代码
        return FALSE;
	}
    return TRUE;
}

BOOL CSerial::InitCommTimeouts()
{
    COMMTIMEOUTS CommTimeouts;//声明一个COMMTIMEOUTS结构
    DWORD dwError;
    //得到超时参数
    GetCommTimeouts (m_hPort, &CommTimeouts);
    //改变COMMTIMEOUTS结构设置
	//不使用这个逾时功能,ReadFile直到所有字符接收完才会返回
    CommTimeouts.ReadIntervalTimeout = 0;
    CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    CommTimeouts.ReadTotalTimeoutConstant = 1000;
	//不使用这个逾时功能,WriteFile直到所有字符接收完才会返回
    CommTimeouts.WriteTotalTimeoutMultiplier = 0;
    CommTimeouts.WriteTotalTimeoutConstant=0;
    //设置端口超时值  
    if (!SetCommTimeouts(m_hPort,&CommTimeouts)) {     //不能设置超时值  
       MessageBox (NULL, TEXT("Unable to set the time-out parameters!"),
				TEXT("Error!"), MB_OK);
       dwError = GetLastError ();//获得错误原因的代码
       return FALSE;
	}
    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -