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

📄 canrecvdlg.cpp

📁 can端口的收数据的测试
💻 CPP
字号:
// CANRecvDlg.cpp : implementation file
//

#include "stdafx.h"
#include "CANRecv.h"
#include "CANRecvDlg.h"
#include "..\..\include\adscan.h"

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

DWORD WINAPI CCANRecvDlg::ListenThreadProc(PVOID pContext);
DWORD WINAPI CCANRecvDlg::CountingThreadProc(PVOID pContext);

// initialize variable
WORD   CCANRecvDlg::m_nPort       = 0;
ULONG  CCANRecvDlg::m_nIndex      = 0;
ULONG  CCANRecvDlg::m_nPreIndex   = 0;
int    CCANRecvDlg::m_nBufferSize = 0;
PVOID  CCANRecvDlg::m_pData             = NULL;

HANDLE CCANRecvDlg::m_hListenEvent      = NULL;
HANDLE CCANRecvDlg::m_hKillListenThread = NULL;
BOOL   CCANRecvDlg::m_bKillListenThread = FALSE;

HANDLE CCANRecvDlg::m_hCountingEvent      = NULL;
HANDLE CCANRecvDlg::m_hKillCountingThread = NULL;
BOOL   CCANRecvDlg::m_bKillCountingThread = FALSE;

CListBox* CCANRecvDlg::m_lstDisplay     = NULL;
CStatic*  CCANRecvDlg::m_lbBufferIndex  = NULL;

/////////////////////////////////////////////////////////////////////////////
// CCANRecvDlg dialog

CCANRecvDlg::CCANRecvDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCANRecvDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCANRecvDlg)
	m_nDevNum    = 1;
	m_sBufferIndex = _T("");
	m_nBufferSize = 8;
    m_nIndex     = 0;
    m_nPreIndex  = 0;
    m_pData = NULL;
    m_nCount = 0;
    m_bKillListenThread = FALSE;
    m_pListenThread = NULL;
    m_hListenEvent = NULL;
    m_bKillCountingThread = FALSE;
    m_pCountingThread = NULL;
    m_hCountingEvent = NULL;
    m_nProtocolType = CANBUS_PROTOCOL_20B;
    m_sFilter      = _T("SINGLE");  // or _T("DOUBLE")
    m_nFilterCode0 = 255;
	m_nFilterCode1 = 255;
	m_nFilterCode2 = 255;
	m_nFilterCode3 = 255;
    m_nFilterMask0 = 255;
	m_nFilterMask1 = 255;
	m_nFilterMask2 = 255;
	m_nFilterMask3 = 255;
    m_bOpen = FALSE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCANRecvDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCANRecvDlg)
	DDX_Text(pDX, IDC_DEV_NUM, m_nDevNum);
	DDX_Text(pDX, IDC_BUFFER_INDEX, m_sBufferIndex);
	DDX_Text(pDX, IDC_RECV_SIZE, m_nBufferSize);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CCANRecvDlg, CDialog)
	//{{AFX_MSG_MAP(CCANRecvDlg)
	ON_BN_CLICKED(IDC_INIT_BTN, OnInitBtn)
	ON_BN_CLICKED(IDC_CLEAR_COUNT_BTN, OnClearCountBtn)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_CLEAR_LIST_BTN, OnClearListBtn)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCANRecvDlg message handlers

BOOL CCANRecvDlg::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

	// initialization value
	m_nBTR0 = 0x03;  // set baud rate to 125K
	m_nBTR1 = 0x1c;  // the detailed information, please refer to help file.

	m_nAcpCode = 0;         // set accept code is 0
	m_nAcpMask = 0xff;      // set mask value is 0xff
	m_nIntMask = 0x1;       // set interrupt enable for receive and transmit
	m_nOutCtrlCode = 0xfa;  // set output control code to 0xfa

    m_lstDisplay    = (CListBox *)GetDlgItem( IDC_REC_LIST );
    m_lbBufferIndex = (CStatic *)GetDlgItem( IDC_BUFFER_INDEX );
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CCANRecvDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default

    // if m_bOpen is true, then free resources usage
    if (m_bOpen)
    {
	    if (CANPortClose(m_nPort) != SUCCESS)
	    {
		    MessageBox(_T( "CANPortClose error!" ), NULL, MB_ICONERROR);
	    }

        CloseThreadHandling(m_nPort);
	    FreeMsgMem();
        m_bOpen = FALSE;
    }

	CDialog::OnClose();
}

