📄 can.c
字号:
/*****************************************************************************
*
* Microchip DeviceNet Stack (CAN Driver Source)
*
*****************************************************************************
* FileName: CAN.c
* Dependencies:
* Processor: PIC18F with CAN
* Compiler: C18 02.20.00 or higher
* Linker: MPLINK 03.40.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.
*
*
* This version of the CAN driver for DeviceNet is designed to be very
* simple. Filtering options are static and limited. Receive buffering is
* is restricted to only the two hardware receive buffers. And transmit
* buffering is restricted to only one of three transmit buffers. However,
* the architecture of this driver lends itself to be upgradable to achieve
* better performance without changes to the firmware using this driver.
*
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Ross Fosler 04/28/03 ...
*
*****************************************************************************/
#include "P18F458.H" // Hardware specific header
#include "dnet.def" // Global definitions file
#include "CAN.h"
/*********************************************************************
* Private definitions derived from Maestro Generated Definitions
********************************************************************/
#define _B125k_BRGCON1 (B125k_BRG1_SJW << 6) | B125k_BRG1_PRESCALE
#define _B125k_BRGCON2 (B125k_BRG2_SEG2PHTS << 7) | (B125k_BRG2_SAM << 6) | (B125k_BRG2_SEG1PH << 3) | B125k_BRG2_PRSEG
#define _B125k_BRGCON3 (B125k_BRG3_WAKFIL << 6) | B125k_BRG3_SEG2PH
#define _B250k_BRGCON1 (B250k_BRG1_SJW << 6) | B250k_BRG1_PRESCALE
#define _B250k_BRGCON2 (B250k_BRG2_SEG2PHTS << 7) | (B250k_BRG2_SAM << 6) | (B250k_BRG2_SEG1PH << 3) | B250k_BRG2_PRSEG
#define _B250k_BRGCON3 (B250k_BRG3_WAKFIL << 6) | B250k_BRG3_SEG2PH
#define _B500k_BRGCON1 (B500k_BRG1_SJW << 6) | B500k_BRG1_PRESCALE
#define _B500k_BRGCON2 (B500k_BRG2_SEG2PHTS << 7) | (B500k_BRG2_SAM << 6) | (B500k_BRG2_SEG1PH << 3) | B500k_BRG2_PRSEG
#define _B500k_BRGCON3 (B500k_BRG3_WAKFIL << 6) | B500k_BRG3_SEG2PH
/*********************************************************************
* Private types
********************************************************************/
typedef union _T_INT
{
unsigned int word;
struct _BYTES_
{
unsigned char LSB;
unsigned char MSB;
}bytes;
}_INT;
// This type is used to copy all first fragment messages
typedef struct T_CAN_DATA_TYP0
{
unsigned char D0;
unsigned char D1;
unsigned char D2;
unsigned char D3;
unsigned char D4;
unsigned char D5;
unsigned char D6;
unsigned char D7;
}_CAN_DATA_TYP0;
// This type is used for fragmented I/O messages
typedef struct T_CAN_DATA_TYP1
{
unsigned char D1;
unsigned char D2;
unsigned char D3;
unsigned char D4;
unsigned char D5;
unsigned char D6;
unsigned char D7;
}_CAN_DATA_TYP1;
// This type is specifically used for fragmented explicit messages
typedef struct T_CAN_DATA_TYP2
{
unsigned char D2;
unsigned char D3;
unsigned char D4;
unsigned char D5;
unsigned char D6;
unsigned char D7;
}_CAN_DATA_TYP2;
/*********************************************************************
* Registers for CAN buffer control
********************************************************************/
#if USE_ACCESS == 1
#pragma udata access _A_CAN_FUNCTIONS
#define NEAR near
#else
#define NEAR
#endif
NEAR unsigned char _msgTxTag; // Tag used to remember the last instance
NEAR unsigned char _msgRxBuf; // Reference to the current active rx buffer
//NEAR unsigned char _mac_filter;
/*********************************************************************
* Function: NEAR unsigned char CANOpen(void)
*
* PreCondition: Bitrate and filters should be setup
*
* Input: void
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Open CAN communications
*
* Note: This function should be interprited as a request
* rather than a command. Use CANIsOpen() to
* verify the bus has been opened.
********************************************************************/
NEAR unsigned char CANOpen(void)
{
// Place the CAN peripherial into Normal mode
CANCON = 0;
return (1);
}
/*********************************************************************
* Function: NEAR unsigned char CANClose(void)
*
* PreCondition: Bus communications should be open.
*
* Input: void
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Close CAN communications
*
* Note: This function should be interprited as a request
* rather than a command. Use CANIsOpen() to
* verify the bus is still open.
********************************************************************/
NEAR unsigned char CANClose(void)
{
// Place the CAN peripherial into Config mode
CANCON = 0x40;
CANCON = 0x80;
return (1);
}
/*********************************************************************
* Function: NEAR unsigned char CANIsOpen(void)
*
* PreCondition:
*
* Input: void
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Return the status of communication.
* TRUE = Open, FALSE = Closed
*
* Note:
********************************************************************/
NEAR unsigned char CANIsOpen(void)
{
return (!(CANSTAT & 0xE0));
}
/*********************************************************************
* Function: NEAR unsigned char CANSetFilter(NEAR unsigned int filterID)
*
* PreCondition:
*
* Input: 16-bit filterID
*
* Output: unsigned char status of the request
*
* Side Effects: Communication may be temporarily interrupted
*
* Overview: Adds a filter to the scan list.
*
* Note: No scan list is actually created in this version;
* a hardware filter is to allow a CAN ID or group
* of IDs to be received.
********************************************************************/
NEAR unsigned char CANSetFilter(NEAR unsigned int filterID)
{
NEAR _INT filters;
NEAR unsigned char oldState;
// Remember the previous state
oldState = CANCON;
// Place the CAN peripherial into Config mode
//CANCON = 0x40;
CANCON = 0x80;
// Stall
while ((CANSTAT & 0xE0) != 0x80);
filters.word = filterID;
// Setup masks and filters according to the message
switch (filters.bytes.LSB & 0xE0)
{
case 0x00:
RXF0SIDL = (NEAR unsigned char)(filters.bytes.LSB);
RXF0SIDH = (NEAR unsigned char)(filters.bytes.MSB);
RXM0SIDL = 0xFF;
RXM0SIDH = 0xFF;
break;
case 0x20:
RXF1SIDL = (NEAR unsigned char)(filters.bytes.LSB);
RXF1SIDH = (NEAR unsigned char)(filters.bytes.MSB);
RXM0SIDL = 0xFF;
RXM0SIDH = 0xFF;
break;
case 0x40:
case 0x60:
case 0x80:
case 0xA0:
case 0xC0:
case 0xE0:
RXF2SIDL = (NEAR unsigned char)(filters.bytes.LSB);
RXF2SIDH = (NEAR unsigned char)(filters.bytes.MSB);
RXM1SIDL = 0x00;
RXM1SIDH = 0xFF;
break;
}
// Place the bus back into run mode
CANCON = oldState;
return (1);
}
/*********************************************************************
* Function: NEAR unsigned char CANClrFilter(NEAR unsigned int filterID)
*
* PreCondition:
*
* Input: 16-bit filterID
*
* Output: unsigned char status of the request
*
* Side Effects: Communication may be temporarily interrupted
*
* Overview: Removes a filter from the scan list.
*
* Note: No scan list is actually created in this version;
* a hardware filter is used to allow a CAN ID or
* group of IDs to be received.
********************************************************************/
NEAR unsigned char CANClrFilter(NEAR unsigned int filterID)
{
NEAR unsigned char oldState;
// Remember the previous state
oldState = CANCON;
// Place the CAN peripherial into Config mode
//CANCON = 0x40;
CANCON = 0x80;
// Stall
while ((CANSTAT & 0xE0) != 0x80);
// Clear filters
switch ((NEAR unsigned char)(filterID & 0xE0))
{
case 0x00:
RXF0SIDLbits.EXIDEN = 1;
break;
case 0x20:
RXF1SIDLbits.EXIDEN = 1;
break;
case 0x40:
case 0x60:
case 0x80:
case 0xA0:
case 0xC0:
case 0xE0:
break;
}
// Place the bus back into run mode
CANCON = oldState;
return (1);
}
/*********************************************************************
* Function: NEAR unsigned char CANSetBitRate(NEAR unsigned char bitrate)
*
* PreCondition:
*
* Input: bitrate
*
* Output: unsigned char status of the request
*
* Side Effects: Communication may be temporarily interrupted
*
* Overview: Changes the bitrate of the node.
*
* Note:
********************************************************************/
NEAR unsigned char CANSetBitRate(NEAR unsigned char bitrate)
{
switch (bitrate)
{
case 0:
BRGCON1 = _B125k_BRGCON1;
BRGCON2 = _B125k_BRGCON2;
BRGCON3 = _B125k_BRGCON3;
break;
case 1:
BRGCON1 = _B250k_BRGCON1;
BRGCON2 = _B250k_BRGCON2;
BRGCON3 = _B250k_BRGCON3;
break;
case 2:
BRGCON1 = _B500k_BRGCON1;
BRGCON2 = _B500k_BRGCON2;
BRGCON3 = _B500k_BRGCON3;
break;
default:
return (0); // This could be autobaud
}
return (1);
}
/*********************************************************************
* Function: NEAR unsigned char CANIsBusError(void)
*
* PreCondition:
*
* Input: none
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Returns an error code.
*
* Note:
********************************************************************/
NEAR unsigned char CANIsBusOffError(void)
{
// If there is an error then return the Bus-off flag
if (PIR3bits.ERRIF)
{
// Reset the interrupt flag
PIR3bits.ERRIF = 0;
// Return the bus off bit
return(COMSTATbits.TXBO);
}
// Otherwise return no error
else
return (0);
}
/*********************************************************************
* Function: NEAR unsigned char CANIsRxRdy(void)
*
* PreCondition:
*
* Input: none
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Returns TRUE if there is data waiting.
*
* Note:
********************************************************************/
NEAR unsigned char CANIsRxRdy(void)
{
// Check hardware buffer 0
if (RXB0CONbits.RXFUL)
{
_msgRxBuf = 0;
return (RXB0CONbits.RXFUL);
}
else
// Check hardware buffer 1
if (RXB1CONbits.RXFUL)
{
_msgRxBuf = 1;
return (RXB1CONbits.RXFUL);
}
else
return (0);
}
/*********************************************************************
* Function: void CANRead(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -