⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odbccommview.cpp

📁 单片机和上位机通讯用软件,用vc**编译,已经通过使用,完全正确
💻 CPP
字号:
// ODBCCommView.cpp : implementation of the CODBCCommView class
//

#include "stdafx.h"
#include "ODBCComm.h"

#include "ODBCCommSet.h"
#include "ODBCCommDoc.h"
#include "ODBCCommView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CODBCCommView
#define CR '\r'
#define LF '\n'


	char m_chChecksum; //用于COM1的校验和计算
	CString m_strRXhhCOM1; //用于存放COM1接收的半BYTE校验字节hh
	CString m_strRXDataCOM1; //COM1接收数据
	CString m_strRXDataCOM2; //COM2接收数据
	UINT m_nRXErrorCOM1; //COM1接收数据错误帧数
	UINT m_nRXErrorCOM2; //COM2接收数据错误帧数
	UINT m_nRXCounterCOM1; //COM1接收数据错误帧数
	UINT m_nRXCounterCOM2; //COM2接收数据错误帧数CString 

	CSerialPort m_ComPort[2];

IMPLEMENT_DYNCREATE(CODBCCommView, CRecordView)

BEGIN_MESSAGE_MAP(CODBCCommView, CRecordView)
	//{{AFX_MSG_MAP(CODBCCommView)
	ON_BN_CLICKED(IDC_ADD, OnAdd)
	ON_BN_CLICKED(IDC_CLEAR, OnClear)
	ON_BN_CLICKED(IDC_DELETE, OnDelete)
	ON_MESSAGE(WM_COMM_RXCHAR, OnCommunication)
	ON_COMMAND(ID_SEND_DATA, OnSendData)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CRecordView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CRecordView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRecordView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CODBCCommView construction/destruction

CODBCCommView::CODBCCommView()
	: CRecordView(CODBCCommView::IDD)
{
	//{{AFX_DATA_INIT(CODBCCommView)
	m_pSet = NULL;
	//}}AFX_DATA_INIT
	// TODO: add construction code here

}

CODBCCommView::~CODBCCommView()
{
}

void CODBCCommView::DoDataExchange(CDataExchange* pDX)
{
	CRecordView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CODBCCommView)
	DDX_FieldText(pDX, IDC_EDIT_NAME, m_pSet->m_name, m_pSet);
	DDX_FieldText(pDX, IDC_EDIT_NUMBER, m_pSet->m_number, m_pSet);
	DDX_FieldText(pDX, IDC_EDIT_SCORE, m_pSet->m_score, m_pSet);
	//}}AFX_DATA_MAP
}

BOOL CODBCCommView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CRecordView::PreCreateWindow(cs);
}

void CODBCCommView::OnInitialUpdate()
{
	m_pSet = &GetDocument()->m_oDBCCommSet;
	CRecordView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();

	m_chChecksum=0; //校验和置0
	m_nRXErrorCOM1=0; //COM1接收数据错误帧数置0
	m_nRXErrorCOM2=0; //COM2接收数据错误帧数置0
	m_nRXCounterCOM1=0; //COM1接收数据错误帧数置0
	m_nRXCounterCOM2=0; //COM2接收数据错误帧数置0
	m_strRXhhCOM1.Empty(); //清空半BYTE校验hh存储变量
	for(int i=0; i<2; i++)
	{
		if(m_ComPort[i].InitPort(this,i+1,9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
		{
			m_ComPort[i].StartMonitoring(); //启动串口监视线程
		}
		else
		{
			CString str;
			str.Format("COM%d 没有发现,或被其它设备占用",i+1);
			AfxMessageBox(str);
		}
	}

}

/////////////////////////////////////////////////////////////////////////////
// CODBCCommView printing

BOOL CODBCCommView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CODBCCommView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CODBCCommView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CODBCCommView diagnostics

#ifdef _DEBUG
void CODBCCommView::AssertValid() const
{
	CRecordView::AssertValid();
}

void CODBCCommView::Dump(CDumpContext& dc) const
{
	CRecordView::Dump(dc);
}

CODBCCommDoc* CODBCCommView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CODBCCommDoc)));
	return (CODBCCommDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CODBCCommView database support
CRecordset* CODBCCommView::OnGetRecordset()
{
	return m_pSet;
}


/////////////////////////////////////////////////////////////////////////////
// CODBCCommView message handlers

void CODBCCommView::OnAdd() 
{
	// TODO: Add your control notification handler code here
	m_pSet->AddNew();
	UpdateData(TRUE);
	if (m_pSet->CanUpdate()) {
	m_pSet->Update();
	}
	if (!m_pSet->IsEOF())
	{
	m_pSet->MoveLast();
	}
	// m_pSet->Requery(); // for sorted sets
	UpdateData(FALSE);
}

void CODBCCommView::OnClear() 
{
	// TODO: Add your control notification handler code here
	m_pSet->SetFieldNull(NULL);
	UpdateData(FALSE);
}

void CODBCCommView::OnDelete() 
{
	// TODO: Add your control notification handler code here
	CRecordsetStatus status;
	try 
	{
		m_pSet->Delete();
	}
	catch(CDBException* e) {
		AfxMessageBox(e->m_strError);
		e->Delete();
		m_pSet->MoveFirst(); // lost our place!
		UpdateData(FALSE);
		return;
	}

	m_pSet->GetStatus(status);
	if (status.m_lCurrentRecord == 0) 
	{
		// We deleted last of 2 records
		m_pSet->MoveFirst();
	}
	else 
	{
		m_pSet->MoveNext();
	}
	UpdateData(FALSE);	
}

BOOL CODBCCommView::OnMove(UINT nIDMoveCommand) 
{
	// TODO: Add your specialized code here and/or call the base class
	switch (nIDMoveCommand)
	{
	case ID_RECORD_PREV:
		if (!m_pSet->IsBOF())
			m_pSet->MovePrev();
		break;

	case ID_RECORD_FIRST:
		m_pSet->MoveFirst();
		break;

	case ID_RECORD_NEXT:
		if (!m_pSet->IsEOF())
			m_pSet->MoveNext();
		break;
	
		if (!m_pSet->CanScroll())
		{
		// Clear out screen since we're sitting on EOF
			m_pSet->SetFieldNull(NULL);
			break;
		}

	case ID_RECORD_LAST:
		m_pSet->MoveLast();
		break;

	default:
	// unexpected case value
	ASSERT(FALSE);
	}
	
	// show results of move operation
	UpdateData(FALSE);
	return TRUE;	
}

LONG CODBCCommView::OnCommunication(WPARAM ch, LPARAM port)
{
	static int count1=0,count2=0,count3=0;
	static char c1,c2;
	static int flag;
	CString strCheck="";

	if(port == 2) //COM2接收到数据 
	{
		CString strtemp=(char)ch;
		if(strtemp=="Y")
		{
			m_nRXCounterCOM2++;
			CString strtemp;
			strtemp.Format("COM2: NO.%06d", m_nRXCounterCOM2);
			AfxMessageBox(strtemp);
		}
	}

	if(port == 1) //COM1接收到数据
	{
		m_strRXDataCOM1 += (char)ch;
		switch(ch)
		{
		case '$':
			m_chChecksum=0; //开始计算CheckSum
			flag = -1;
			break;
		case '%':
			flag = 0;
			break;
		case '*':
			flag=2;
			c2=m_chChecksum & 0x0f; 
			c1=((m_chChecksum >> 4) & 0x0f);
			if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;
			if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;
			break;
		case CR:
			break;
		case LF:
			m_strRXDataCOM1.Empty();
			break;
		default:
	
		if(flag >= 0) 
		{
			if(flag > 0)
			{
				m_strRXhhCOM1 += ch; //得到收到的校验值hh
				if(flag==1) 
				{
					strCheck = strCheck+c1+c2; //计算得到的校验值hh
					if(strCheck!=m_strRXhhCOM1) //如果校验有错
					{
						m_strRXDataCOM1.Empty();
						m_nRXErrorCOM1++; //串口1错误帧数加1
					}
					else
					{
						m_nRXCounterCOM1++;
						if(m_strRXDataCOM1.Left(1)=="$") //接收数据的第一个字符是$吗?
						{
							char tbuf[6];
							char *temp=(char*)((LPCTSTR)m_strRXDataCOM1);
							tbuf[0] = temp[1];
							tbuf[1] = temp[2]; 
							tbuf[2] = temp[3]; 
							tbuf[3] = temp[4];
							tbuf[4] = 0; //0表示字符串的结束,必要
							
							int data=atoi(tbuf);
							CString strDisplay1;														
							strDisplay1.Format("Receive %04d, Error Counter=%04d.",data, m_nRXErrorCOM1);
							
							AfxMessageBox(strDisplay1);
			

							CString strTemp, strTemp1;
							int n1 = m_strRXDataCOM1.Find('%');
							strTemp = m_strRXDataCOM1.Right(m_strRXDataCOM1.GetLength() - n1 -1);
							//析取出姓名
							n1 = strTemp.Find('%');
							strTemp1 = strTemp.Right(strTemp.GetLength() - n1 -1);
							m_pSet->m_name = strTemp.Left(n1);
							//析取出学号
							n1 = strTemp1.Find('%');
							strTemp = strTemp1.Right(strTemp1.GetLength() - n1 - 1);
							m_pSet->m_number = strTemp1.Left(n1);
							//析取出成绩
							n1 = strTemp.Find('*');
							m_pSet->m_score = strTemp.Left(n1);
						}
						SendBack();
						UpdateData(FALSE);
						OnAdd();

					}
					m_strRXhhCOM1.Empty();
				}
				flag--;
			}
		}
		else
			m_chChecksum ^= ch;
		break;
		}
	}
	return 0;
}


void CODBCCommView::SendString(int n, int port)
{
	char checksum=0,cr=CR,lf=LF;

	char c1,c2;
	CString str;
	str.Format("%04d", n);

	for(int i = 0; i < str.GetLength(); i++)
		checksum = checksum^str[i];
	c2 = checksum & 0x0f;
	c1=((checksum >> 4) & 0x0f);
	if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;
	if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;
	
	CString str1;
	
	str1='$' + str + "%" + "Li" + "%" + "9306" + "%" + "85" + "*"+c1+c2+cr+lf;
	
	m_ComPort[port-1].WriteToPort((char *)(LPCTSTR)str1);
}

void CODBCCommView::OnSendData() 
{
	// TODO: Add your command handler code here
	int i = 3;
	SendString(i, 2); //串口2发送数据;
}

void CODBCCommView::SendBack()
{
	CString str1="Y";
	m_ComPort[0].WriteToPort((char *)(LPCTSTR)str1);//发送应答信号Y
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -