串口通信示例

前面我写了一篇博客介绍了使用串口通信,这里我给大家写一个示例:
这里我只写必要的部分。

头文件.h

typedef struct  
{
    BYTE*               pFile;
    BYTE*               byEnterCmd;
    BYTE*               byEraseCmd;
    ULONGLONG iTotal;
    int                 iPort;
    UINT                uiAddr;
    int                 iFlag;
}SendProcStruct;

typedef struct  
{
    int nErrorFlag;
    int nUart;
} ReturnValue;

#define WM_PROGRESS WM_USER+1000

// CSerialCommDlg dialog
class CSerialCommDlg : public CDialog
{
    ......

public:
    afx_msg void OnBnClickedBtnOpenserial();

    afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
    //static int UpdateProc(LPVOID iComPort );
    BOOL SearchBin( int iFilesize );
    void ShowDeviceInfo(BOOL bRepeat);
    int GetPort(vector<int>& vctPort);
    CComboBox m_comboLanguage;
    afx_msg void OnCbnSelendcancelComboLan();

    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    CStatic m_staticFilePath;


    int                     ReadBinFile( );
    BYTE*                   m_pFile;
    ULONGLONG   m_iTotal;
    BYTE                    m_byteEnterCmd[9];
    BYTE                    m_byteEraseCmd[9];
    UINT                    m_uiAddr;
    int                     m_iDuring, m_iBinFileType, m_iFileLen_Bin, m_iFileLen_Aut, m_iFlag;
    UINT                    m_uiFileOffset;
    vector<int>     m_vctCommPort;
    afx_msg void OnDestroy();


    void DeleteFileBuffer();
    afx_msg void OnCbnSelchangeComboEqp119();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    CComboBox m_comboEQP119;
    afx_msg void OnStnClickedStaticSerial();
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);

    afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam);

    BOOL        m_bWriteBusy;
};
#include "Serial.h"


vector<int> g_vctComPort;
vector<int> g_vctUnkonwnComPort;
vector<int> g_vctComPortOK;
vector<int> g_vctComPortFail;
int         g_iComPortIdx=0;

CString         g_strDeviceName=_T("");
CString         g_strBinName=_T("");
CString         g_strBinPath=_T("");
CString         g_strCurrentLanguage=_T("EN");
BOOL            g_bDeviceDetected;
DWORD           g_dwDeviceChange=-1;
BOOL            g_bOneEnter=TRUE;///
BYTE*           g_pFile=NULL;

extern CFont* g_DisplayFont16;

DEFINE_GUID (UsbClassGuid, 0xa5dcbf10L, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed);

CSerialCommDlg::CSerialCommDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CSerialCommDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    g_pFile=NULL;
    m_iTotal=0;
    m_iDuring=0, m_iBinFileType=0, m_iFileLen_Bin=0, m_iFileLen_Aut=0, m_iFlag=0;
    m_uiFileOffset = 0;
    m_bWriteBusy=FALSE;
}

void CSerialCommDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_COMBO_LAN, m_comboLanguage);
    DDX_Control(pDX, IDC_STATIC_FILEPATH, m_staticFilePath);
    DDX_Control(pDX, IDC_COMBO_EQP119, m_comboEQP119);
}

BEGIN_MESSAGE_MAP(CSerialCommDlg, CDialog)
    ......
    ON_WM_DEVICECHANGE()
    ON_BN_CLICKED(IDC_BTN_OPENSERIAL, &CSerialCommDlg::OnBnClickedBtnOpenserial)
    ON_CBN_SELENDCANCEL(IDC_COMBO_LAN, &CSerialCommDlg::OnCbnSelendcancelComboLan)
    ON_WM_LBUTTONDOWN()
    ON_WM_DESTROY()
    ON_CBN_SELCHANGE(IDC_COMBO_EQP119, &CSerialCommDlg::OnCbnSelchangeComboEqp119)
    ON_STN_CLICKED(IDC_STATIC_SERIAL, &CSerialCommDlg::OnStnClickedStaticSerial)
    ON_WM_RBUTTONDOWN()
    ON_MESSAGE(WM_PROGRESS, &CSerialCommDlg::OnProgress)
    ON_CBN_SELCHANGE(IDC_COMBO_LAN, &CSerialCommDlg::OnCbnSelchangeComboLan)
END_MESSAGE_MAP()

// CSerialCommDlg message handlers
BOOL CSerialCommDlg::OnInitDialog()
{
    ......  
    // TODO: Add extra initialization here  
    SetDlgItemText(IDC_STATIC_TISHI, _T("先选择要烧录的语言和产品(NT301/NT201/NT204/NT1001/EQP119/LASER 等产品),然后再选择要烧录的文件(.bin或者 .Aut)"));
    SetDlgItemText(IDC_STATIC_LAN, _T("语言:"));
    SetDlgItemText(IDC_STATIC_EQP119, _T("产品:"));
    SetDlgItemText(IDC_STATIC_SERIAL, _T("可烧录设备串口有:"));
    SetDlgItemText(IDC_STATIC_UNKONWN, _T("未识别串口:"));

    SetDlgItemText(IDC_STATIC_FILEPATH, _T("鼠标点击此区域,打开要烧录的bin文件"));
    SetDlgItemText(IDC_BTN_OPENSERIAL, _T("开始烧录"));

    SetDlgItemText(IDC_STATIC_OK, _T("烧写完成串口:"));
    SetDlgItemText(IDC_STATIC_FAIL, _T("烧写失败串口:"));

    OnDeviceChange(0,0);
    m_comboLanguage.SetCurSel(0);
    m_comboEQP119.SetCurSel(0);
    GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(FALSE);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void ShowError(/*HWND hWnd, */int iError)
{
    switch (iError)
    {
    case 1: MessageBox( NULL, _T("Read file error."), _T("提示"), MB_OK); break;
    case 2: MessageBox( NULL, _T("Wrong file detected."), _T("提示"), MB_OK); break;
    case -1:    MessageBox( NULL, _T("-1 串口打开失败."), _T("提示"), MB_OK);   break;
    case -2:    MessageBox( NULL, _T("-2 通信失败"), _T("提示"), MB_OK);  break;
    case -3:    MessageBox( NULL, _T("-3 通信失败"), _T("提示"), MB_OK);  break;
    case -4:    MessageBox( NULL, _T("-4 通信失败"), _T("提示"), MB_OK);  break;
    case -5:    MessageBox( NULL, _T("-5 通信失败"), _T("提示"), MB_OK);  break;
    case -6:    MessageBox( NULL, _T("-6 通信失败"), _T("提示"), MB_OK);  break;
    case -7:    MessageBox( NULL, _T("-7 通信失败"), _T("提示"), MB_OK);  break;
    case -8:    MessageBox( NULL, _T("-8 通信失败"), _T("提示"), MB_OK);  break;
    case -9:    MessageBox( NULL, _T("-9 通信失败"), _T("提示"), MB_OK);  break;
    case -10:   MessageBox( NULL, _T("-10 通信失败"), _T("提示"), MB_OK); break;
    case -11:   MessageBox( NULL, _T("-11 通信失败"), _T("提示"), MB_OK); break;
    case -12:   MessageBox( NULL, _T("-12 通信失败"), _T("提示"), MB_OK); break;
    case -13:   MessageBox( NULL, _T("-13 通信失败"), _T("提示"), MB_OK); break;
    default:break;
    }
}
// iFlag  1:单个文件升级   2:多个文件升级のBin   3:多个文件升级Aut
ReturnValue SendProc( BYTE* pFile,BYTE* byEnterCmd,BYTE* byEraseCmd,int iTotal,int iPort,UINT uiAddr,int iFlag )
{
    //////////////////////////////////////////////////////////////////////////打开串口
    CSerial m_serial;
    ReturnValue rv;
    rv.nErrorFlag=0;
    rv.nUart=iPort;
    if (!m_serial.Open( iPort, 115200))
    {
        rv.nErrorFlag=-1;
        return rv;
    }

    ///////////////////////////////////////////////////C9问产品类型(如foxwell-NT301)
    BYTE byTypeCmd[] = {0x00,0x00,0x00};
    BYTE* byRecv = new BYTE[PACK_SIZE];
    int iRet = m_serial.MySendData(byTypeCmd,3,100,byRecv);
    if (iRet <= 8)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-2;
        return rv;
    }
    else if((byRecv[0] != '0')||(byRecv[1] != '0')||(byRecv[2] != '0')||(byRecv[3] != '0')||(byRecv[4] != '0')||(byRecv[5] != '0')||(byRecv[6] != '0')||(byRecv[7] != '0'))///文件头检测
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-3;
        return rv;
    }
    ////////////////////////////A0进入升级模式   回复0xA1 进入升级模式OK
    iRet = m_serial.MySendData( byEnterCmd,9,100,byRecv);
    if (iRet <= 2)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-4;
        return rv;
    }
    else if(byRecv[2] != 0x00)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-5;
        return rv;
    }
    //////////////////////////A2开始擦除   回复0xA3 设备擦除OK
    iRet = m_serial.MySendData( byEraseCmd,9,50000,byRecv);
    if (iRet <= 2)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-6;
        return rv;
    }
    else if(byRecv[2] != 0x00)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-7;
        return rv;
    }
    //////////////////开始循环发送升级数据   (A1设置地址和数据大小   回复0xA2地址和数据大小OK) + (2054bytes   回复0xA4当前帧数据升级OK)
    BYTE btFromFile[PACK_SIZE+6] = {0};
    int iCount = 0, uiSize = 0;
    BYTE byCmdAddrSize[] = {0x46,0x58,0xC1,0x00,0x40,0x00,0x08,0x06,0x08,0xFF};

    while (1)
    {
        uiSize =  iTotal - iCount*PACK_SIZE;
        if(uiSize > PACK_SIZE)
            uiSize = PACK_SIZE;

        //////////////////////////////////发送          aa 55 c1 ( 00 48 00 08 ) ( 06 08 ) ff
        byCmdAddrSize[3] = ( uiAddr&0x000000FF)>>0;
        byCmdAddrSize[4] = ( uiAddr&0x0000FF00)>>8;
        byCmdAddrSize[5] = ( uiAddr&0x00FF0000)>>16;
        byCmdAddrSize[6] = ( uiAddr&0xFF000000)>>24;//Addr
        byCmdAddrSize[7] = ((uiSize+6)&0x000000FF)>>0;
        byCmdAddrSize[8] = ((uiSize+6)&0x0000FF00)>>8;//Size
        iRet = m_serial.MySendData(byCmdAddrSize,10,100,byRecv);
        if (iRet <= 2)
        {
            delete[] byRecv;
            byRecv=NULL;
            m_serial.Close();
            rv.nErrorFlag=-8;
            return rv;
        }
        else if(byRecv[2] != 0x00)
        {
            delete[] byRecv;
            byRecv=NULL;
            m_serial.Close();
            rv.nErrorFlag=-9;
            return rv;
        }

        //////////////////////////////////////////////////////////////////////////发送文件内容        
        memcpy(btFromFile,  pFile+iCount*PACK_SIZE,uiSize);
        UINT uiCheckSum = 0;
        for (int iByte = 0 ; iByte < uiSize ; iByte ++)
            uiCheckSum += btFromFile[iByte];
        btFromFile[uiSize+0] = (uiCheckSum&0x000000FF)>>0;
        btFromFile[uiSize+1] = (uiCheckSum&0x0000FF00)>>8;
        btFromFile[uiSize+2] = (uiCheckSum&0x00FF0000)>>16;
        btFromFile[uiSize+3] = (uiCheckSum&0xFF000000)>>24;
        btFromFile[uiSize+4] = (iCount&0x0000FF00)>>8;
        btFromFile[uiSize+5] = (iCount&0x000000FF)>>0;

        iRet = m_serial.MySendData(btFromFile,uiSize+6,100,byRecv);
        if (iRet <= 2)
        {
            delete[] byRecv;
            byRecv=NULL;
            m_serial.Close();
            rv.nErrorFlag=-10;
            return rv;
        }
        else if(byRecv[2] != 0x00)
        {
            delete[] byRecv;
            byRecv=NULL;
            m_serial.Close();
            rv.nErrorFlag=-11;
            return rv;
        }
         uiAddr += PACK_SIZE;
        iCount ++;
        memset(btFromFile, 0,PACK_SIZE);
        if(uiSize < PACK_SIZE)
            break;

    }
    ///////////////////////////////////////////////A3所有数据传输完指令    回复0x85升级成功
    BYTE byCmdSuccess[] = {0x00,0x00,0x00,0xFF};
    iRet = m_serial.MySendData(byCmdSuccess,4,100,byRecv);
    if (iRet <= 2)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-12;
        return rv;
    }
    else if(byRecv[2] != 0x85)
    {
        delete[] byRecv;
        byRecv=NULL;
        m_serial.Close();
        rv.nErrorFlag=-13;
        return rv;
    }

    delete[] byRecv;
    byRecv=NULL;
    m_serial.Close();
    return rv;
}

int CSerialCommDlg::ReadBinFile(  )
{
    g_pFile=NULL;
    m_iTotal=0;
    m_iDuring=0, m_iBinFileType=0, m_iFileLen_Bin=0, m_iFileLen_Aut=0, m_iFlag=0;
    m_uiFileOffset = 0;

    CFile fileBin;  
    if(fileBin.Open(g_strBinPath, CFile::modeRead | CFile::typeBinary))
    {
        m_iTotal = fileBin.GetLength();

        g_pFile = new BYTE[m_iTotal];
        int iRead = fileBin.Read(g_pFile, m_iTotal);
        fileBin.Close();
        if(iRead != m_iTotal)           return 1;
    }
    else
        return 1;

    //////////////////////////////////////////解密
    for (int iDec = 0 ; iDec < m_iTotal ; iDec ++)
    {
        g_pFile[iDec] = g_pFile[iDec]^0x00^0x00;
    }

    /////////////////////////////////////////////验证文件
    UINT uiSize = 0;

    m_iBinFileType = (g_pFile[10]<<24) + (g_pFile[9]<<16) + (g_pFile[8]<<8) + g_pFile[7];
    if(m_iBinFileType == 1)//Bin
    {
        m_iFileLen_Bin = (g_pFile[14]<<24) + (g_pFile[13]<<16) + (g_pFile[12]<<8) + g_pFile[11];
        m_iDuring = 1;
    }
    if(m_iBinFileType == 2)//Aut
    {
        m_iFileLen_Aut = (g_pFile[14]<<24) + (g_pFile[13]<<16) + (g_pFile[12]<<8) + g_pFile[11];
        m_iDuring = 2;
    }
    if(m_iBinFileType == 3)//Bin + Aut
    {
        m_iFileLen_Bin = (g_pFile[14]<<24) + (g_pFile[13]<<16) + (g_pFile[12]<<8) + g_pFile[11];
        m_iFileLen_Aut = (g_pFile[18]<<24) + (g_pFile[17]<<16) + (g_pFile[16]<<8) + g_pFile[15];
        m_iDuring = 1;
    }

    BOOL bVerify = FALSE;
    if((g_pFile[0] == '0')&&(g_pFile[1] == '0')&&(g_pFile[2] == '0')&&(g_pFile[3] == '0')&&(g_pFile[4] == '0')&&(g_pFile[5] == '0')&&(g_pFile[6] == '0'))
    {
        if((m_iBinFileType > 0)&&(m_iBinFileType < 4))
        {
            int iVerifySum = 0;
            int iVerifySumInFile = (g_pFile[m_iTotal - 1]<<24) + (g_pFile[m_iTotal - 2]<<16) + (g_pFile[m_iTotal - 3]<<8) + g_pFile[m_iTotal - 4];
            for(int iV = 0 ; iV < (m_iTotal - 4) ; iV ++)
                iVerifySum += g_pFile[iV];
            if(m_iFileLen_Bin)
            {
                iVerifySum += m_iFileLen_Bin;
                iVerifySum -= (m_iFileLen_Bin&0x000000FF);
                iVerifySum -= ((m_iFileLen_Bin&0x0000FF00)>>8);
                iVerifySum -= ((m_iFileLen_Bin&0x00FF0000)>>16);
                iVerifySum -= ((m_iFileLen_Bin&0xFF000000)>>24);
            }
            if(m_iFileLen_Aut)
            {
                iVerifySum += m_iFileLen_Aut;
                iVerifySum -= (m_iFileLen_Aut&0x000000FF);
                iVerifySum -= ((m_iFileLen_Aut&0x0000FF00)>>8);
                iVerifySum -= ((m_iFileLen_Aut&0x00FF0000)>>16);
                iVerifySum -= ((m_iFileLen_Aut&0xFF000000)>>24);
            }
            if(iVerifySum == iVerifySumInFile)
                bVerify = TRUE;
        }
    }
    if(!bVerify)        return 2;

    //////////////////////////////////////////////////////计算好变量
    m_uiAddr = 0x08004000;
    m_iTotal = m_iFileLen_Bin;

    g_pFile += 15;
    m_uiFileOffset += 15;
    if(m_iBinFileType == 3)
    {
        g_pFile += 4;
        m_uiFileOffset += 4;
    }
    ///////////////////////////////////////////////////////
    if(m_iBinFileType == 3)
        m_iFlag = 2;
    else
        m_iFlag = 1;

    return 0;
}

