www.pudn.com > NEWMeter.rar > ReadMeterDlg.cpp


// ReadMeterDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "ReadMeter.h" 
#include "ReadMeterDlg.h" 
#include "Resource.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
 
class CAboutDlg : public CDialog 
{ 
public: 
	CAboutDlg(); 
 
// Dialog Data 
	//{{AFX_DATA(CAboutDlg) 
	enum { IDD = IDD_ABOUTBOX }; 
	//}}AFX_DATA 
 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CAboutDlg) 
	protected: 
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
	//}}AFX_VIRTUAL 
 
// Implementation 
protected: 
	//{{AFX_MSG(CAboutDlg) 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
	//{{AFX_DATA_INIT(CAboutDlg) 
	//}}AFX_DATA_INIT 
} 
 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CAboutDlg) 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
	//{{AFX_MSG_MAP(CAboutDlg) 
		// No message handlers 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CReadMeterDlg dialog 
 
CReadMeterDlg::CReadMeterDlg(CWnd* pParent /*=NULL*/) 
	: CDialog(CReadMeterDlg::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CReadMeterDlg) 
	m_strRXData = _T(""); 
	//}}AFX_DATA_INIT 
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 
 
void CReadMeterDlg::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CReadMeterDlg) 
	DDX_Control(pDX, IDC_BUTTON2, m_ReadClass2); 
	DDX_Control(pDX, IDC_BUTTON17, m_ReadClass17); 
	DDX_Control(pDX, IDC_BUTTON14, m_ReadClass14); 
	DDX_Control(pDX, IDC_BUTTON12, m_ReadClass12); 
	DDX_Control(pDX, IDC_BUTTON0, m_ReadClass0); 
	DDX_Control(pDX, IDCANCEL, m_Cancel); 
	DDX_Control(pDX, IDC_Read, m_Read); 
	DDX_Control(pDX, IDC_MSCOMM, m_msComm); 
	DDX_Text(pDX, IDC_EDIT1, m_strRXData); 
	//}}AFX_DATA_MAP 
} 
 
BEGIN_MESSAGE_MAP(CReadMeterDlg, CDialog) 
	//{{AFX_MSG_MAP(CReadMeterDlg) 
	ON_WM_SYSCOMMAND() 
	ON_WM_PAINT() 
	ON_WM_QUERYDRAGICON() 
	ON_BN_CLICKED(IDC_Read, OnRead) 
	ON_BN_CLICKED(IDC_BUTTON0, OnButton0) 
	ON_BN_CLICKED(IDC_BUTTON12, OnButton12) 
	ON_BN_CLICKED(IDC_BUTTON14, OnButton14) 
	ON_BN_CLICKED(IDC_BUTTON17, OnButton17) 
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CReadMeterDlg message handlers 
 
BOOL CReadMeterDlg::OnInitDialog() 
{ 
	CDialog::OnInitDialog(); 
 
	// Add "About..." menu item to system menu. 
 
	// IDM_ABOUTBOX must be in the system command range. 
	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); 
		} 
	} 
 
	// Set the icon for this dialog.  The framework does this automatically 
	//  when the application's main window is not a dialog 
	SetIcon(m_hIcon, TRUE);			// Set big icon 
	SetIcon(m_hIcon, FALSE);		// Set small icon 
	 
 
	// TODO: Add extra initialization here 
	if(m_msComm.GetPortOpen()) 
		m_msComm.SetPortOpen(FALSE); 
 
	m_msComm.SetCommPort(1);   //选择com1 
	if( !m_msComm.GetPortOpen()) 
		m_msComm.SetPortOpen(TRUE);//打开串口 
	else 
		AfxMessageBox("cannot open serial port"); 
 
	m_msComm.SetSettings("9600,n,8,1"); //波特率9600,无校验,8个数据位,1个停止位 
    m_msComm.SetRThreshold(1);  
	m_msComm.SetInputMode(1); //1--二进制方式 
	//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 
	m_msComm.SetInputLen(0);  //设置当前接收区数据长度为0 
	m_msComm.GetInput();//先预读缓冲区以清除残留数据 
	 
	return TRUE;  // return TRUE  unless you set the focus to a control 
} 
 
void CReadMeterDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
	if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
	{ 
		CAboutDlg dlgAbout; 
		dlgAbout.DoModal(); 
	} 
	else 
	{ 
		CDialog::OnSysCommand(nID, lParam); 
	} 
} 
 
// If you add a minimize button to your dialog, you will need the code below 
//  to draw the icon.  For MFC applications using the document/view model, 
//  this is automatically done for you by the framework. 
 
void CReadMeterDlg::OnPaint()  
{ 
	if (IsIconic()) 
	{ 
		CPaintDC dc(this); // device context for painting 
 
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
 
		// Center icon in client rectangle 
		int cxIcon = GetSystemMetrics(SM_CXICON); 
		int cyIcon = GetSystemMetrics(SM_CYICON); 
		CRect rect; 
		GetClientRect(&rect); 
		int x = (rect.Width() - cxIcon + 1) / 2; 
		int y = (rect.Height() - cyIcon + 1) / 2; 
 
		// Draw the icon 
		dc.DrawIcon(x, y, m_hIcon); 
	} 
	else 
	{ 
		CDialog::OnPaint(); 
	} 
} 
 
// The system calls this to obtain the cursor to display while the user drags 
//  the minimized window. 
HCURSOR CReadMeterDlg::OnQueryDragIcon() 
{ 
	return (HCURSOR) m_hIcon; 
} 
 
