基于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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值