void CCANRecvDlg::OnClearListBtn() 
{
	// TODO: Add your control notification handler code here
    UpdateData(TRUE);

	m_lstDisplay->ResetContent();
}

void CCANRecvDlg::OnClearCountBtn() 
{
	// TODO: Add your control notification handler code here
    UpdateData(TRUE);

	m_nCount = 0;

    m_sBufferIndex = _T( " Count : 0 " );

	UpdateData( FALSE );
}

void CCANRecvDlg::OnInitBtn() 
{
    UpdateData (TRUE);

    BOOL bReady;

    // Before using driver, we need to call CANPortOpen
	if (CANPortOpen(m_nDevNum, &m_nPort, &m_nHostID, &m_nBaudRate) != SUCCESS)
	{
		MessageBox(_T( "CANPortOpen error!" ), NULL, MB_ICONERROR);
        return;
	}
    
    // Set protocol usage 
    if (CANSetProtocolType(m_nPort, m_nProtocolType) != SUCCESS)
    {
		MessageBox(_T( "CANSetProtocol 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;
	}

   if (m_nProtocolType == CANBUS_PROTOCOL_20A)
    {
        // Set accept code for 2.0A only
	    if (CANSetAcp(m_nPort, m_nAcpCode, m_nAcpMask) != SUCCESS)
	    {
		    MessageBox(_T( "CANSetAcp error!" ), NULL, MB_ICONERROR);
		    CANPortClose(m_nPort);
            return;
	    }
    }
    else
    {
        // Set accept code for 2.0B only
        PT_FilterSetting  ssFilterSetting;
      
        if (m_sFilter.Compare(_T("DOUBLE")) == 0)
           ssFilterSetting.dwFilterType  =  PELICAN_DOUBLE_FILTER;
      
        if (m_sFilter.Compare(_T("SINGLE")) == 0)
           ssFilterSetting.dwFilterType  =  PELICAN_SINGLE_FILTER;
      
        ssFilterSetting.uchAcceptCode0   =  m_nFilterCode0;
        ssFilterSetting.uchAcceptCode1   =  m_nFilterCode1;
        ssFilterSetting.uchAcceptCode2   =  m_nFilterCode2;
        ssFilterSetting.uchAcceptCode3   =  m_nFilterCode3;
        ssFilterSetting.uchAcceptMask0   =  m_nFilterMask0;
        ssFilterSetting.uchAcceptMask1   =  m_nFilterMask1;
        ssFilterSetting.uchAcceptMask2   =  m_nFilterMask2;
        ssFilterSetting.uchAcceptMask3   =  m_nFilterMask3;

	    if (CANSetAcpEx(m_nPort, &ssFilterSetting) != 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);

    // allocate resources
    CreateThreadHandling(m_nPort);
    AllocMsgMem();

    // Set a buffer pointer to driver
	CANSetBufferPtr( m_nPort, m_pData, m_nBufferSize, &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 );

    // Everything is OK, then update the flag
    m_bOpen = TRUE;
}

LONG CCANRecvDlg::CreateThreadHandling(WORD wPort)
{
    // Set up the dispatch thread and it's kill flag. 
    m_bKillListenThread   = FALSE;
    m_pListenThread       = NULL;  
    m_bKillCountingThread = FALSE;
    m_pCountingThread     = NULL;  

    m_hListenEvent        = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hKillListenThread   = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hCountingEvent      = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_hKillCountingThread = CreateEvent(NULL, TRUE, FALSE, NULL);

    if ((m_hListenEvent == NULL)      || 
        (m_hKillListenThread == NULL) ||
        (m_hCountingEvent == NULL)      || 
        (m_hKillCountingThread == NULL))
        return CANCreateEventFailed;
    
    m_pListenThread = CreateThread(
                NULL,0, ListenThreadProc, (PVOID)wPort, 0, NULL); 

    m_pCountingThread = CreateThread(
                NULL,0, CountingThreadProc, (PVOID)wPort, 0, NULL); 
                
    if ((m_pListenThread == NULL ) || (m_pCountingThread == NULL))
    {
        return(CANCreateThreadFailed);  // failure
    }  

    return SUCCESS;
}

LONG CCANRecvDlg::CloseThreadHandling(WORD wPort)
{
    if (m_pListenThread)
    {   
        m_bKillListenThread = TRUE;
        SetEvent(m_hListenEvent);
        
        WaitForSingleObject(m_hKillListenThread, 3000);
        
        CloseHandle(m_pListenThread);
        m_pListenThread = NULL;  
    }

    if (m_pCountingThread)
    {   
        m_bKillCountingThread = TRUE;
        SetEvent(m_hCountingEvent);
        
        WaitForSingleObject(m_hKillCountingThread, 3000);
        
        CloseHandle(m_pCountingThread);
        m_pCountingThread = NULL;  
    }

    return SUCCESS;
}

DWORD CCANRecvDlg::ListenThreadProc(PVOID pContext)
{
    // Wait for the event that any CAN port action creates.
    while ( !m_bKillListenThread ) 
    {
        ListenEventHandler((WORD)pContext);
    }

    return(0);
}

LONG CCANRecvDlg::ListenEventHandler(WORD wPort)
{
	CString s;
	BOOL bReady = FALSE;
	DWORD   ret = 0;	
	CAN_MSG_T*  msg = (CAN_MSG_T*)m_pData;

    if (m_bKillListenThread || (!m_hListenEvent))
    {
        SetEvent (m_hKillListenThread);
        ExitThread(0);
    }   

    // handling routine
	CANWaitForFIFOEvent( wPort, INFINITE, &bReady);
	if ( bReady )
	{
        /*I will not capture the half buffer ready event.
        // half buffer
		HWND      ActhWnd;
		ActhWnd = (HWND)GetActiveWindow( );
        ::MessageBox(ActhWnd, _T( " Receive Data Buffer half full!" ), _T("Driver Message"), MB_OK);
        */
	}	
    
	CANWaitForFIFOEvent( wPort, INFINITE, &bReady);    
	if ( bReady )
	{
        //I will capture the full buffer ready event.
		HWND      ActhWnd;
		ActhWnd = (HWND)GetActiveWindow( );
        ::MessageBox(ActhWnd, _T( " Receive Data Finished! Below is Data:" ), _T("Driver Message"), MB_OK);
		for ( int i = 0; i < m_nBufferSize; i++ )
		{
			s.Format(_T( "RECV%5d: ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH" ),
                i+1, 
				msg[i].id,
				msg[i].dlen,
				msg[i].data[0],
				msg[i].data[1],
				msg[i].data[2],
				msg[i].data[3],
				msg[i].data[4],
				msg[i].data[5],
				msg[i].data[6],
				msg[i].data[7]);
	
			m_lstDisplay->AddString( s );
		}
	}

    return SUCCESS;
}

DWORD CCANRecvDlg::CountingThreadProc(PVOID pContext)
{
    // Wait for the event that any CAN port action creates.
    while ( !m_bKillCountingThread ) 
    {
        CountingEventHandler((WORD)pContext);
    }

    return(0);
}

LONG CCANRecvDlg::CountingEventHandler(WORD wPort)
{
	CString s;

    if (m_bKillCountingThread || (!m_hCountingEvent))
    {
        SetEvent (m_hKillCountingThread);
        ExitThread(0);
    }   

    // handling routine
    if ( m_nIndex != m_nPreIndex )
	{
        m_nPreIndex = m_nIndex;
		s.Format( _T("Buffer Index : %d"), m_nPreIndex );	
		m_lbBufferIndex->SetWindowText( s );
	}
	Sleep(300);

    return SUCCESS;
}

LONG CCANRecvDlg::AllocMsgMem()
{
	m_pData = ( PCAN_MSG_T )GlobalAlloc( GPTR, m_nBufferSize*sizeof(CAN_MSG_T) );
	GlobalLock( m_pData );

    return SUCCESS;
}

LONG CCANRecvDlg::FreeMsgMem()
{
    if (m_pData)
    {
	    GlobalUnlock( m_pData );
	    GlobalFree( m_pData );
    }

    return SUCCESS;
}

⌨️ 快捷键说明

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