void CReadMeterDlg::OnRead()  
{ 
	// TODO: Add your control notification handler code here 
   // m_strRXData = ""; 
//	UpdateData(TRUE); 
  //	if(!Read_Class_11()) 
//	m_strRXData += "Fail to communication!\n"; 
//	UpdateData(FALSE); 
//	CalculateKey(0x00000000,0x00000000); 
	Read_Class_11(); 
	m_strRXData += "\r\n\r\n"; 
	UpdateData(FALSE); 
	 
} 
 
 
 
 
bool CReadMeterDlg::HandShake(int nPrtlCode, int nTryNum, unsigned char * ucMeterAdd) 
{ 
    //前面0x00表示握手次数,后面0x01表示表的设备号,暂时1初始化,然后根据实际的填写 
	//后面的2位为CRCH和CRCL。 
    unsigned char chrShakeHand[]={0x02,0x18,0x06,0x00,0x01,0x01,0x98,0x9e}; 
    CByteArray byteShakeHand,byteKey; 
   //chrKey[3]根据实际等待时间更改,步长0.5s 
   //chrKey[5]-chrKey[8]为加密计算后的密码,chrKey[9]和chrKey[10]为CRC校验 
   //初始化时,以上内容均为随意填写的 
   unsigned char chrKey[] ={0x02,0x18,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00}; 
   
   //ACK 
   unsigned char chrACK[] ={0x02,0x18,0x00,0x00,0x00,0x07,0xaa}; 
   unsigned int CRCCode; 
   unsigned char CRCH,CRCL; 
//   unsigned char err; 
   int i=0; 
   int tempTryNum = nTryNum; 
   long delaytime=0; 
 
   VARIANT variant_inp; 
   COleSafeArray safearray_inp; 
   LONG len,k; 
   BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed. 
   CString strtemp; 
 
  /* union  
   { 
	   unsigned long key; 
	   struct { 
		   unsigned char bytea,byteb,bytec,byted; 
	   }parts; 
   }val;*/ 
   unsigned long CalculatedKey,returnedKey=0; 
    
   if (nPrtlCode != 2) 
	   return false; 
	//chrShakeHand[3] = TransferTryNum(nTryNum); //计算每次的等待时间,步长0.5s 
   	CRCCode = CRCVerify(chrShakeHand,6); 
	CRCL = CRCCode & 0x00ff; 
	CRCH = (CRCCode >> 8) & 0x00ff; 
    chrShakeHand[6] = CRCH; 
    chrShakeHand[7] = CRCL; 
	for(i=0; i< 8;i++) 
	byteShakeHand.Add(chrShakeHand[i]); 
 
//	for(int i=0; i<8; i++) 
//	{ 
//		US_TXSEM.ucBuf[i] = chrShakeHand[i]; 
//   } 
//	US_TXSEM.lDataLen = 8; 
/*	for(i = nTryNum; i>0; i--) 
	{ 
		 
		m_msComm.SetOutput(COleVariant(byteShakeHand)); 
         delay(); 
		//		OSSemPost(US_TXSEM);    //发送握手指令 
//		do{ 
//			; 
//	       }while(m_msComm.GetCommEvent()!=2); 
//      SemPend(US_RXSEM, 500, &err);	 //等待串口的数据,等待的时间和握手中的填充数有关系 
//      if (err == OS_NO_ERR) // 在规定时间内收到数据 
     if(m_msComm.GetCommEvent()==2) 
	   { 
        break;  //退出循环,对接收的数据进行处理 
	   } 
      else   //在规定时间内没有收到数据 
	  { 
        if(i == 1) //如果已经尝试了足够次数,则放弃尝试,认为连接失败  
        { 
			return false; 
		} 
	  } 
	}*/ 
	do{ 
	m_strRXData += "===Send===\r\n";  
	UpdateData(FALSE); 
 	m_msComm.SetOutput(COleVariant(byteShakeHand)); 
    delay(8000); 
	UpdateTXT(chrShakeHand,8); 
	tempTryNum--; 
   // if(m_msComm.GetInBufferCount( )>=15) 
   //break; 
//	} 
 //获取报文中的密码 
//	delay(); 
//	if(m_msComm.GetInBufferCount( )>=15){ 
	variant_inp=m_msComm.GetInput();   //读缓冲区 
	safearray_inp=variant_inp;           //VARIANT型变量转换为ColeSafeArray型变量 
	len=safearray_inp.GetOneDimSize(); //得到有效数据长度 
	for(k=0;k>24 & 0x00000000ff; 
	  chrKey[6]=(CalculatedKey >>16) & 0x000000ff; 
	  chrKey[7]=(CalculatedKey >>8) & 0x000000ff; 
	  chrKey[8]=CalculatedKey & 0x000000ff; 
	  CRCCode = CRCVerify(chrKey,9); 
      CRCL = CRCCode & 0x00ff; 
      CRCH = (CRCCode >> 8) & 0x00ff; 
      chrKey[9] = CRCH; 
      chrKey[10] = CRCL; 
	  for(i=0;i<11;i++) 
	   byteKey.Add(chrKey[i]); 
//	  for(i=0; i<11; i++) 
//	{ 
//		US_TXSEM.ucBuf[i] = chrKey[i]; 
//	  } 
//	  	US_TXSEM.lDataLen = 11; 
//	for(i = nTryNum; i>0; i--) 
//	{ 
//	   OSSemPost(US_TXSEM);    //发送密码校验指令 
//       OSSemPend(US_RXSEM, 500, &err);	 //等待串口的数据,等待的时间和握手中的填充数有关系 
               
       m_strRXData += "===Send===\r\n";  
    	UpdateData(FALSE); 
   
	   m_msComm.SetOutput(COleVariant(byteKey)); 
        delay(8000); 
		UpdateTXT(chrKey,11); 
//		if (err == OS_NO_ERR) // 在规定时间内收到数据 
//    		{ 
//        break;  //退出循环,对接收的数据进行处理 
//	   } 
//      else   //在规定时间内没有收到数据 
//	  { 
 //       if(i == 1) //如果已经尝试了足够次数,则放弃尝试,认为连接失败  
 //      { 
 //    if(m_msComm.GetCommEvent()!=2) 
//		return false; 
//		} 
//	  }	 
//	 } 
	variant_inp=m_msComm.GetInput();   //读缓冲区 
	safearray_inp=variant_inp;           //VARIANT型变量转换为ColeSafeArray型变量 
	len=safearray_inp.GetOneDimSize(); //得到有效数据长度 
	for(k=0;k> 8) & 0x00ff; 
	chrRead[8] = CRCH; 
	chrRead[9] = CRCL; 
/*	  for(int i=0; i<10; i++) 
	{ 
		US_TXSEM.ucBuf[i] = chrRead[i]; 
	  } 
	  	US_TXSEM.lDataLen = 10; 
    OSSemPost(US_TXSEM);  
	OSSemPend(US_RXSEM, 500, &err); 
	if (err == OS_NO_ERR) 
		return true; 
	else */ 
		return false; 
} 
 
//断开连接 
void CReadMeterDlg::Disconnected() 
{ 
	unsigned char  chrDisconnect[] = {0x02,0x80, 0xf7,0xea}; 
	CByteArray byteDisconnect; 
	int i=0; 
	for(i=0;i<4;i++) 
		byteDisconnect.Add(chrDisconnect[i]); 
//	for(int i=0; i<4; i++) 
//	{ 
//		US_TXSEM.ucBuf[i] = chrDisconnect[i]; 
//	} 
//		US_TXSEM.lDataLen = 4; 
   //  OSSemPost(US_TXSEM); 
	m_strRXData += "===Send===\r\n";  
	m_msComm.SetOutput(COleVariant(byteDisconnect)); 
	UpdateTXT(chrDisconnect,4); 
	 	 
} 
 
//传入的重试次数超过255,则认为等同于0,被认为一直重试 
//unsigned char TransferTryNum(int nTryNum) 
//{ 
//	unsigned char chrTryNum; 
//	if(nTryNum >= 255) 
//		chrTryNum = 0x00; 
//   //nTryNum 为0-255, 
//	else 
//		chrTryNum = nTryNum; 
//	return chrTryNum; 
 
//} 
 
 
//CRC校验 
unsigned int CReadMeterDlg::CRCVerify(unsigned char CRCByte[], int len) 
{ 
  unsigned int iTemp=0;	  
  int i=0,j=0; 
  for (i=0; i>4) & 0x0f) * 10) > 255) 
	{ 
	 MeterAddNum = (MeterAddL & 0x0f) + ((MeterAddL>>4) & 0x0f) * 10; 
	} 
	else 
	 MeterAddNum = (MeterAddH & 0x0f) * 100 + (MeterAddL & 0x0f) + ((MeterAddL>>4) & 0x0f) * 10; 
	return MeterAddNum; 
} 
 
