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

📄 co_nmte.c

📁 在pic单片机上实现canopen协议通讯
💻 C
字号:

/*****************************************************************************
 *
 * Microchip CANopen Stack (Network Management Error Communications Handler)
 *
 *****************************************************************************
 * FileName:        CO_NMTE.C
 * Dependencies:    
 * Processor:       PIC18F with CAN
 * Compiler:       	C18 02.30.00 or higher
 * Linker:          MPLINK 03.70.00 or higher
 * Company:         Microchip Technology Incorporated
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the "Company") is intended and supplied to you, the Company's
 * customer, for use solely and exclusively with products manufactured
 * by the Company. 
 *
 * The software is owned by the Company and/or its supplier, and is 
 * protected under applicable copyright laws. All rights are reserved. 
 * Any use in violation of the foregoing restrictions may subject the 
 * user to criminal sanctions under applicable laws, as well as to 
 * civil liability for the breach of the terms and conditions of this 
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, 
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED 
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, 
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR 
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *
 * 
 * 
 *
 *
 * Author               Date        Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Ross Fosler			11/13/03	...	
 * 
 *****************************************************************************/


// Heartbeat or node-guard

#include	"CO_DEFS.DEF"			// Global definitions
#include	"CO_TYPES.H"			// Data types
#include	"CO_CANDRV.H"			// Driver services
#include	"CO_COMM.H"				// Object
#include	"CO_DICT.H"				// Dictionary Object Services
#include	"CO_NMTE.H"				// Network Management Error services
#include	"CO_TOOLS.H"			// COB ID tools



UNSIGNED32 		_uNMTE_COBID;

short long 		_uNMTETimer;
UNSIGNED8		_uNMTEState;
UNSIGNED8		_uNMTELocalState;

UNSIGNED16		_uNMTEHeartBeat;
UNSIGNED16		_uNMTEGuardTime;
UNSIGNED8		_uNMTELifeFactor;


unsigned char 	_hNMTE;


void CO_NMTENodeGuardErrEvent(void);


/*********************************************************************
 * Function:        void _CO_COMM_NMTE_HeartBeatAccessEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Process access events to the heartbeat.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_HeartBeatAccessEvent(void)
{
	switch (uDict.cmd)
	{
		//case DICT_OBJ_INFO:		// Get information about the object
		//	break;

		case DICT_OBJ_READ: 	// Read the object
			*(UNSIGNED16 *)(uDict.obj->pReqBuf) = _uNMTEHeartBeat;
			break;

		case DICT_OBJ_WRITE: 	// Write the object
			_uNMTEHeartBeat = *(UNSIGNED16 *)(uDict.obj->pReqBuf);

			// Reset the state
			_uNMTEState.byte = 0;

			// If the heartbeat is greater than 0 then enable heartbeat
			if (_uNMTEHeartBeat.word) 
			{
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEHeartBeat.word;
			}
			else 

			// else if the node guard and life is greater than 0 then enable node guard
			if (_uNMTEGuardTime.word && _uNMTELifeFactor.byte) 
			{
				_uNMTELocalState.byte = 0x80;
				NMTE_NODE_GUARD_EN = 1;
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;
			}
			break;
	}	
}




/*********************************************************************
 * Function:        void _CO_COMM_NMTE_GuardTimeAccessEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Process access events to the guard time.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_GuardTimeAccessEvent(void)
{
	switch (uDict.cmd)
	{
		//case DICT_OBJ_INFO:		// Get information about the object
		//	break;

		case DICT_OBJ_READ: 	// Read the object
			*(UNSIGNED16 *)(uDict.obj->pReqBuf) = _uNMTEGuardTime;
			break;

		case DICT_OBJ_WRITE: 	// Write the object
			_uNMTEGuardTime = *(UNSIGNED16 *)(uDict.obj->pReqBuf);

			// Reset the state
			_uNMTEState.byte = 0;

			// If the heartbeat is greater than 0 then enable heartbeat
			if (_uNMTEHeartBeat.word) 
			{
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEHeartBeat.word;
			}
			else 

			// else if the node guard and life is greater than 0 then enable node guard
			if (_uNMTEGuardTime.word && _uNMTELifeFactor.byte) 
			{
				_uNMTELocalState.byte = 0x80;
				NMTE_NODE_GUARD_EN = 1;
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;
			}		
			break;
	}	
}



/*********************************************************************
 * Function:        void _CO_COMM_NMTE_GuardTimeAccessEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Process access events to the life time factor.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_LifeFactorAccessEvent(void)
{
	switch (uDict.cmd)
	{
		//case DICT_OBJ_INFO:		// Get information about the object
		//	break;

		case DICT_OBJ_READ: 	// Read the object
			*(UNSIGNED8 *)(uDict.obj->pReqBuf) = _uNMTELifeFactor;
			break;

		case DICT_OBJ_WRITE: 	// Write the object
			_uNMTELifeFactor = *(UNSIGNED8 *)(uDict.obj->pReqBuf);

			// Reset the state
			_uNMTEState.byte = 0;

			// If the heartbeat is greater than 0 then enable heartbeat
			if (_uNMTEHeartBeat.word) 
			{
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEHeartBeat.word;
			}
			else 

			// else if the node guard and life is greater than 0 then enable node guard
			if (_uNMTEGuardTime.word && _uNMTELifeFactor.byte) 
			{
				_uNMTELocalState.byte = 0x80;
				NMTE_NODE_GUARD_EN = 1;
				NMTE_TMR_LOCAL_EN = 1;
				_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;
			}		
			break;
	}	
}


/*********************************************************************
 * Function:        void _CO_COMM_NMTE_Open(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Open the NMTE endpoint.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_Open(void)
{
	// Set the COB ID and convert it to MCHP
	_uNMTE_COBID.word = 0x700L + _uCO_nodeID.byte;
	mTOOLS_CO2MCHP(_uNMTE_COBID.word);
	_uNMTE_COBID.word = mTOOLS_GetCOBID();
		
	_uNMTEState.byte = 0;

	// If the heartbeat is greater than 0 then enable heartbeat
	if (_uNMTEHeartBeat.word) 
	{
		NMTE_TMR_LOCAL_EN = 1;
		COMM_NETCTL_NMTE_EN = 1;
		_uNMTETimer = _uNMTEHeartBeat.word;
	}
	else 

	// else if the node guard and life is greater than 0 then enable node guard
	if (_uNMTEGuardTime.word && _uNMTELifeFactor.byte) 
	{
		// Call the driver and request to open a receive endpoint
		mCANOpenMessage((COMM_MSGGRP_NETCTL) | COMM_NETCTL_NMTE, _uNMTE_COBID.word, _hNMTE);
		if (_hNMTE)
		{ 
			COMM_NETCTL_NMTE_EN = 1;
		
			// Reset the toggle memory
			_uNMTELocalState.byte = 0x80;

			NMTE_NODE_GUARD_EN = 1;
			NMTE_TMR_LOCAL_EN = 1;
			_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;
		}
	}
}



/*********************************************************************
 * Function:        void _CO_COMM_NMTE_Close(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        Close the NMTE endpoint.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_Close(void)
{
	// Call the driver, request to close the receive endpoint
	mCANCloseMessage(_hNMTE);
	COMM_NETCTL_NMTE_EN = 0;
}




/*********************************************************************
 * Function:        void _CO_COMM_NMTE_RXEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the receive event handler for the NMTE
 *					endpoint. 
 *
 * Note:          	This is only used for nodeguard.
 ********************************************************************/
