📄 serialdlg.cpp
字号:
// 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 + -