//加密口令字计算 
unsigned long CReadMeterDlg::CalculateKey(unsigned long key, unsigned long remotepwd) 
{ 
	int i,j,k=0; 
	union  
	{ 
		unsigned long tempkey; 
		struct { 
			unsigned char bytea,byteb,bytec,byted; 
		}tempparts; 
	}tempval; 
	unsigned long temppwd = remotepwd; 
	 
	tempval.tempkey = key; 
 
//	tempval.tempkey = 0x4b7eddc1;  
 
	tempval.tempkey += 0xab41; 
	i= tempval.tempparts.bytea +tempval.tempparts.byteb +tempval.tempparts.bytec+tempval.tempparts.byted; 
	i = i & 0x0f; 
	while(i>=0) { 
		if(tempval.tempparts.byted >= 0x80)  j=1; 
		else j=0; 
		tempval.tempkey = tempval.tempkey<<1 ; 
		tempval.tempkey += k; 
		k=j; 
		temppwd ^= tempval.tempkey; 
		i--; 
	} 
   return temppwd; 
} 
 
 bool CReadMeterDlg::Read_Class_11() 
 { 
	unsigned char chrReadClass11[] = {0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x0B,0x47,0x6a}; 
	unsigned char ucMeterAdd[] = {0x00,0x00,0x00}; 
	unsigned char chrContinRead[] = {0x02,0x81,0xe7,0xcb}; 
	CByteArray byteReadClass11, byteContinRead; 
	int nTryNum =10; 
	int nPtrlCode = 2;	 
    VARIANT m_input1; 
	COleSafeArray m_input2; 
	long length,i; 
	BYTE data[1024]; 
	CString str; 
	int totaltimes =1; 
	int k; 
	for(k=0;k<10;k++) 
		byteReadClass11.Add(chrReadClass11[k]); 
	for(k=0;k<4;k++) 
		byteContinRead.Add(chrContinRead[k]); 
	m_strRXData += "********** Read Class11 **********\r\n"; 
	UpdateData(FALSE); 
//	int nn=m_ctrlComm.GetCommEvent(); 
//	str.Format("%d",nn); 
//	AfxMessageBox(str);  
	bool success = HandShake(nPtrlCode, nTryNum, ucMeterAdd); 
//	if(!HandShake(nPtrlCode, nTryNum, ucMeterAdd)) //握手不成功 
    if(!success) 
	{  
		Disconnected(); 
		return false; 
	} 
    m_strRXData += "===Send===\r\n";  
    m_msComm.SetOutput(COleVariant(byteReadClass11)); 
	delay(4000); 
    UpdateTXT(chrReadClass11,10); 
//	 do{ 
//		; 
//	 }while(m_msComm.GetCommEvent()<42); 
		m_input1=m_msComm.GetInput();//读取缓冲区内的数据 
		m_input2=m_input1;//将VARIANT型变量转换为ColeSafeArray型变量 
		length=m_input2.GetOneDimSize();//确定数据长度 
		for(i=0;i0; totaltimes--) 
	{  
   
    m_msComm.SetOutput(COleVariant(byteContinRead)); 
   	delay(4000); 
	m_strRXData += "===Send===\r\n"; 
    UpdateTXT(chrContinRead,4); 
//	 do{ 
//		; 
//	 }while(m_msComm.GetCommEvent()<42); 
		m_input1=m_msComm.GetInput();//读取缓冲区内的数据 
		m_input2=m_input1;//将VARIANT型变量转换为ColeSafeArray型变量 
		length=m_input2.GetOneDimSize();//确定数据长度 
		for(i=0;i>4) & 0x0f)  > 9) 
		tempdataH = (char)(((temphexdata>>4) & 0x0f)-10 +'a'); 
	  else  
		tempdataH =(char)(((temphexdata >>4) & 0x0f)+'0'); 
 
	  if((temphexdata & 0x0f) > 9) 
		tempdataL = (char)((temphexdata & 0x0f)-10 +'a'); 
	  else  
		tempdataL =(char)((temphexdata & 0x0f)+'0'); 
 
	  m_strRXData +=tempdataH; 
	  m_strRXData +=tempdataL; 
	  m_strRXData +=" "; 
	  } 
   m_strRXData +="\r\n"; 
   UpdateData(FALSE); 
    
 } 
 
