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