前面我写了一篇博客介绍了使用串口通信,这里我给大家写一个示例:
这里我只写必要的部分。
头文件.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;
}