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

📄 serialdlg.cpp

📁 华中科技大学计算机学院接口课程设计.vc制作,上位机下位机模拟商场贵宾卡系统.使用access数据库.
💻 CPP
字号:
// SerialDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Serial.h"
#include "SerialDlg.h"

#include "MFID.h"
#include "myport.h"
#include "test2222set.h"
#include "conio.h"	//for inportb(), outportb()
#include "ctype.h"	//for toupper(), is...
#include "time.h"	//for time

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

#define REPEATS1_8251					3
#define REPEATS2_8251					3
#define DELAY1_8251						3
#define DELAY2_8251						2

#define alpnum						30
#define numnum						10
#define numalp						30

CEvent g_eventKill;
//wjz
void change (long money);
//初始化静态成员
TCHAR CSerialDlg::tchReceive = _T('\0');
char CSerialDlg::chReceive = '\0';

/////////////////////////////////////////////////////////////////////////////
// CSerialDlg dialog

CSerialDlg::CSerialDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSerialDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSerialDlg)
	m_strSend = _T("");
	m_wjz = 0;
	m_add = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	//给变量赋值
	iBaudrate = 1200;	//波特率
	iDataBits = 0xC;	//数据位8位
	iParity = 0x0;	//无校验
	iStopBits = 0x40;	//一位停止位

	this->m_IndexNum = 0;
	this->m_strMessage = "";
	iTextLengthOld = 0 ;
	iTextLengthNew = 0 ;
}

void CSerialDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSerialDlg)
	DDX_Control(pDX, IDC_EDIT_SEND, m_ctrlEditSend);
	DDX_Control(pDX, IDCANCEL, m_IDCANCEL);
	DDX_Control(pDX, IDOK, m_IDOK);
	DDX_Text(pDX, IDC_EDIT_SEND, m_strSend);
	DDX_Text(pDX, IDC_EDIT1, m_wjz);
	DDX_Text(pDX, IDC_EDIT2, m_add);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSerialDlg, CDialog)
	//{{AFX_MSG_MAP(CSerialDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_EN_CHANGE(IDC_EDIT_SEND, OnChangeEditSend)
	ON_BN_CLICKED(IDC_CONN, OnConn)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialDlg message handlers

BOOL CSerialDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 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
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// 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 CSerialDlg::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 CSerialDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CSerialDlg::OnOK() 
{
	// TODO: Add extra validation here
	m_IDOK.EnableWindow(false);
	m_IDCANCEL.EnableWindow(true);
	m_ctrlEditSend.EnableWindow(true);

	working = true;

	//根据参数计算8251的方式命令
	int iModal_8251 = 0 ;	//先初始化为0

	//波特率因子16。
	iModal_8251 = iStopBits | iParity | iDataBits | 0x2 ;
		
	//打开端口
	OpenPortTalk();


	//置8251的工作命令字为0x27
	//(D7=0)不搜索同步字符
	//(D6=0)不进行内部复位
	//(D5=1)强迫请求发送RTS#为有效(低)电平
	//(D4=0)状态字中的错误标志位(PE/OE/FE)不复位
	//(D3=0)TxD正常操作
	//(D2=1)允许接收
	//(D1=1)强制DTR#有效,表示终端设备已准备好
	//(D0=1)允许发送
	int iOperating_8251 = 0x27 ;

	int iTimeHigh, iTimeLow, iTime ;	//8253计时常数
	//计算8253计数初值,波特率因子设为16
	iTime = (CLK_8253 / iBaudrate ) / FACTOR16_BAUDRATE_8251 ;
	iTimeHigh = (iTime>>8) & 0x00FF ;
	iTimeLow  = iTime & 0x00FF ;

	//初始化8255、8253、8251
	for(int i=0; i<REPEATS1_8251; i++)
	{
		//设置8255工作方式
		//置PC6为输出以控制8251 GATE2
		outportb(CTRL_8255, 0x80 );
		Sleep(DELAY1_8251);

		//设置8253工作方式
		//通道2;
		//读/写2个字节,先是低字节,后是高字节;
		//3方式;
		//二进制码计数。
		outportb (CTRL_8253, 0xB6) ;	//10110110B,8253工作方式命令字
		Sleep (DELAY1_8251) ;

		//往8253送计时常数
		outportb (TIMER2_8253, iTimeLow ) ;	//装计数初值低字节
		outportb (TIMER2_8253, iTimeHigh ) ;	//装计数初值高字节
		Sleep (DELAY1_8251) ;

		//置8255 PC6=1,PC6与8253 GATE2相连,即允许8253通道2计数
		outportb (CTRL_8255, 0x0D ) ;	//00001101B
		Sleep (DELAY1_8251) ;

		//空操作,向8251命令口写任意数
		for(int j=0; j<REPEATS2_8251; j++)
		{
			outportb (CTRL_8251, 0x00 ) ;
			Sleep (DELAY2_8251) ;
		}
		//8251内部复位
		//置8251 D6=1,使其内部复位
		//发方式命令之前一定要先进行内部复位
		outportb (CTRL_8251, 0x40) ;
		Sleep (DELAY1_8251);
		//往8251写方式命令字
		//复位命令之后一定是跟方式命令
		outportb (CTRL_8251, iModal_8251) ;
		Sleep (DELAY1_8251);

		//往8251写工作命令字
		outportb(CTRL_8251, iOperating_8251);
		Sleep(DELAY1_8251);
	}

	//开启接收线程
	CSerialDlg *m_this = (CSerialDlg *)this;
	AfxBeginThread (Receiving,(LPVOID)m_this) ;
	OnConn();
	//CDialog::OnOK();
}

void CSerialDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	if (!m_IDOK.IsWindowEnabled())	//如果OK按钮已按下则存在接收线程
	{
		working = false;
		g_eventKill.SetEvent();	//通知接收字符进程Receiving()结束
	}
	//置8255 PC6=0,PC6与8251 GATE2相连,即禁止8253通道2计数
	outportb (CTRL_8255, 0xC ) ;	//00001100B
	Sleep (5) ;	
	
	//关闭端口
	ClosePortTalk();

	CDialog::OnCancel();
}

UINT CSerialDlg::Receiving(LPVOID pParam)
{
	
	CSerialDlg *p_this = (CSerialDlg*)pParam;

	do{
		if (::WaitForSingleObject(g_eventKill, 0) == WAIT_OBJECT_0 )
		{
			break ;
		}
		// if RxRDY on
//		if (working == false) break;
		if (inportb(CTRL_8251) & 0x02 ) {
			Sleep (3) ;	//稳定一会儿

			// received from 8251
			chReceive = inportb(DATA_8251) ;
			Sleep (3) ;	//稳定一会儿
			//::PostMessage ((HWND)p_this, WM_RECEIVE, 0, 0 );
			p_this->OnReceive();
		}
	} while (true);

	return 0 ;
}

VOID CSerialDlg::OnReceive() 
{
	static long money;
	// TODO: Add your control notification handler code here
	CEdit*	pWndReceive =(CEdit*) GetDlgItem(IDC_EDIT_RECEIVE );
	// CHAR to TCHAR
	tchReceive = _T(chReceive);

/*RECEIVE CARD NUM*/
	if (chReceive == 'a') 
	{  // MessageBox("");
		Sleep(50);
		char a[6];
		//card no to char a[]
		for(int i=0;i<6;i++)
		{
			a[i]=inportb(DATA_8251);
			Sleep(50);
		}
		//display card no		
		m_strMessage.Insert(m_IndexNum, 'A');
		m_IndexNum ++;
		for(i=0;i<6;i++)
		{
			m_strMessage.Insert(m_IndexNum, a[i]);
			m_IndexNum ++ ;
		}
		//a[] to strId
		CString strId="";
		for(i=0;i<6;i++)
		{
			strId+=a[i];
		}
		
		//find record where
		DBSet->MoveFirst();
		while(!DBSet->IsEOF())
		{
			if(DBSet->m_ID==strId)
			{
				money=DBSet->m_Money;
				outportb (DATA_8251, 'b' ) ;
				
				pWndReceive->SetWindowText(m_strMessage);
				pWndReceive->LineScroll(255,0);

				change(money);
				
				return;
			}
			else
				DBSet->MoveNext();
		}
		if(DBSet->IsEOF())
		{
			outportb (DATA_8251, 'f') ;
		}
		
	};
	/*INCREACE MONEY*/
	if(chReceive == 'c')
	{
		Sleep(50);
		char c[6];
		long add=0;

		for(int i=0;i<6;i++)
		{
			 c[i]=inportb(DATA_8251);
			 add=add*10+(int)(c[i]-'0');
			 Sleep(50);
		}
		m_strMessage.Insert(m_IndexNum, 'C');
		m_IndexNum ++;
		for(i=0;i<6;i++)
		{
			m_strMessage.Insert(m_IndexNum, c[i]);
			m_IndexNum ++ ;
		}

		money=money+add;
		if(money<=999999)
		{
			//更新
			DBSet->Edit();
			DBSet->m_Money=money;
			DBSet->Update();
			DBSet->Requery();
			outportb (DATA_8251, 'b' ) ;
			//outportb (DATA_8251, 'f' ) ;
			//Sleep(50);
			
			change(money);
		}
		else
		{
			money=money-add;
			outportb (DATA_8251, 'j' ) ;
		}
		pWndReceive->SetWindowText(m_strMessage);
		pWndReceive->LineScroll(255,0);
	}
/*REDUCE MONEY*/
	if(chReceive == 'd')
	{
		Sleep(50);
		char d[6];
		long sub=0;
		for(int i=0;i<6;i++)
		{
			 d[i]=inportb(DATA_8251);
			 sub=sub*10+(int)(d[i]-'0');
			 Sleep(50);
		}
		m_strMessage.Insert(m_IndexNum, 'D');
		m_IndexNum ++;
		for(i=0;i<6;i++)
		{
			m_strMessage.Insert(m_IndexNum, d[i]);
			m_IndexNum ++ ;
		}

		money=money-sub;
		if(money>=0)
		{
			//更新
			
			DBSet->Edit();
			DBSet->m_Money=money;
			DBSet->Update();
			DBSet->Requery();
			outportb (DATA_8251, 'b' ) ;
			//outportb (DATA_8251, 'f' ) ;
			//Sleep(50);
			
			change(money);
		}
		else
		{
			money=money+sub;
			outportb (DATA_8251, 'j' ) ;
		}
		pWndReceive->SetWindowText(m_strMessage);
		pWndReceive->LineScroll(255,0);
	}
	/*EXIT*/
	if(chReceive == 'e')
	{
		/*
		MessageBox("用户已经拔卡");
		*/
		m_strMessage.Insert(m_IndexNum, 'E');
		m_IndexNum ++;
		m_strMessage.Insert(m_IndexNum, '\r');
        m_IndexNum ++;
		m_strMessage.Insert(m_IndexNum, 10);
        m_IndexNum ++;
		pWndReceive->SetWindowText(m_strMessage);
		pWndReceive->LineScroll(255,0);
	}

    if(tchReceive==10||tchReceive==13)//10:换行,13:回车
	{
		m_strMessage.Insert(m_IndexNum, '\r');
        m_IndexNum ++;	pWndReceive->SetWindowText(m_strMessage);
		pWndReceive->LineScroll(255,0);
	}

	// display the text
	pWndReceive->SetWindowText(m_strMessage);
    pWndReceive->LineScroll(255,0);
	return ;
}

void CSerialDlg::OnChangeEditSend() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	pWndSend = GetDlgItem(IDC_EDIT_SEND);
	
	// get input text
	pWndSend->GetWindowText(m_strSend);

	iTextLengthNew = m_strSend.GetLength() ;
	if (iTextLengthNew > iTextLengthOld ) {
		// CString to TCHAR
		tchSend = m_strSend.GetAt(iTextLengthNew - 1) ;

		// TCHAR to CHAR
		//chSend = tchSend & 0x00FF ;	//method 1
		//chSend = char(tchSend) ;	//method 2
		chSend = (char)tchSend ;	//method 3

		//判断待发字符种类
		//if (! iscntrl (chSend ) ) {//如果chSend是
			// Waiting for TxRDY on
			time (&tFirst) ;	//取当前时间(以秒为单位)
			do {
				time (&tSecond) ;	//再次取当前时间(以秒为单位)
				if(difftime(tSecond,tFirst) > 1 )
				{  
					//TxRDY missing, can't send.
					MessageBox ("Error: TxRDY missing, can't send. To be terminated!" ) ;
					return ;
				}
			} while(! (inportb(CTRL_8251) & 0x01) );

			// send to 8251
			outportb (DATA_8251, chSend ) ;
			Sleep(5);
		//}
	}
	iTextLengthOld = iTextLengthNew ;	
}


void CSerialDlg::OnSend(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	
	*pResult = 0;
}


void CSerialDlg::OnConn() 
{
	// TODO: Add your control notification handler code here
	dbOdbc;
	*DBSet;

	dbOdbc.Open(NULL,false,false,"ODBC;DSN=card");
	DBSet=new CTest2222Set(&dbOdbc);

	try
	{
		DBSet->Open();
	}
	catch(CDBException *e)
	{ 
		AfxMessageBox(e->m_strError);
		return;
	}

	/*
	while(!DBSet->IsEOF())
	{
		if(DBSet->m_ID=="123456")
		{
			long l=DBSet->m_Money;
			m_wjz=l;
			UpdateData(false);

			DBSet->MoveNext();
		}
		else
			DBSet->MoveNext();
	}
	*/
}

void CSerialDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	
}

void change (long money)
{
		int i;
		long mycp=money;
		char dollar[6];
		
		i=(int)(mycp/100000);
		dollar[0]=i+'0';
		mycp=mycp-i*100000;
		
		i=(int)(mycp/10000);
		dollar[1]=i+'0';
		mycp=mycp-i*10000;
		
		i=(int)(mycp/1000);
		dollar[2]=i+'0';
		mycp=mycp-i*1000;
		
		i=(int)(mycp/100);
		dollar[3]=i+'0';
		mycp=mycp-i*100;
		
		i=(int)(mycp/10);
		dollar[4]=i+'0';
		mycp=mycp-i*10;
		
		i=(int)(mycp/1);
		dollar[5]=i+'0';
		mycp=mycp-i*1;
		
		for(i=0;i<6;i++)
		{
			outportb (DATA_8251, dollar[i] ) ;
			Sleep(50);
		}
}

⌨️ 快捷键说明

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