UINT UpdateProc( LPVOID lParam)///向设备中写入数据 烧写程序
{
    CSerialCommDlg* pSerialDlg= (CSerialCommDlg*)lParam;    
    BYTE g_byteEnterCmd[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF};
    BYTE g_byteEraseCmd[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF};
    int nUart=g_vctComPort[g_iComPortIdx++];

    UINT uiAddr = 0x08004000;
    if(pSerialDlg->m_iDuring == 2)
    {
        g_byteEnterCmd[3] = 0x05;
        g_byteEnterCmd[4] = 0x04;
        g_byteEnterCmd[6] = 0x02;
        g_byteEnterCmd[7] = 0x01;

        g_byteEraseCmd[4] = 0x00;
        g_byteEraseCmd[6] = 0x00;
        g_byteEraseCmd[7] = 0x00;
        uiAddr = 0;
        pSerialDlg->m_iTotal = pSerialDlg->m_iFileLen_Aut;
    }
    ReturnValue rvSendRet = SendProc(g_pFile, g_byteEnterCmd, g_byteEraseCmd, pSerialDlg->m_iTotal, nUart, uiAddr, pSerialDlg->m_iFlag );
    if (rvSendRet.nErrorFlag < 0)
    {
        ShowError( rvSendRet.nErrorFlag);
        g_vctComPortFail.push_back(rvSendRet.nUart);
        pSerialDlg->SendMessage(WM_PROGRESS, 0, rvSendRet.nErrorFlag);
    }
    else
    {
        if(pSerialDlg->m_iBinFileType == 3)
        {       
            g_byteEnterCmd[3] = 0x05;
            g_byteEnterCmd[4] = 0x04;
            g_byteEnterCmd[6] = 0x02;
            g_byteEnterCmd[7] = 0x01;

            g_byteEraseCmd[4] = 0x00;
            g_byteEraseCmd[6] = 0x00;
            g_byteEraseCmd[7] = 0x00;
            uiAddr = 0;
            pSerialDlg->m_iTotal = pSerialDlg->m_iFileLen_Aut;

            ReturnValue rvSendRet = SendProc( g_pFile+pSerialDlg->m_iFileLen_Bin , g_byteEnterCmd, g_byteEraseCmd, pSerialDlg->m_iTotal, nUart, uiAddr, pSerialDlg->m_iFlag );
            if (rvSendRet.nErrorFlag < 0)
            {
                ShowError( rvSendRet.nErrorFlag);
                g_vctComPortFail.push_back(rvSendRet.nErrorFlag);
                pSerialDlg->SendMessage(WM_PROGRESS, 0, rvSendRet.nErrorFlag);
            }
            else
            {
                g_vctComPortOK.push_back( rvSendRet.nUart );
                pSerialDlg->SendMessage(WM_PROGRESS, rvSendRet.nUart, 0);
            }
        }
    }
    return 0;
}