//read_class_0 
 bool CReadMeterDlg::Read_Class_0() 
 { 
	unsigned char chrReadClass0[] = {0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0xf6,0x01}; 
	unsigned char ucMeterAdd[] = {0x00,0x00,0x00}; 
	CByteArray byteReadClass0; 
	int nTryNum =10; 
	int nPtrlCode = 2;	 
    VARIANT m_input1; 
	COleSafeArray m_input2; 
	long length,i; 
	BYTE data[1024]; 
	CString str; 
	int totaltimes =1; 
	int k; 
	for(k=0;k<10;k++) 
		byteReadClass0.Add(chrReadClass0[k]); 
	m_strRXData += "********** Read Class0 **********\r\n"; 
	UpdateData(FALSE); 
//	int nn=m_ctrlComm.GetCommEvent(); 
//	str.Format("%d",nn); 
//	AfxMessageBox(str);  
	bool success = HandShake(nPtrlCode, nTryNum, ucMeterAdd); 
//	if(!HandShake(nPtrlCode, nTryNum, ucMeterAdd)) //握手不成功 
    if(!success) 
	{ 
	    Disconnected(); 
	    return false; 
	} 
    m_strRXData += "===Send===\r\n";  
    m_msComm.SetOutput(COleVariant(byteReadClass0)); 
	delay(8000); 
    UpdateTXT(chrReadClass0,10); 
		m_input1=m_msComm.GetInput();//读取缓冲区内的数据 
		m_input2=m_input1;//将VARIANT型变量转换为ColeSafeArray型变量 
		length=m_input2.GetOneDimSize();//确定数据长度 
		for(i=0;i0; totaltimes--) 
	{  
   
    m_msComm.SetOutput(COleVariant(byteContinRead)); 
   	delay(5000); 
	m_strRXData += "===Send===\r\n"; 
    UpdateTXT(chrContinRead,4); 
//	 do{ 
//		; 
//	 }while(m_msComm.GetCommEvent()<42); 
		m_input1=m_msComm.GetInput();//读取缓冲区内的数据 
		m_input2=m_input1;//将VARIANT型变量转换为ColeSafeArray型变量 
		length=m_input2.GetOneDimSize();//确定数据长度 
		for(i=0;i