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

📄 sioport.c

📁 串口通讯
💻 C
字号:
// Serial.cpp

#include "sioport.h"
#include <windows.h>

#define BUFFER_SIZE (1024+16)

HANDLE g_hIDComDev = NULL;
BOOL   g_bOpened   = FALSE;
BOOL   g_nFlag;//同步还是异步,g_nFlag=1表示异步

OVERLAPPED g_OverlappedRead;
OVERLAPPED g_OverlappedWrite;


int CommIsOpened(void)
{
	return g_bOpened;
}

int CommOpen(int nPort, int nBaud,int nByteSize,int nParity,int nStopBits,int nFlag)
{
    char szPort[15];
    DCB  dcb;
    COMMTIMEOUTS CommTimeOuts;
    unsigned char ucSet;
	
    if (g_bOpened) return TRUE;

	if(nPort<=0 || nPort>255) return FALSE;

	g_nFlag=nFlag;

    wsprintf(szPort, "\\\\.\\COM%d", nPort);
	
	if(g_nFlag)
		g_hIDComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
	else
		g_hIDComDev = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (g_hIDComDev == INVALID_HANDLE_VALUE)
        return FALSE;

    memset(&g_OverlappedRead, 0, sizeof(OVERLAPPED));
    memset(&g_OverlappedWrite, 0, sizeof(OVERLAPPED));

    CommTimeOuts.ReadIntervalTimeout         = 0xFFFFFFFF;
    CommTimeOuts.ReadTotalTimeoutMultiplier  = 0;
    CommTimeOuts.ReadTotalTimeoutConstant    = 0;
    CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts.WriteTotalTimeoutConstant   = 5000;
	
    SetCommTimeouts(g_hIDComDev, &CommTimeOuts);

    dcb.DCBlength = sizeof(DCB);
    GetCommState(g_hIDComDev, &dcb);
    dcb.BaudRate = nBaud;
    dcb.ByteSize = nByteSize;
	dcb.StopBits=nStopBits;
    dcb.Parity   = nParity;

    ucSet = (unsigned char)((FC_RTSCTS & FC_DTRDSR) != 0);
    ucSet = (unsigned char)((FC_RTSCTS & FC_RTSCTS) != 0);
    ucSet = (unsigned char)((FC_RTSCTS & FC_XONXOFF) != 0);
	
    if (!SetCommState(g_hIDComDev, &dcb) ||
        !SetupComm(g_hIDComDev, BUFFER_SIZE, BUFFER_SIZE)
		)
    {
        DWORD dwError = GetLastError();
        CloseHandle(g_hIDComDev);

        return FALSE;
    }
	
	if(g_nFlag)
	{
		g_OverlappedRead.hEvent  = CreateEvent(NULL, TRUE, FALSE, NULL);
		g_OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		if(g_OverlappedRead.hEvent == NULL || g_OverlappedWrite.hEvent == NULL)
		{
			if (g_OverlappedRead.hEvent != NULL)
				CloseHandle(g_OverlappedRead.hEvent);
			if (g_OverlappedWrite.hEvent != NULL)
				CloseHandle(g_OverlappedWrite.hEvent);

			CloseHandle(g_hIDComDev);

			return FALSE;
		}
	}

    g_bOpened = TRUE;

    return g_bOpened;
}

int CommClose(void)
{
    if (!g_bOpened || g_hIDComDev == NULL)
        return TRUE;
    if (g_OverlappedRead.hEvent != NULL)
        CloseHandle(g_OverlappedRead.hEvent);
    if (g_OverlappedWrite.hEvent != NULL)
        CloseHandle(g_OverlappedWrite.hEvent);
    CloseHandle(g_hIDComDev);
    g_bOpened = FALSE;
    g_hIDComDev = NULL;

    return TRUE;
}