UINT UpdateEndProc( LPVOID lparam)///find zp 20170109 向设备中写入数据
{
    while (1)
    {
        if (g_vctComPort.size()==g_vctComPortFail.size())
        {
            ::MessageBox( NULL, _T("烧录失败!!!"), _T("错误"), MB_OK );
            break;
        }
        if (g_vctComPort.size()==g_vctComPortOK.size()+g_vctComPortFail.size())//说明已经升级完成
        {
            ::MessageBox( NULL ,_T("烧录完成"),_T("提示"),MB_OK);
            break;
        }
        Sleep(3000);
    }
    return 0;
}

void CSerialCommDlg::OnBnClickedBtnOpenserial()
{
    m_bWriteBusy=TRUE;

    g_iComPortIdx=0;
    g_vctUnkonwnComPort.clear();
    g_vctComPortOK.clear();
    g_vctComPortFail.clear();

    //////////////////////////////////////////////////////////////////////////读取文件
    if (g_pFile)
    {
        DeleteFileBuffer();
    }
    if (!g_pFile )
    {
        int iRet = ReadBinFile( );
        if (iRet > 0)
            ShowError( iRet);
    }
    if (g_pFile)
    {
        GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(FALSE);
        //////////////////////////////////////////////////////////////////////////烧写文件到设备中
        for (int i=0; i< g_vctComPort.size(); i++)
        {       
            AfxBeginThread(UpdateProc, (LPVOID)this, THREAD_PRIORITY_NORMAL);
        }   
        ///烧写完成
        AfxBeginThread(UpdateEndProc, (LPVOID)this,  THREAD_PRIORITY_NORMAL);
    }   
}

BOOL CSerialCommDlg::SearchBin( int iFilesize )//XX001_V1.00_EN_20170323.bin
{
    CString strDevice = _T("");
    if(!g_strBinName.GetLength())
    {
        AfxMessageBox(_T("请选择要烧录的bin文件"));
        return FALSE;
    }
    CString strTemp=_T("");
    strTemp=g_strBinName.Mid(0, g_strBinName.Find('_') );

    strDevice=strTemp;
    g_strDeviceName=strTemp;
    if(!strDevice.GetLength())
    {
        AfxMessageBox(_T("没有识别到设备"));
        return FALSE;
    }

    strDevice.MakeUpper();
    g_strCurrentLanguage.MakeUpper();

    CString strDeviceBin = g_strBinName.Left(strDevice.GetLength());
    CString strLanguageBin = g_strBinName.Right(15);
    CString strDateBin = g_strBinName.Right(12);
    strDateBin = strDateBin.Left(4) + _T("/") + strDateBin.Mid(4,2) + _T("/") + strDateBin.Mid(6,2);
    strLanguageBin = strLanguageBin.Left(2);
    strDeviceBin.MakeUpper();
    strLanguageBin.MakeUpper();

    if((strDevice == strDeviceBin)&&(g_strCurrentLanguage == strLanguageBin))
    {
        int iBinLen = g_strBinName.GetLength();
        int iDeviceLen = strDeviceBin.GetLength();
        CString strVersion = g_strBinName.Mid(iDeviceLen + 1,iBinLen - iDeviceLen - 17);
        CString strFilesize = _T("");
        if(iFilesize >= 1048576)
            strFilesize.Format(_T("%.2f MB"),(float)iFilesize/1048576);
        else if(iFilesize >= 1024)
            strFilesize.Format(_T("%.2f KB"),(float)iFilesize/1024);
        else
            strFilesize.Format(_T("%.1f B"),(float)iFilesize);  
        return TRUE;
    }
    else
    {
        if(g_strCurrentLanguage != strLanguageBin)
            AfxMessageBox(_T("语言错误,请重新选择语言或者bin文件"));

        return FALSE;
    }
    return TRUE;
}
///检测设备变更的系统 API 函数
BOOL CSerialCommDlg::OnDeviceChange(UINT nEventType,DWORD dwData)
{
    DWORD dwTime = ::GetTickCount();
    int iSpan = 0;
    if(g_dwDeviceChange != -1)
        iSpan = dwTime - g_dwDeviceChange;
    g_dwDeviceChange = dwTime;
    if(iSpan <= 1000)
        ShowDeviceInfo(TRUE);
    else
        ShowDeviceInfo(FALSE);

    BOOL bRes = TRUE,bRet = FALSE;
    HDEVINFO hDevInfo;
    SP_DEVICE_INTERFACE_DATA spDevData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
    int nCount = 0;
    hDevInfo = ::SetupDiGetClassDevs((LPGUID)&UsbClassGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
    if (hDevInfo != INVALID_HANDLE_VALUE)
    {
        pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT,1024);
        pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        while (bRes)
        {           
            spDevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
            bRes = ::SetupDiEnumDeviceInterfaces(hDevInfo,NULL,(LPGUID)&UsbClassGuid,nCount,&spDevData);
            if (bRes)
            {
                bRes = ::SetupDiGetInterfaceDeviceDetail(hDevInfo,&spDevData,pDetail,1024,NULL,NULL);
                if (bRes)
                {
                    CString szStr = pDetail->DevicePath;
                    szStr.MakeLower();
                    nCount ++;
                    if(szStr.Find(_T("#vid_0000&pid_0000#")) != -1)///设备驱动 硬件ID
                    {
                        bRet = TRUE;
                        break;
                    }
                }
            }
        }
        ::GlobalFree(pDetail);
        ::SetupDiDestroyDeviceInfoList(hDevInfo);
    }
    if(bRet)
    {
        if(g_strDeviceName.GetLength())///设备没有烧写程序
        {
            SetDlgItemText(IDC_STATIC_DEVICEINFO, _T("设备连接成功"));
            if (g_pFile )
                GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(TRUE);
        }
        else///设备已经烧写程序,需要重复/重新烧写
        {
            SetDlgItemText(IDC_STATIC_DEVICEINFO, _T("设备连接成功......"));
            if (g_pFile )
                GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(TRUE);
            else
                GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(FALSE);
        }
    }
    else
    {
        SetDlgItemText(IDC_STATIC_DEVICEINFO, _T("没有设备连接。"));//No device connected.
        SetDlgItemText(IDC_STATIC_OK, _T("烧写完成串口:"));
        SetDlgItemText(IDC_STATIC_FAIL, _T("烧写失败串口:"));
    }
    return TRUE;
}

void CSerialCommDlg::ShowDeviceInfo(BOOL bRepeat)
{
    g_vctComPort.clear();
    vector <int> vctPort;
    int iCntGet = GetPort(vctPort);

    for(int i = 0 ; i < iCntGet ; i ++)
    {
        CSerial m_serial;
        if (m_serial.Open(vctPort[i], 115200))//COM  BaudRate
        {
            BYTE byTypeCmd[] = {0x00,0x01,0x02};//发送一组命令,来确认硬件设备
            BYTE* byRecv = new BYTE[PACK_SIZE];
            if(m_serial.MySendData(byTypeCmd,3,100,byRecv) > 8)
            {
                string strDevice = (char*)byRecv;
                g_strDeviceName = string2CString(strDevice);
                g_strDeviceName= g_strDeviceName.Mid( g_strDeviceName.Find('-')+1, g_strDeviceName.GetLength() );//foxwell-NT301-->NT301

                g_vctComPort.push_back(vctPort[i]);
            }
            delete[] byRecv;
            byRecv=NULL;
            m_serial.Close();
        }
    }
    if(vctPort.size() > 0)
    {   
        CString strCommPort=_T("");
        for (int k=0; k<g_vctComPort.size(); k++)//可用串口
        {           
            strCommPort.AppendFormat(_T(" %d, "), g_vctComPort[k]);
        }
        SetDlgItemText(IDC_STATIC_PORT, strCommPort);
        strCommPort=_T("");
        for (int k=0;k<g_vctUnkonwnComPort.size();k++)//未知串口
        {
            strCommPort.AppendFormat(_T(" %d, "), g_vctUnkonwnComPort[k]);
        }
        SetDlgItemText(IDC_STATIC_UNKONWNPORT, strCommPort);
    }
    else
    {
        if(bRepeat && (g_strDeviceName.GetLength()))
            return;
        g_strDeviceName = _T("");
        SetDlgItemText(IDC_STATIC_PORT, _T(""));
        SetDlgItemText(IDC_STATIC_UNKONWNPORT, _T(""));
        SetDlgItemText(IDC_STATIC_DEVICEINFO,_T("没有设备连接."));//No device connected.
    }
}
// 得到串口号
int CSerialCommDlg::GetPort(vector<int>& vctPort)
{
    vctPort.clear();
    HKEY hKEY;//定义有关的hKEY,在查询结束时要关闭
    //打开与路径data_Set相关的hKEY
    LPCTSTR data_Set=_T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\");

    //访问注册表,hKEY则保存此函数所打开的键的句柄
    long ret0=(::RegOpenKeyEx(HKEY_LOCAL_MACHINE,data_Set,NULL,KEY_READ,&hKEY));
    if(ret0 != ERROR_SUCCESS)//如果无法打开hKEY,则中止程序的执行
        return 0;

    for(int i = 0; i < 256; i++)
    {
        //查询有关的数据
        LPBYTE owner_Get=new BYTE[80];//定义用户姓名owner_Get
        ZeroMemory(owner_Get,80);
        DWORD type_1=REG_SZ;//定义数据类型
        DWORD cbData_1=80;//定义数据长度

        CString str=_T("");
        str.Format(_T("\\Device\\USBSER%03d"),i); 
        long ret1=::RegQueryValueEx(hKEY, str, NULL, &type_1, owner_Get, &cbData_1);
        if (ret1==0) 
        {
            CString strUsbSer = _T("");
            strUsbSer.Format(_T("%s"),owner_Get+6);
            int mm = _ttoi(strUsbSer);
            vctPort.push_back(mm);
        }
        delete[] owner_Get;
        owner_Get = NULL;
    }
    //程序结束,关闭打开的hKEY
    ::RegCloseKey(hKEY);
    return vctPort.size();
}


void CSerialCommDlg::OnCbnSelendcancelComboLan()
{
    // TODO: Add your control notification handler code here
    //英语;德语;俄语;法语;西班牙语;意大利语;葡萄牙语;荷兰语;波兰语;瑞典语;匈牙利语;
    int iSelCur=m_comboLanguage.GetCurSel();
    switch (iSelCur)
    {
    case 0:
        g_strCurrentLanguage="EN";      break;
    case 1:
        g_strCurrentLanguage="CN";      break;  
    default:
        g_strCurrentLanguage="EN";      break;
    }
}

void CSerialCommDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    //DeleteFileBuffer();
    // TODO: Add your message handler code here and/or call default
    CRect filePathRt;
    GetDlgItem(IDC_STATIC_FILEPATH)->GetWindowRect(&filePathRt);//获取控件基于全屏的位置
    ScreenToClient(filePathRt);//转换为对话框上的相对位置
    if (filePathRt.PtInRect(point) && !m_bWriteBusy)
    {
        // 设置过滤器   
        TCHAR szFilter[] = _T("二进制文件(*.bin)|*.bin|二进制文件(*.AUT)|*.AUT|所有文件(*.*)|*.*||");   
        // 构造打开文件对话框   
        CFileDialog fileDlg(TRUE, _T("bin"), NULL, 0, szFilter, this);   
        CString strFilePath;   

        // 显示打开文件对话框   
        if (IDOK == fileDlg.DoModal())   
        {
            // 如果点击了文件对话框上的“打开”按钮,则将选择的文件路径显示到编辑框里   
            strFilePath = fileDlg.GetPathName();   
            SetDlgItemText(IDC_STATIC_FILEPATH, strFilePath);
            g_strBinPath=strFilePath;//bin文件全路径
            g_strBinName=g_strBinPath.Mid(g_strBinPath.ReverseFind('\\')+1, g_strBinPath.GetLength());          
        }
        //////////////////////////////////////////////////////////////////////////得到文件大小
        ULONGLONG size;
        CFileStatus fileStatus;
        if (CFile::GetStatus(g_strBinPath, fileStatus))
        {
            size = fileStatus.m_size;
        }
        //////////////////////////////////////////////////////////////////////////加载文件
        BOOL bRet = SearchBin(size);
        if (!bRet)
            return;

        SetDlgItemText(IDC_STATIC_DEVICEINFO, _T("设备连接成功---") + g_strDeviceName);//Device connected.
        GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(TRUE);
//      //读取文件
//      if (g_pFile)
//      {
//          DeleteFileBuffer();
//      }
//      if (!g_pFile )
//      {
//          int iRet = ReadBinFile( );
//          if (iRet > 0)
//              ShowError( iRet);
//          else
//              GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(TRUE);
//      }       
    }

    CDialog::OnLButtonDown(nFlags, point);
}

void CSerialCommDlg::OnDestroy()
{
    CDialog::OnDestroy();
    // TODO: Add your message handler code here
    DeleteFileBuffer();
}
void CSerialCommDlg::DeleteFileBuffer()
{   
    if(g_pFile)
    {
        g_pFile -= m_uiFileOffset;
        delete[] g_pFile;
        g_pFile = NULL;
    }
}

HBRUSH CSerialCommDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    // TODO:  Change any attributes of the DC here
    if(pWnd->GetDlgCtrlID()==IDC_STATIC_TISHI)  
    {  
        pDC->SelectObject(g_DisplayFont16);    // 设置字体  
        pDC->SetTextColor(RGB(255,0,0));    // 设置颜色  
    }
    if (pWnd->GetDlgCtrlID()==IDC_STATIC_FAIL)
    {
        pDC->SelectObject(g_DisplayFont16);
        pDC->SetTextColor(RGB(255,0,0));    // 设置颜色  
    }
    if (pWnd->GetDlgCtrlID()==IDC_STATIC_UNKONWNPORT)
    {
        pDC->SelectObject(g_DisplayFont16);
        pDC->SetTextColor(RGB(255,0,0));    // 设置颜色  
    }
    if (pWnd->GetDlgCtrlID()==IDC_STATIC_FILEPATH)
    {
        pDC->SelectObject(g_DisplayFont16);
        pDC->SetTextColor(RGB(255,0,0));    // 设置颜色  
    }
    if (pWnd->GetDlgCtrlID()==IDC_STATIC_DEVICEINFO)
    {
        pDC->SelectObject(g_DisplayFont16);
        pDC->SetTextColor(RGB(250,22,133));    // 设置颜色  
    }
    // TODO:  Return a different brush if the default is not desired
    return hbr;
}

///显示烧写进度
LRESULT CSerialCommDlg::OnProgress(WPARAM wParam, LPARAM lParam)
{
    int nOK=0, nFail=0;
    CString strOK=_T("");
    CString strFail=_T("");

    nOK=(int)wParam;
    nFail=(int)lParam;
    if (nOK > 0)
    {
        GetDlgItemText(IDC_STATIC_OK, strOK);
        strOK.AppendFormat(_T("%d"), nOK);
        SetDlgItemText(IDC_STATIC_OK, strOK);
    }

    if (nFail > 0)
    {
        GetDlgItemText(IDC_STATIC_OK, strFail);
        strOK.AppendFormat(_T("%d"), strFail);
        SetDlgItemText(IDC_STATIC_FAIL, strFail);
    }   
    m_bWriteBusy=FALSE;
    GetDlgItem(IDC_BTN_OPENSERIAL)->EnableWindow(TRUE);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值