📄 odbccommview.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 + -