void _CO_COMM_NMTE_RXEvent(void)
{
	// If node guard is used and an RTR with 1 byte is received
	if (NMTE_NODE_GUARD_EN)
	{
		if (mCANIsGetRTR())
		{
			if (mCANGetDataLen() == 1) 
			{
				// Queue a request to send data
				COMM_NETCTL_NMTE_TF = 1;
 
				// Reset the timer
				_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;
			}
		}
	}
}



/*********************************************************************
 * Function:        void _CO_COMM_NMTE_TXEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the transmit event handler for the NMTE
 *					endpoint. Node guarding and heartbeat
 *					transmissions are handled.
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_TXEvent(void)
{
	{
		// Set the COB
		*(unsigned long *)(mCANGetPtrTxCOB()) = _uNMTE_COBID.word;

		// Set the length
		mCANPutDataLen(1);

		
		// Send the state or the boot
		if (!NMTE_BOOT_SERVICE)
		{
			// Toggle and strip old state (also known as bootup state)
			_uNMTELocalState.byte = _uNMTELocalState.byte & 0x80;
			if (NMTE_NODE_GUARD_EN) {_uNMTELocalState.bits.b7 = (~_uNMTELocalState.bits.b7);}
			else {_uNMTELocalState.bits.b7 = 0;}

			// Set the data
			if (COMM_STATE_STOP) _uNMTELocalState.byte = _uNMTELocalState.byte | 4;
			else
			if (COMM_STATE_OPER) _uNMTELocalState.byte = _uNMTELocalState.byte | 5;
			else
			if (COMM_STATE_PREOP) _uNMTELocalState.byte = _uNMTELocalState.byte | 127;

			// Load the data
			mCANPutDataByte0(_uNMTELocalState.byte);
		}
		else
		{
			NMTE_BOOT_SERVICE = 0;
			mCANPutDataByte0(0);
		}
	}
}


/*********************************************************************
 * Function:        void _CO_COMM_NMTE_LSTimerEvent(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This is the timer event handler for the NMTE
 *					endpoint. 
 *
 * Note:          	
 ********************************************************************/
void _CO_COMM_NMTE_LSTimerEvent(void)
{
	// Process only if the local timer is enabled
	if (NMTE_TMR_LOCAL_EN)
	{
		// Adjust the time
		_uNMTETimer -= CO_TICK_PERIOD;
			
		// If the timer is zero then
		//if (_uNMTETimer == 0)
		if (_uNMTETimer <= 0)
		{
			// If the heartbeat protocol is enabled
			if (!NMTE_NODE_GUARD_EN)
			{
				// Reset the timer
				_uNMTETimer = _uNMTETimer + _uNMTEHeartBeat.word;
						
				// Queue the endpoint to send a heartbeat	
				COMM_NETCTL_NMTE_TF = 1;
			}

			// Else the node guard protocol is enabled
			else
			{
				// Reset the timer
				_uNMTETimer = _uNMTEGuardTime.word * _uNMTELifeFactor.byte;

				// Notify the application of an error
				CO_NMTENodeGuardErrEvent();
			}
		}
	}
}

⌨️ 快捷键说明

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