基於mfc的簡單的串口助手,發送接收

#pragma once
#include "Com.h"

class CComDlgDlg : public CDialog
{
// 構造
public:
    CComDlgDlg(CWnd* pParent = NULL);    // 標準構造函數

// 對話框數據
    enum { IDD = IDD_COMDLG_DIALOG };


    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 實現
protected:
    HICON m_hIcon;

    static void RecComData(BYTE *pdata, DWORD len);
    static HWND gHwndRec;
    static char *pRecStr;

    CCom *m_com;

    // 生成的消息映射函數
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedButton1();
};

 

//初始化串口

HWND CComDlgDlg::gHwndRec = NULL;
char* CComDlgDlg::pRecStr = NULL;

BOOL CComDlgDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // 將“關於...”菜單項添加到系統菜單中。

    // IDM_ABOUTBOX 必須在系統命令範圍內。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自動
    //  執行此操作
    SetIcon(m_hIcon, TRUE);            // 設置大圖標
    SetIcon(m_hIcon, FALSE);        // 設置小圖標

    // TODO: 在此添加額外的初始化代碼

    gHwndRec = m_hWnd;
    m_com = new CCom();
    m_com->OpenCom("COM5", 115200, RecComData);
    pRecStr = new char[32768];
    return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

//接收數據,在textbox裏面顯示

void CComDlgDlg::RecComData(BYTE *pdata, DWORD len)
{
    char *pTmp = pRecStr;
    int i, cnt,unit;
    cnt = ::GetDlgItemText(gHwndRec, IDC_EDIT_REC, (LPSTR)pRecStr, 32768);
    pTmp += cnt;
    do{
        unit = sprintf(pTmp, "%02X ", *pdata++);
        cnt += unit;
        if (cnt >= 32768)
        {
            memset(pRecStr, 0, 32768);
            pTmp = pRecStr;
            cnt = 0;
        }else pTmp += unit;
        if (cnt % 50 == 48)
        {
            unit = sprintf(pTmp, "\r\n");
            cnt += unit;
            if (cnt >= 32768)
            {
                memset(pRecStr, 0, 32768);
                pTmp = pRecStr;
                cnt = 0;
            }
            else pTmp += unit;
        }
    } while (--len);
    ::SetDlgItemText(gHwndRec, IDC_EDIT_REC, (LPSTR)pRecStr);
}

//發送數據

void CComDlgDlg::OnBnClickedButton1()
{
    // TODO: Add your control notification handler code here
    int len;
    BYTE str[1024];
    len=GetDlgItemText(IDC_EDIT_SEND, (char*)str, 1024);
    m_com->SendData(str, len);
}

 

 

//windows下面串口類,

// Com.cpp: implementation of the CCom class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "windows.h"
#include "string.h"
#include "com.h"
#pragma warning(disable:4996)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCom::CCom()
{
    //h_Semaphore=CreateSemaphore(NULL,1,1,NULL);
}

CCom::~CCom()
{
    CloseCom();
}

DWORD WINAPI CCom::ReadThread(LPVOID lpParam)
{
    BYTE *pReadData=NULL;
    DWORD dwRead=0;        //,dwErr;
    CCom *pCom=(CCom*)lpParam;
    BOOL ReadState;
    pCom->m_running=TRUE;
    pReadData=new BYTE[256];
    while(pCom->m_running==TRUE)
    {
        //系統讀出數據        
        ReadState=ReadFile(pCom->m_hcom,pReadData,256,&dwRead,&pCom->m_osReader);        
        if(!ReadState)
        {
            if(GetLastError()==ERROR_IO_PENDING)
            {
                //等待串口接收結果
                GetOverlappedResult(pCom->m_hcom,&pCom->m_osReader,&dwRead,TRUE);    
                ReadState=TRUE;
            }
        }
        if(ReadState && dwRead)
        {
            if(pCom->fnc!=NULL)    
                pCom->fnc(pReadData,dwRead);
        }
        else Sleep(1);
    }
    delete pReadData;
    return 1;
}

VOID CCom::CloseCom()
{
    if(m_running==TRUE)
    {
        m_running=FALSE;
        Sleep(5);
        CloseHandle(m_osReader.hEvent);
        CloseHandle(m_osWriter.hEvent);
        CloseHandle(m_hcom);
    }
}

DWORD CCom::SendData(const BYTE *src,DWORD len)
{
    DWORD dwWrite;
    BOOL bResult;
    if(m_running==FALSE)    return len;
    do{
        m_osWriter.Offset=0;
        m_osWriter.OffsetHigh=0;
        dwWrite=0;
        bResult=WriteFile(m_hcom,src,len,&dwWrite,&m_osWriter);
        if(!bResult)
        {
            if(GetLastError()==ERROR_IO_PENDING)
            {
                GetOverlappedResult(m_hcom,&m_osWriter,&dwWrite,TRUE);        //等待異步寫完成
                bResult=TRUE;
            }
        }
        len-=dwWrite;
        src+=dwWrite;
    }while(len && bResult==TRUE);
    return len;
}


BOOL CCom::OpenCom(LPCTSTR lpName, DWORD boud,VFNC recdeal)
{
    TCHAR portName[128];
    BOOL UsbMode=FALSE;
    portName[0]=0;
    strcat(portName,lpName);
    if(strlen(portName)==5)
    {
        TCHAR tmp[128]="\\\\.\\";
        strcat(tmp,portName);
        strcpy(portName,tmp);
    }
    m_hcom=CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);    
    if (m_hcom == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }
    else
    {
        DCB wdcb = {0};
        GetCommState(m_hcom, &wdcb);
        wdcb.BaudRate = boud;    
        wdcb.ByteSize = 8;        

        //設置串口參數
        SetCommState(m_hcom, &wdcb);
        //設置串口超時參數
        COMMTIMEOUTS toUsb =// 串口超時控制參數
        {
            1,        // 讀字符間隔超時時間
            1,        // 讀操作時每字符的時間
            100,        // 基本的(額外的)讀超時時間
            0,        // 寫操作時每字符的時間
            0        // 基本的(額外的)寫超時時間
        };

        COMMTIMEOUTS toNormal =// 串口超時控制參數
        {
            50,        // 讀字符間隔超時時間
            1,        // 讀操作時每字符的時間
            50,        // 基本的(額外的)讀超時時間
            2,        // 寫操作時每字符的時間
            100        // 基本的(額外的)寫超時時間
        };
        
        if(UsbMode==TRUE)    SetCommTimeouts(m_hcom, &toUsb);
        else                SetCommTimeouts(m_hcom, &toNormal);
        //設置串口緩衝隊列
        SetupComm(m_hcom, 1024, 1024);
        //清空並結束串口當前動作
        PurgeComm(m_hcom, PURGE_TXCLEAR | PURGE_RXCLEAR);
        fnc=recdeal;
        FillMemory(&m_osReader, sizeof(OVERLAPPED),0);    
        FillMemory(&m_osWriter, sizeof(OVERLAPPED),0);
        m_osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
        m_osWriter.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
        HANDLE hThread =CreateThread(NULL, 0, ReadThread, this, 0, &dwThreadID);
        CloseHandle(hThread);
    }
    return TRUE;
}

軟件運行截圖

源碼下載地址:https://download.csdn.net/download/ljxh401/11347798

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章