📄 canloopbackdlg.cpp
字号:
// CANLoopbackDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CANLoopback.h"
#include "CANLoopbackDlg.h"
#include "..\..\include\adscan.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
DWORD WINAPI CCANLoopbackDlg::SendThreadProc(PVOID pContext);
DWORD WINAPI CCANLoopbackDlg::RecvThreadProc(PVOID pContext);
WORD CCANLoopbackDlg::m_nPort = 0;
ULONG CCANLoopbackDlg::m_nIndex = NULL;
HANDLE CCANLoopbackDlg::m_hSendEvent = NULL;
HANDLE CCANLoopbackDlg::m_hKillSendThread = NULL;
BOOL CCANLoopbackDlg::m_bKillSendThread = FALSE;
HANDLE CCANLoopbackDlg::m_hRecvEvent = NULL;
HANDLE CCANLoopbackDlg::m_hKillRecvThread = NULL;
BOOL CCANLoopbackDlg::m_bKillRecvThread = FALSE;
int CCANLoopbackDlg::m_nHostCANID = 0;
int CCANLoopbackDlg::m_nRecvCANID = 0;
int CCANLoopbackDlg::m_nSendCANID = 0;
CAN_MSG_T CCANLoopbackDlg::m_pData;
CAN_MSG_T CCANLoopbackDlg::m_msg;
CString CCANLoopbackDlg::m_sRecvMessage;
CDialog * CCANLoopbackDlg::m_pDlg = NULL;
CStatic* CCANLoopbackDlg::m_ctrlRecvMessage = NULL;
/////////////////////////////////////////////////////////////////////////////
// CCANLoopbackDlg dialog
CCANLoopbackDlg::CCANLoopbackDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCANLoopbackDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCANLoopbackDlg)
m_nDevNum = 0;
m_nHostCANID = 0;
m_nRecvCANID = 0;
m_sSendMessage = _T("abc");
m_sRecvMessage = _T("");
m_nSendCANID = 0;
m_pSendThread = NULL;
m_pRecvThread = NULL;
m_bOpen = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCANLoopbackDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCANLoopbackDlg)
DDX_Text(pDX, IDC_DEV_NUM_EDT, m_nDevNum);
DDX_Text(pDX, IDC_RECV_CAN_ID_EDT, m_nRecvCANID);
DDX_Text(pDX, IDC_SEND_MSG_EDT, m_sSendMessage);
DDX_Text(pDX, IDC_SEND_CAN_ID_EDT, m_nSendCANID);
DDX_Text(pDX, IDC_HOST_CAN_ID_EDT, m_nHostCANID);
DDX_Text(pDX, IDC_RECV_MSG_EDT, m_sRecvMessage);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCANLoopbackDlg, CDialog)
//{{AFX_MSG_MAP(CCANLoopbackDlg)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_OPEN_PORT_BTN, OnOpenPortBtn)
ON_BN_CLICKED(IDC_CLOSE_PORT_BTN, OnClosePortBtn)
ON_BN_CLICKED(IDC_SEND_MSG_BTN, OnSendMsgBtn)
ON_BN_CLICKED(IDC_RECV_MSG_BTN, OnRecvMsgBtn)
ON_BN_CLICKED(IDC_LOOP_SEND_BTN, OnLoopSendBtn)
ON_BN_CLICKED(IDC_LOOP_RECV_BTN, OnLoopRecvBtn)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCANLoopbackDlg message handlers
BOOL CCANLoopbackDlg::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
CenterWindow(GetDesktopWindow()); // center to the hpc screen
m_pDlg = this;
m_ctrlRecvMessage = (CStatic *)GetDlgItem( IDC_RECV_MSG_EDT );
// initialization value
m_nBTR0 = 0x3; // set baud rate to 125K
m_nBTR1 = 0x1c;// the detailed information, please refer to help file.
m_nAcpCode = 0; // set accept code
m_nAcpMask = 0xff; // set mask value is 0xff
m_nIntMask = 0; // set interrupt disable
m_nOutCtrlCode = 250; // set output control code to 0xfa
return TRUE; // return TRUE unless you set the focus to a control
}
void CCANLoopbackDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
OnClosePortBtn();
CDialog::OnClose();
}
void CCANLoopbackDlg::OnOpenPortBtn()
{
// TODO: Add your control notification handler code here
BOOL bReady;
UpdateData(TRUE);
// Before using driver, we need to call CANPortOpen
if (CANPortOpen(m_nDevNum, &m_nPort, &m_nHostID, &m_nPreBaudRate) != SUCCESS)
{
MessageBox(_T( "CANPortOpen error!" ), NULL, MB_ICONERROR);
return;
}
m_nHostCANID = m_nHostID;
m_nAcpCode = 0; // set accept code again
m_nAcpMask = 0xff; // set mask value again
// Make a hardware reset action
if ( CANHwReset( m_nPort ) != SUCCESS )
{
MessageBox(_T( "CANHwReset error!" ), NULL, MB_ICONERROR);
CANPortClose( m_nPort);
return;
}
// Initialize baud rate and interrupt bits
if (CANInit(m_nPort, m_nBTR0, m_nBTR1, (UCHAR) m_nIntMask) != SUCCESS)
{
MessageBox(_T( "CANInit error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set output control code
if (CANSetOutCtrl(m_nPort, m_nOutCtrlCode) != SUCCESS)
{
MessageBox(_T( "CANSetOutCtrl error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set accept code for 2.0A
if (CANSetAcp(m_nPort, m_nAcpCode, m_nAcpMask) != SUCCESS)
{
MessageBox(_T( "CANSetAcp error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set baud rate again
if (CANSetBaud(m_nPort, m_nBTR0, m_nBTR1) != SUCCESS)
{
MessageBox(_T( "CANSetBaud error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set to operation mode
if (CANSetNormal(m_nPort) != SUCCESS)
{
MessageBox(_T( "CANSetNormal error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Enabled the recieve interrupt only
CANEnableRxInt( m_nPort );
// Set a buffer pointer to driver
CANSetBufferPtr(m_nPort, &m_pData, 1, &bReady);
if (!bReady)
{
MessageBox(_T( "CANSetBufferPtr error!" ), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Set a buffer index to driver
CANSetCountPtr( m_nPort, &m_nIndex, &bReady );
if ( !bReady )
{
MessageBox(_T("CANSetCountPtr error!"), NULL, MB_ICONERROR);
CANPortClose(m_nPort);
return;
}
// Enable the event usage
CANEnableEvent(m_nPort, TRUE);
m_bOpen = TRUE;
UpdateData(FALSE);
}
void CCANLoopbackDlg::OnClosePortBtn()
{
// TODO: Add your control notification handler code here
if (m_bOpen)
{
CloseSendThreadHandling(m_nPort);
CloseRecvThreadHandling(m_nPort);
if (CANPortClose(m_nPort) != SUCCESS)
{
MessageBox(_T( "CANPortClose error!" ), NULL, MB_ICONERROR);
}
m_bOpen = FALSE;
}
}
void CCANLoopbackDlg::OnSendMsgBtn()
{
// TODO: Add your control notification handler code here
LPTSTR lpData;
UCHAR ucDataAnsi[30];
UpdateData(TRUE);
CString s;
CAN_MSG_T msgdata;
msgdata.id = (m_nSendCANID << 3) | 1;
msgdata.rtr = 0;
msgdata.dlen = m_sSendMessage.GetLength() > 8 ? 8 : m_sSendMessage.GetLength();
lpData = m_sSendMessage.GetBuffer(20);
#ifdef _WIN32_WCE
// convert the TCHAR to CHAR
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK,
lpData, -1, (LPSTR)ucDataAnsi, 20, NULL, NULL);
strncpy( (char*)&msgdata.data[0], (char*)ucDataAnsi, msgdata.dlen );
#else
strncpy( (char*)&msgdata.data[0], lpData, msgdata.dlen );
#endif
m_sSendMessage.ReleaseBuffer(-1);
BOOL bReady = FALSE;
// try to write some data into CAN bus
CANWriteFile(m_nPort, (BOOL *) &bReady, (PVOID) &msgdata);
if (!bReady)
{
MessageBox(_T( "CANWriteFile FAILURE!" ), NULL, MB_OK);
}
else
{
MessageBox(_T( "CANWriteFile OK!" ), NULL, MB_OK);
}
}
void CCANLoopbackDlg::OnRecvMsgBtn()
{
// TODO: Add your control notification handler code here
BOOL bReady = FALSE;
CString sReturn;
TCHAR szTemp[256];
UpdateData(TRUE);
// try to get from CAN bus
CANWaitForFIFOEvent(m_nPort, 1500, &bReady);
if (bReady)
{
m_nRecvCANID = (BYTE) (m_pData.id >> 3);
m_sRecvMessage.Empty();
{
#ifdef _WIN32_WCE
// Convert CHAR to TCHAR
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
(char*)&m_pData.data[0], -1, szTemp, 128);
sReturn.Format(_T("%s"), szTemp);
#else
sReturn.Format(_T("%s"), (PUCHAR)&m_pData.data[0]);
#endif
m_sRecvMessage += sReturn;
}
UpdateData(FALSE);
}
else
{
MessageBox(_T( "CAN receive data error!" ), NULL, MB_ICONERROR);
}
}
void CCANLoopbackDlg::OnLoopSendBtn()
{
// TODO: Add your control notification handler code here
LPTSTR lpData;
UCHAR ucDataAnsi[30];
UpdateData(TRUE);
m_msg.id = (m_nSendCANID << 3) | 1;
m_msg.rtr = 0;
m_msg.dlen = m_sSendMessage.GetLength() > 8 ? 8 : m_sSendMessage.GetLength();
lpData = m_sSendMessage.GetBuffer(20);
#ifdef _WIN32_WCE
// convert the TCHAR to CHAR
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK,
lpData, -1, (LPSTR)ucDataAnsi, 20, NULL, NULL);
strncpy( (char*)&m_msg.data[0], (char*)ucDataAnsi, m_msg.dlen );
#else
strncpy( (char*)&m_msg.data[0], lpData, m_msg.dlen );
#endif
m_sSendMessage.ReleaseBuffer(-1);
CreateSendThreadHandling(m_nPort);
}
void CCANLoopbackDlg::OnLoopRecvBtn()
{
// TODO: Add your control notification handler code here
CreateRecvThreadHandling(m_nPort);
}
LONG CCANLoopbackDlg::CreateSendThreadHandling(WORD wPort)
{
// Set up the dispatch thread and it's kill flag.
if (m_pSendThread == NULL)
{
m_bKillSendThread = FALSE;
m_pSendThread = NULL;
m_hSendEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hKillSendThread = CreateEvent(NULL, TRUE, FALSE, NULL);
if ((m_hSendEvent == NULL) ||
(m_hKillSendThread == NULL))
return CANCreateEventFailed;
m_pSendThread = CreateThread(
NULL,0, SendThreadProc, (PVOID)wPort, 0, NULL);
if (m_pSendThread == NULL )
{
return(CANCreateThreadFailed); // failure
}
}
return SUCCESS;
}
LONG CCANLoopbackDlg::CloseSendThreadHandling(WORD wPort)
{
if (m_pSendThread)
{
m_bKillSendThread = TRUE;
SetEvent(m_hSendEvent);
WaitForSingleObject(m_hKillSendThread, 3000);
CloseHandle(m_pSendThread);
m_pSendThread = NULL;
}
return SUCCESS;
}
DWORD CCANLoopbackDlg::SendThreadProc(PVOID pContext)
{
// Wait for the event that any CAN port action creates.
while ( !m_bKillSendThread )
{
SendEventHandler((WORD)pContext);
}
return(0);
}
LONG CCANLoopbackDlg::SendEventHandler(WORD wPort)
{
if (m_bKillSendThread || (!m_hSendEvent))
{
SetEvent (m_hKillSendThread);
ExitThread(0);
}
// handling routine
CString s = _T( "" );
BOOL bReady = FALSE;
static DWORD dwCount = 0;
static int i=0x30;
{
if (m_msg.dlen < 8)
{
if (i >= 0x39)
i = 0x30;
else
i ++;
m_msg.data[m_msg.dlen] = i;
m_msg.dlen++;
}
// try to write some data into CAN bus
CANWriteFile(m_nPort, &bReady, (PVOID)&m_msg);
if (m_msg.dlen < 8)
{
m_msg.dlen--;
}
dwCount++;
s.Format(_T( "%lu"), dwCount);
if (!bReady)
{
m_pDlg->SetWindowText(s + _T(": CAN send message FAILURE!"));
}
else
{
m_pDlg->SetWindowText(s + _T(": CAN send message OK!"));
}
}
Sleep (300);
return SUCCESS;
}
LONG CCANLoopbackDlg::CreateRecvThreadHandling(WORD wPort)
{
// Set up the dispatch thread and it's kill flag.
if (m_pRecvThread == NULL)
{
m_bKillRecvThread = FALSE;
m_pRecvThread = NULL;
m_hRecvEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hKillRecvThread = CreateEvent(NULL, TRUE, FALSE, NULL);
if ((m_hRecvEvent == NULL) ||
(m_hKillRecvThread == NULL))
return CANCreateEventFailed;
m_pRecvThread = CreateThread(
NULL,0, RecvThreadProc, (PVOID)wPort, 0, NULL);
if (m_pRecvThread == NULL )
{
return(CANCreateThreadFailed); // failure
}
}
return SUCCESS;
}
LONG CCANLoopbackDlg::CloseRecvThreadHandling(WORD wPort)
{
if (m_pRecvThread)
{
m_bKillRecvThread = TRUE;
SetEvent(m_hRecvEvent);
WaitForSingleObject(m_hKillRecvThread, 3000);
CloseHandle(m_pRecvThread);
m_pRecvThread = NULL;
}
return SUCCESS;
}
DWORD CCANLoopbackDlg::RecvThreadProc(PVOID pContext)
{
// Wait for the event that any CAN port action creates.
while ( !m_bKillRecvThread )
{
RecvEventHandler((WORD)pContext);
}
return(0);
}
LONG CCANLoopbackDlg::RecvEventHandler(WORD wPort)
{
if (m_bKillRecvThread || (!m_hRecvEvent))
{
SetEvent (m_hKillRecvThread);
ExitThread(0);
}
// handling routine
BOOL bReady = FALSE;
CString sReturn;
TCHAR szTemp[256];
// try to get some data from CAN bus
CANWaitForFIFOEvent(wPort, 1500, &bReady);
if (bReady)
{
m_nRecvCANID = (BYTE) (m_pData.id >> 3);
m_sRecvMessage.Empty();
{
#ifdef _WIN32_WCE
// Convert CHAR to TCHAR
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
(char*)&m_pData.data[0], -1, szTemp, 128);
sReturn.Format(_T("%s"), szTemp);
#else
sReturn.Format(_T("%s"), (PUCHAR)&m_pData.data[0]);
#endif
m_ctrlRecvMessage->SetWindowText(sReturn);
}
}
return SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -