📄 can.c
字号:
#include "includes.h"
/*********************************************************************
* Private definitions derived from Maestro Generated Definitions
********************************************************************/
//CANSendBitRate 50K LIWEI calculate
#define _B050k_BRGCON1 (B050k_BRG1_SJW << 6) | B050k_BRG1_PRESCALE
#define _B050k_BRGCON2 (B050k_BRG2_SEG2PHTS << 7) | (B050k_BRG2_SAM << 6) | (B050k_BRG2_SEG1PH << 3) | B050k_BRG2_PRSEG
#define _B050k_BRGCON3 (B050k_BRG3_WAKFIL << 6) | B050k_BRG3_SEG2PH
//CANSendBitRate 100K LIWEI calculate
#define _B100k_BRGCON1 (B100k_BRG1_SJW << 6) | B100k_BRG1_PRESCALE
#define _B100k_BRGCON2 (B100k_BRG2_SEG2PHTS << 7) | (B100k_BRG2_SAM << 6) | (B100k_BRG2_SEG1PH << 3) | B100k_BRG2_PRSEG
#define _B100k_BRGCON3 (B100k_BRG3_WAKFIL << 6) | B100k_BRG3_SEG2PH
/*********************************************************************
* Private types of Standard Fram 11 Bits ID
********************************************************************/
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 //near是段内修饰符,在32位编译器,near或者far没有用处
#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 char CidAddress)
{
NEAR _INT filters;
NEAR unsigned char oldState,CIDADDRESS;
CIDADDRESS = CidAddress;
filters.word = ((unsigned int)(CIDADDRESS)<<5)+((unsigned int)(1)<<15);
// Remember the previous state
oldState = CANCON;
// Place the CAN peripherial into Config mode
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 = 0x00;
RXM0SIDH = 0x88;
// break;
// case 0x20:
RXF1SIDL = (NEAR unsigned char)(filters.bytes.LSB);
RXF1SIDH = (NEAR unsigned char)(filters.bytes.MSB);
RXM0SIDL = 0x00;
RXM0SIDH = 0x88;
// 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 = 0x88;
// 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: Modified by LIWEI
********************************************************************/
NEAR unsigned char CANSetBitRate(NEAR unsigned char bitrate)
{
switch (bitrate)
{
case 50: //50K
BRGCON1 = _B050k_BRGCON1;
BRGCON2 = _B050k_BRGCON2;
BRGCON3 = _B050k_BRGCON3;
break;
case 100: //100K
BRGCON1 = _B100k_BRGCON1;
BRGCON2 = _B100k_BRGCON2;
BRGCON3 = _B100k_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)
*
* PreCondition:
*
* Input: none
*
* Output: none
*
* Side Effects:
*
* Overview: Indicates to the module that the data has been read.
*
* Note: This effectively frees the active hardware buffer
* to continue receiving.
********************************************************************/
void CANRead(void)
{
if (_msgRxBuf == 0)
{
RXB0CONbits.RXFUL = 0;
}
else
if (_msgRxBuf == 1)
{
RXB1CONbits.RXFUL = 0;
}
}
/*********************************************************************
* Function: NEAR unsigned char CANIsTxRdy(void)
*
* PreCondition:
*
* Input: none
*
* Output: unsigned char status of the request
*
* Side Effects:
*
* Overview: Returns TRUE if the transmit engine is ready to
* accept new data to transmit.
*
* Note: This function is as simple as it gets, i.e. direct
* access to only one TX buffer.
********************************************************************/
NEAR unsigned char CANIsTxRdy(void)
{
return (!(TXB0CONbits.TXREQ));
}
/*********************************************************************
* Function: NEAR unsigned char CANIsMsgSent(void)
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -