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

📄 serialdlg.cpp

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

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

#include "MFID.h"
#include "myport.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

CEvent g_eventKill;
bool ifcardin=false;
int iTimeHigh, iTimeLow, iTime ;	//8253计时常数

int iModal_8251 = 0 ;
int iOperating_8251 = 0x27 ;
char idstring[7]="123456";

//这里开始是对钱的输入的控制

char substring[7]="000000"; //2222.22元
bool ifpoint=false;
int nowat=3;

//初始化静态成员
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_disp = _T("");
	m_mony = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	//给变量赋值
	char moneyreceive[7]="000000";
	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_0, m_0);
	DDX_Control(pDX, IDC_sub, m_sub);
	DDX_Control(pDX, IDC_point, m_point);
	DDX_Control(pDX, IDC_c, m_clear);
	DDX_Control(pDX, IDC_add, m_add);
	DDX_Control(pDX, IDC_9, m_9);
	DDX_Control(pDX, IDC_8, m_8);
	DDX_Control(pDX, IDC_7, m_7);
	DDX_Control(pDX, IDC_6, m_6);
	DDX_Control(pDX, IDC_5, m_5);
	DDX_Control(pDX, IDC_4, m_4);
	DDX_Control(pDX, IDC_3, m_3);
	DDX_Control(pDX, IDC_2, m_2);
	DDX_Control(pDX, IDC_1, m_1);
	DDX_Control(pDX, IDC_IDout, m_idout);
	DDX_Control(pDX, IDC_BUTTON, m_idbutton);
	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_DISP, m_disp);
	DDX_Text(pDX, IDC_MONEY, m_mony);
	//}}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_BUTTON, OnButton)
	ON_BN_CLICKED(IDC_IDout, OnIDout)
	ON_BN_CLICKED(IDC_add, Onadd)
	ON_BN_CLICKED(IDC_sub, Onsub)
	ON_BN_CLICKED(IDC_1, On1)
	ON_BN_CLICKED(IDC_2, On2)
	ON_BN_CLICKED(IDC_3, On3)
	ON_BN_CLICKED(IDC_4, On4)
	ON_BN_CLICKED(IDC_5, On5)
	ON_BN_CLICKED(IDC_6, On6)
	ON_BN_CLICKED(IDC_7, On7)
	ON_BN_CLICKED(IDC_8, On8)
	ON_BN_CLICKED(IDC_9, On9)
	ON_BN_CLICKED(IDC_0, On0)
	ON_BN_CLICKED(IDC_point, Onpoint)
	ON_BN_CLICKED(IDC_c, Onc)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_WM_TIMER()
	//}}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_disp=substring;
	UpdateData(false);
	//m_idbutton.EnableWindow(true);
	//m_idout.EnableWindow(false);
	m_IDOK.EnableWindow(false);
	m_IDCANCEL.EnableWindow(true);
	//m_1.EnableWindow(true);
	m_ctrlEditSend.EnableWindow(false);
	
	working = true;
	
	//根据参数计算8251的方式命令
		//先初始化为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)允许发送
	
	

	//计算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 );

		outportb(0x301,0xff);//LED全灭   ////8255控制
		outportb(0x303,0x0c);//关闭SPK
		
		outportb(0x303,0x01); //PC0置1

		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 ) ;	//装计数初值高字节

		outportb (TIMER2_8253, 0xff);
		outportb (TIMER2_8253, 0x00);

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

		outportb (0x301, 0xcc);//灯亮

		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);

		//outportb(0x303,0
	}

	outportb(0x303,0x0c);//  关声音clock

	outportb (TIMER2_8253, iTimeLow ) ;	//装计数初值低字节
	outportb (TIMER2_8253, iTimeHigh ) ;	//装计数初值高字节
	outportb(0x303,0x0d);//  开声音clock

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

void CSerialDlg::OnCancel() 
{
	outportb(0x301,0xff);
	// 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() 
{
	// TODO: Add your control notification handler code here
   CEdit*	pWndReceive =(CEdit*) GetDlgItem(IDC_EDIT_RECEIVE );


	// CHAR to TCHAR
	//tchReceive = _T(chReceive);
	tchReceive = _T(chReceive);

    char tempreceive;
	if (chReceive == 'f') {
		MessageBox("WrongIDCard");
		//开始声音
	iTime = (CLK_8253 / iBaudrate ) / FACTOR16_BAUDRATE_8251 ;
	iTimeHigh = (iTime>>8) & 0x00FF ;
	iTimeLow  = iTime & 0x00FF ;
	
	//初始化8255、8253、8251
	
		//设置8255工作方式
		//置PC6为输出以控制8251 GATE2
		outportb(CTRL_8255, 0x80 );

		outportb(0x301,0xff);//LED全灭   ////8255控制
		outportb(0x303,0x0c);//关闭SPK
		
		outportb(0x303,0x01); //PC0置1

		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 ) ;	//装计数初值高字节

		outportb (TIMER2_8253, 0xff);
		outportb (TIMER2_8253, 0x00);

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

		outportb (0x301, 0xcc);//灯亮

		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);

		//outportb(0x303,0
	

	outportb(0x303,0x0c);//  关声音clock

	outportb (TIMER2_8253, iTimeLow ) ;	//装计数初值低字节
	outportb (TIMER2_8253, iTimeHigh ) ;	//装计数初值高字节
	outportb(0x303,0x0d);//  开声音clock

	outportb(0x301,0xff);//
//结束声音
	}
	if (chReceive == 'j') {
		MessageBox("Not ENOUGH Money or Money Overflow");
		//开始声音
	iTime = (CLK_8253 / iBaudrate ) / FACTOR16_BAUDRATE_8251 ;
	iTimeHigh = (iTime>>8) & 0x00FF ;
	iTimeLow  = iTime & 0x00FF ;
	
	//初始化8255、8253、8251
	
		//设置8255工作方式
		//置PC6为输出以控制8251 GATE2
		outportb(CTRL_8255, 0x80 );

		outportb(0x301,0xff);//LED全灭   ////8255控制
		outportb(0x303,0x0c);//关闭SPK
		
		outportb(0x303,0x01); //PC0置1

		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 ) ;	//装计数初值高字节

		outportb (TIMER2_8253, 0xff);
		outportb (TIMER2_8253, 0x00);

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

		outportb (0x301, 0xcc);//灯亮

		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);

		//outportb(0x303,0
	

	outportb(0x303,0x0c);//  关声音clock

	outportb (TIMER2_8253, iTimeLow ) ;	//装计数初值低字节
	outportb (TIMER2_8253, iTimeHigh ) ;	//装计数初值高字节
	outportb(0x303,0x0d);//  开声音clock

	outportb(0x301,0xff);//
//结束声音//开始声音
	iTime = (CLK_8253 / iBaudrate ) / FACTOR16_BAUDRATE_8251 ;
	iTimeHigh = (iTime>>8) & 0x00FF ;
	iTimeLow  = iTime & 0x00FF ;
	
	//初始化8255、8253、8251
	
		//设置8255工作方式
		//置PC6为输出以控制8251 GATE2
		outportb(CTRL_8255, 0x80 );

		outportb(0x301,0xff);//LED全灭   ////8255控制
		outportb(0x303,0x0c);//关闭SPK
		
		outportb(0x303,0x01); //PC0置1

		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 ) ;	//装计数初值高字节

		outportb (TIMER2_8253, 0xff);
		outportb (TIMER2_8253, 0x00);

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

		outportb (0x301, 0xcc);//灯亮

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

⌨️ 快捷键说明

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