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

📄 co_candrv.c

📁 在pic单片机上实现canopen协议通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *
 * Microchip CANopen Stack (ECAN Driver For CANopen)
 *
 *****************************************************************************
 * FileName:        CO_CANDRV.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	...	
 * 
 *****************************************************************************/


#include	"CO_DEFS.DEF"			// Global definitions
#include	"CO_TYPES.H"
#include	"CO_CANDRV.H"			// Driver services




// Definition of a Microchip CAN filter
typedef union __FILTER
{
	unsigned long dword;
	struct __BYTES
	{
		unsigned char	SIDH;
		unsigned char	SIDL;
		unsigned char 	EIDH;
		unsigned char 	EIDL;
	}bytes;
}_FILTER;


// Parameter area
unsigned char _uCAN_Handle;				// Statically passed parameters
unsigned char _uCAN_Param1;
unsigned char _uCAN_Param2;
unsigned char _uCAN_Param3;
unsigned char _uCAN_Param4;
unsigned char _uCAN_ret;

// Driver related static data
unsigned char 	_uCAN_Bitrate;						// Stored bitrate
unsigned char 	_uCANRxHndls[CAN_MAX_RCV_ENDP];		// Filter handles
_FILTER			_uCANRxIDRes[CAN_MAX_RCV_ENDP];		// Filters
unsigned char 	_uCANTxHndls[3];					// Transmit handles

unsigned char _uCANReq;					// Queued driver request

unsigned char _uCANOldMode;




/* ******** CAN Control Services ******* */


/*********************************************************************
 * Function:        void _CANEventManager(void)
 *
 * PreCondition:    none
 *
 * Input:       	none
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        This function processes any queued requests in
 *					the CAN driver.
 *
 * Note:          	
 ********************************************************************/
void _CANEventManager(void)
{
	if (_uCANReq)
	{
		switch (_uCANReq)
		{	
			// Filter has been modified, re-sync		
			case 1:
				// Check for config mode
				if (CANSTATbits.OPMODE2)
				{
					if (_uCANRxHndls[0]) {*(_FILTER *)(&RXF0SIDH) = _uCANRxIDRes[0]; RXFCON0bits.RXF0EN = 1;}
					else RXFCON0bits.RXF0EN = 0;
					#if CAN_MAX_RCV_ENDP > 1
					if (_uCANRxHndls[1]) {*(_FILTER *)(&RXF1SIDH) = _uCANRxIDRes[1]; RXFCON0bits.RXF1EN = 1;}
					else RXFCON0bits.RXF1EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 2
					if (_uCANRxHndls[2]) {*(_FILTER *)(&RXF2SIDH) = _uCANRxIDRes[2]; RXFCON0bits.RXF2EN = 1;}
					else RXFCON0bits.RXF2EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 3
					if (_uCANRxHndls[3]) {*(_FILTER *)(&RXF3SIDH) = _uCANRxIDRes[3]; RXFCON0bits.RXF3EN = 1;}
					else RXFCON0bits.RXF3EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 4
					if (_uCANRxHndls[4]) {*(_FILTER *)(&RXF4SIDH) = _uCANRxIDRes[4]; RXFCON0bits.RXF4EN = 1;}
					else RXFCON0bits.RXF4EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 5
					if (_uCANRxHndls[5]) {*(_FILTER *)(&RXF5SIDH) = _uCANRxIDRes[5]; RXFCON0bits.RXF5EN = 1;}
					else RXFCON0bits.RXF5EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 6
					if (_uCANRxHndls[6]) {*(_FILTER *)(&RXF6SIDH) = _uCANRxIDRes[6]; RXFCON0bits.RXF6EN = 1;}
					else RXFCON0bits.RXF6EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 7
					if (_uCANRxHndls[7]) {*(_FILTER *)(&RXF7SIDH) = _uCANRxIDRes[7]; RXFCON0bits.RXF7EN = 1;}
					else RXFCON0bits.RXF7EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 8
					if (_uCANRxHndls[8]) {*(_FILTER *)(&RXF8SIDH) = _uCANRxIDRes[8]; RXFCON1bits.RXF8EN = 1;}
					else RXFCON1bits.RXF8EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 9
					if (_uCANRxHndls[9]) {*(_FILTER *)(&RXF9SIDH) = _uCANRxIDRes[9]; RXFCON1bits.RXF9EN = 1;}
					else RXFCON1bits.RXF9EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 10
					if (_uCANRxHndls[10]) {*(_FILTER *)(&RXF10SIDH) = _uCANRxIDRes[10]; RXFCON1bits.RXF10EN = 1;}
					else RXFCON1bits.RXF10EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 11
					if (_uCANRxHndls[11]) {*(_FILTER *)(&RXF11SIDH) = _uCANRxIDRes[11]; RXFCON1bits.RXF11EN = 1;}
					else RXFCON1bits.RXF11EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 12
					if (_uCANRxHndls[12]) {*(_FILTER *)(&RXF12SIDH) = _uCANRxIDRes[12]; RXFCON1bits.RXF12EN = 1;}	
					else RXFCON1bits.RXF12EN = 0;	
					#endif
					#if CAN_MAX_RCV_ENDP > 13
					if (_uCANRxHndls[13]) {*(_FILTER *)(&RXF13SIDH) = _uCANRxIDRes[13]; RXFCON1bits.RXF13EN = 1;}
					else RXFCON1bits.RXF13EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 14
					if (_uCANRxHndls[14]) {*(_FILTER *)(&RXF14SIDH) = _uCANRxIDRes[14]; RXFCON1bits.RXF14EN = 1;}
					else RXFCON1bits.RXF14EN = 0;
					#endif
					#if CAN_MAX_RCV_ENDP > 15
					if (_uCANRxHndls[15]) {*(_FILTER *)(&RXF15SIDH) = _uCANRxIDRes[15]; RXFCON1bits.RXF15EN = 1;}
					else RXFCON1bits.RXF15EN = 0;
					#endif
					
					// Cancel the request
					_uCANReq = 0;
					
					// Request normal operation
					CANCON = _uCANOldMode;;
				}
				
				// Request config mode
				else CANCON = 0x80;
				break;
				
			case 2:
				// Check for config mode
				if (CANCONbits.REQOP2)
				{
					// Set the bitrate
					_CANSetBitRate();
					
					// Cancel the request
					_uCANReq = 0;
					
					// Request normal operation
					CANCON = _uCANOldMode;;
				}
				// Request config mode
				else CANCON = 0x80;
				break;
		}			
	}
}