int CommWrite(void* ucByte, int len)
{
	BOOL bSuccessWrite=TRUE;
    BOOL bWriteStat;
    DWORD dwBytesWritten;

	if(!g_nFlag) 
	{
		bWriteStat=WriteFile(g_hIDComDev, (LPSTR)ucByte, len, &dwBytesWritten, NULL);
		if(bWriteStat) 
			return dwBytesWritten;
		else 
			return 0;
	}

    bWriteStat = WriteFile(g_hIDComDev, (LPSTR)ucByte, len, &dwBytesWritten, &g_OverlappedWrite);
	
	if (!bWriteStat)
	{
		//如果异步写入进行中
		if(GetLastError() == ERROR_IO_PENDING) 
		{
			//等待写入
			if(WaitForSingleObject(g_OverlappedWrite.hEvent, 2000)==WAIT_OBJECT_0)
			{
				if(GetOverlappedResult(g_hIDComDev, &g_OverlappedWrite, &dwBytesWritten, FALSE))
					g_OverlappedWrite.Offset += dwBytesWritten;
				else
					bSuccessWrite=FALSE;
			} 
			else bSuccessWrite=FALSE;
		}
		else bSuccessWrite=FALSE;
	}
	else//如果已全部成功写入
	{
        g_OverlappedWrite.Offset += dwBytesWritten;
	}

	//如果写入失败
	if(!bSuccessWrite) 
	{
		//清除已写入的数据
		PurgeComm(g_hIDComDev,PURGE_TXABORT | PURGE_TXCLEAR);
	}
	
	if(bSuccessWrite)
		return dwBytesWritten;
	else
		return 0;
}

int CommGetReadBufferSize(void)
{
    DWORD dwErrorFlags;
    COMSTAT ComStat;

    if (!g_bOpened || g_hIDComDev == NULL) 
        return 0 ;
	
	ComStat.cbInQue=0;

    if(ClearCommError(g_hIDComDev, &dwErrorFlags, &ComStat))
	{
		return (int)ComStat.cbInQue;
	}
	else 
	{
		return 0;
	}
}

int CommRead(void* buffer, int limit, int timeout)
{
	BOOL bSuccessRead=TRUE;
    BOOL bReadStatus;
    DWORD dwBytesRead;
	DWORD dwCount;

    if (!g_bOpened || g_hIDComDev == NULL) 
        return 0;

    dwCount = CommGetReadBufferSize();

	if(dwCount<=0) return 0;
	
    if (limit < (int)dwCount)
        dwBytesRead = (DWORD)limit;
	else 
		dwBytesRead=dwCount;

	if(!g_nFlag) 
	{
		bReadStatus = ReadFile(g_hIDComDev, buffer, dwBytesRead, &dwBytesRead, NULL);
		if(bReadStatus)
			return dwBytesRead;
		else 
			return 0;
	}

    bReadStatus = ReadFile(g_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &g_OverlappedRead);

    if (!bReadStatus) 
	{
		//如果异步读进行中
        if (GetLastError() == ERROR_IO_PENDING) 
		{
			//如果没有全部成功读出
            if(WaitForSingleObject(g_OverlappedRead.hEvent, timeout)==WAIT_OBJECT_0)
			{
				if(GetOverlappedResult(g_hIDComDev, &g_OverlappedRead, &dwBytesRead, FALSE))
				{
					g_OverlappedRead.Offset += dwBytesRead;
				}
				else 
				{
					bSuccessRead=FALSE;
					//printf("COM Read Data %d,Has Drop........................\r\n",dwBytesRead);
				}
			}
			else 
			{
				bSuccessRead=FALSE;
				//printf("COM Read Data timeout........................................\r\n");
			}
        }
		else bSuccessRead=FALSE;
    }
	
	//如果没有成功读出
	if(!bSuccessRead)
	{
		//清空已读出的数据
		dwBytesRead=0;
		PurgeComm(g_hIDComDev,PURGE_RXABORT | PURGE_RXCLEAR);
	}

	if(CommGetReadBufferSize()<=0) g_OverlappedRead.Offset=0;

    return (int)dwBytesRead;
}

void CommClear(void)
{
    if (!g_bOpened || g_hIDComDev == NULL) 
        return ;

	PurgeComm( g_hIDComDev, PURGE_TXCLEAR|PURGE_RXCLEAR);

	if(g_nFlag)
	{
		g_OverlappedRead.Offset=0;
		g_OverlappedWrite.Offset=0;
	}
}

⌨️ 快捷键说明

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