/*********************************************************************
 * Function:        void _CANReset(void)
 *
 * PreCondition:    none
 *
 * Input:       	unsigned char _uCAN_Bitrate
 *                  
 * Output:         	none  
 *
 * Side Effects:    none
 *
 * Overview:        All aspects of the CAN driver are reset.
 *
 * Note:          	This function does not automatically enable the 
 *					device on the network.
 ********************************************************************/
void _CANReset(void)
{
	// Empty an queued requests
	_uCANReq = 0;
	
	// Force the CAN peripherial into Config mode
	CANCON = 0x40;
	CANCON = 0x80;
	
	// Set the bitrate
	_CANSetBitRate();
	
	// Make all programmable buffers receive buffers
	BSEL0 = 0x00;
	
	// Setup the receive buffers
	RXB0CON = 0;
	RXB1CON = 0;
	B0CON = 0;
	B1CON = 0;
	B2CON = 0;
	B3CON = 0;
	B4CON = 0;
	B5CON = 0;
	
	
	// Place the module in enhanced legacy mode
	ECANCON = 0x50;
	
	// Disable all filters
	RXFCON0 = 0;
	RXFCON1 = 0;
	
	// No data byte filtering
	SDFLC = 0;
	
	// Setup filter/buffer association, two filters per buffer
	RXFBCON0 = 0x00;
	RXFBCON1 = 0x11;
	RXFBCON2 = 0x22;
	RXFBCON3 = 0x33;
	RXFBCON4 = 0x44;
	RXFBCON5 = 0x55;
	RXFBCON6 = 0x66;
	RXFBCON7 = 0x77;
	
	// Setup filter/mask association to Mask 0
	MSEL0 = MSEL1 = MSEL2 = MSEL3 = 0;
	
	// Set Mask 0 to not mask any filter bit
	RXM0SIDH = 0xFF;
	RXM0SIDL = 0xE3;
	RXM0EIDH = 0xFF;
	RXM0EIDL = 0xFF;
	
	// Set I/O control
	CIOCON = 0x20;
	
	// Set interrupts
	TXBIE = 0x1C;
	BIE0 = 0xFF;
	
	// Reset all handles
	_uCANRxHndls[0] = 0;
	#if CAN_MAX_RCV_ENDP > 1
	_uCANRxHndls[1] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 2
	_uCANRxHndls[2] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 3
	_uCANRxHndls[3] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 4
	_uCANRxHndls[4] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 5
	_uCANRxHndls[5] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 6
	_uCANRxHndls[6] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 7
	_uCANRxHndls[7] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 8
	_uCANRxHndls[8] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 9
	_uCANRxHndls[9] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 10
	_uCANRxHndls[10] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 11
	_uCANRxHndls[11] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 12
	_uCANRxHndls[12] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 13
	_uCANRxHndls[13] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 14
	_uCANRxHndls[14] = 0;
	#endif
	#if CAN_MAX_RCV_ENDP > 15
	_uCANRxHndls[15] = 0;
	#endif
}







/*********************************************************************
 * Function:        void _CANSetBitRate(void)
 *
 * PreCondition:    This function should only be called when the 
 *					device is not active on the CAN bus.

⌨️ 快捷键说明

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