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

📄 can18xx8.c

📁 一个CAN学习程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
 *
 *              PIC18CXX8 CAN C Library Source Code
 *
 *********************************************************************
 * FileName:        CAN18CXX8.C
 * Dependencies:    CAN18CXX8.h
 * Date:            09/06/00
 * Processor:       PIC18CXX8
 * Complier:        MPLAB 5.11.00
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the 揅ompany? for its PICmicro?Microcontroller is intended and
 * supplied to you, the Company抯 customer, for use solely and
 * exclusively on Microchip PICmicro Microcontroller products. 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 揂S 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
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Nilesh Rajbharti     9/6/00  Original        (Rev 1.0)
 * Nilesh Rajbharti     12/1/00 Fixed bugs.
 *                              (CANRegsToID, CANReceiveMessage,
 *                               CANSetMask + Added
 *                               CAN_CONFIG_DBL_BUFFER_ON/OFF option)
 * Nilesh Rajbharti     6/8/01  Renamed CAN_CONFIG_DBL_BUFFERED to
 *                              CAN_RX_DBL_BUFFERED
 * Nilesh Rajbharti     10/11/01 Added support for HITECH compiler
 *                              Modified CAN_MESSAGE_ID def to be
 *                              compatible with HITECH Compiler
 *                              (Rev 1.1)
 * Nilesh Rajbharti     6/5/02  Modified RXB0DLC_RTR def to fix compiler
 *                              missing def problem.
 *                              Fixed CANIDToRegs() where "static"
 *                              mode would not compile.  (Rev 1.2)
 *
 ********************************************************************/
#include "can18xx8.h"

#if defined(MCHP_C18)
    #include <p18f458.h>    // p18cxxx.h must have current processor
                            			// defined.
#endif

#if defined(HITECH_C18)
    #include <pic18.h>
#endif


#if defined(MCHP_C18)
    #define RXB0CON_RX0DBEN     RXB0CONbits.RXB0DBEN
    #define BRGCON2_SAM         BRGCON2bits.SAM
    #define BRGCON2_SEG2PHTS    BRGCON2bits.SEG2PHTS
    #define BRGCON3_WAKFIL      BRGCON3bits.WAKFIL
    #define PIR3_RXB0IF         PIR3bits.RXB0IF
    #define COMSTAT_RX0OVFL     COMSTATbits.RXB0OVFL
    #define PIR3_RXB1IF         PIR3bits.RXB1IF
    #define COMSTAT_RX1OVFL     COMSTATbits.RXB1OVFL
    #define RXB0DLC_RTR         (RXB0DLC & 0x40) // RXB0DLCbits.RTR
    #define RXB0SIDL_EXID       RXB0SIDLbits.EXID
    #define PIR3_IRXIF          PIR3bits.IRXIF
#endif

#if defined(HITECH_C18)
    #define RXB0CON_RX0DBEN     RXB0DBEN
    #define BRGCON2_SAM         SAM
    #define BRGCON2_SEG2PHTS    SEG2PHTS
    #define BRGCON3_WAKFIL      WAKFIL
    #define PIR3_RXB0IF         RXB0IF
    #define COMSTAT_RX0OVFL     RXB0OVFL
    #define PIR3_RXB1IF         RXB1IF
    #define COMSTAT_RX1OVFL     RXB1OVFL
    #define RXB0DLC_RTR         RXB0RXRTR
    #define RXB0SIDL_EXID       RXB0EXID
    #define PIR3_IRXIF          IRXIF
#endif



/*
 * Private helper functions to convert 32-bit CAN ID value into
 * corresponding PIC18CXX8 registers and vice-versa.
 */

static void CANIDToRegs(BYTE* ptr,
                        unsigned long val,
                        enum CAN_CONFIG_FLAGS type);
static void RegsToCANID(BYTE* ptr,
                        unsigned long *val,
                        enum CAN_CONFIG_FLAGS type);


/*********************************************************************
 * Function:        void CANInitialize(BYTE SJW,
 *                                      BYTE BRP,
 *                                      BYTE PHSEG1,
 *                                      BYTE PHSEG2,
 *                                      BYTE PROPSEG,
 *                                      enum CAN_CONFIG_FLAGS flags)
 *
 * PreCondition:    MCU must be in Configuration mode or else these
 *                  values will be ignored.
 *
 * Input:           SJW     - SJW value as defined in 18CXX8 datasheet
 *                              (Must be between 1 thru 4)
 *                  BRP     - BRP value as defined in 18CXX8 datasheet
 *                              (Must be between 1 thru 64)
 *                  PHSEG1  - PHSEG1 value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  PHSEG2  - PHSEG2 value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  PROPSEG - PROPSEG value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  flags   - Value of type enum CAN_CONFIG_FLAGS
 *
 * Output:          CAN bit rate is set. All masks registers are set
 *                  '0' to allow all messages.
 *                  Filter registers are set according to flag value.
 *                  If (config & CAN_CONFIG_VALID_XTD_MSG)
 *                      Set all filters to XTD_MSG
 *                  Else if (config & CONFIG_VALID_STD_MSG)
 *                      Set all filters to STD_MSG
 *                  Else
 *                      Set half of the filters to STD while rests to
 *                      XTD_MSG.
 *
 * Side Effects:    All pending transmissions are aborted.
 *
 ********************************************************************/
 void CANInitialize(BYTE SJW,
                    BYTE BRP,
                    BYTE PHSEG1,
                    BYTE PHSEG2,
                    BYTE PROPSEG,
                    enum CAN_CONFIG_FLAGS config)
 {
     BYTE FilterConfig1;
     BYTE FilterConfig2;

    // In order to setup necessary config parameters of CAN module,
    // it must be in CONFIG mode.
    CANSetOperationMode(CAN_OP_MODE_CONFIG);

    // Now set the baud rate.
    CANSetBaudRate(SJW,
                    BRP,
                    PHSEG1,
                    PHSEG2,
                    PROPSEG,
                    config);

    RXB0CON = config & CAN_CONFIG_MSG_BITS;
    if ( (config & CAN_CONFIG_DBL_BUFFER_BIT)
                == CAN_CONFIG_DBL_BUFFER_ON )
        RXB0CON_RX0DBEN = 1;


    RXB1CON = RXB0CON;

    // Set default filter and mask registers for all receive buffers.
    CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG);
    CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG);

    switch( (config & CAN_CONFIG_MSG_BITS) | ~CAN_CONFIG_MSG_BITS )
    {
    case CAN_CONFIG_VALID_XTD_MSG:
        FilterConfig1 = CAN_CONFIG_XTD_MSG;
        FilterConfig2 = CAN_CONFIG_XTD_MSG;
        break;

    case CAN_CONFIG_VALID_STD_MSG:
        FilterConfig1 = CAN_CONFIG_STD_MSG;
        FilterConfig2 = CAN_CONFIG_STD_MSG;
        break;
    default:
        FilterConfig1 = CAN_CONFIG_STD_MSG;
        FilterConfig2 = CAN_CONFIG_XTD_MSG;
        break;
    }

    // By default, there will be no mask on any receive filters,
    // hence filter value of '0' will be ignored.
    CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1);
    CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1);
    CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2);
    CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2);
    CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2);
    CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2);

    // Restore to Normal mode.
    CANSetOperationMode(CAN_OP_MODE_NORMAL);
}

//////////////////////////////////////////////////////////////////////

/*********************************************************************
 * Function:        void CANSetOperationMode(CAN_OP_MODE mode)
 *
 * PreCondition:    None
 *
 * Input:           mode    - Operation mode code
 *                            must be of type enum CAN_OP_MODES
 *
 * Output:          MCU is set to requested mode
 *
 * Side Effects:    None
 *
 * Overview:        Given mode byte is copied to CANSTAT and made
 *                  sure that requested mode is set.
 *
 * Note:            This is a blocking call.  It will not return until
 *                  requested mode is set.
 ********************************************************************/
void CANSetOperationMode(enum CAN_OP_MODE mode)
{
	
     // Request desired mode.
     CANCON = mode;

    // Wait till desired mode is set.
    
    while( ( CANSTAT & CAN_OP_MODE_BITS) != mode );
}

//////////////////////////////////////////////////////////////////////

/*********************************************************************
 * Function:        void CANSetBaudRate(BYTE SJW,
 *                                      BYTE BRP,
 *                                      BYTE PHSEG1,
 *                                      BYTE PHSEG2,
 *                                      BYTE PROPSEG,
 *                                      enum CAN_CONFIG_FLAGS flags)
 *
 * PreCondition:    MCU must be in Configuration mode or else these
 *                  values will be ignored.
 *
 * Input:           SJW     - SJW value as defined in 18CXX8 datasheet
 *                              (Must be between 1 thru 4)
 *                  BRP     - BRP value as defined in 18CXX8 datasheet
 *                              (Must be between 1 thru 64)
 *                  PHSEG1  - PHSEG1 value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  PHSEG2  - PHSEG2 value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  PROPSEG - PROPSEG value as defined in 18CXX8
 *                            datasheet
 *                              (Must be between 1 thru 8)
 *                  flags   - Value of type enum CAN_CONFIG_FLAGS
 *
 * Output:          CAN bit rate is set as per given values.
 *
 * Side Effects:    None
 *
 * Overview:        Given values are bit adjusted to fit in 18CXX8
 *                  BRGCONx registers and copied.
 *
 ********************************************************************/
 void CANSetBaudRate(BYTE SJW,
                     BYTE BRP,
                     BYTE PHSEG1,
                     BYTE PHSEG2,
                     BYTE PROPSEG,
                     enum CAN_CONFIG_FLAGS flags)
 {
     // Actual values are offset '0'.
     // Hence map given values from offset '1' to offset '0'
     SJW--;
     BRP--;
     PHSEG1--;
     PHSEG2--;
     PROPSEG--;

    // Bit adjust given values into their appropriate registers.
    BRGCON1 = SJW << 6;
    BRGCON1 |= BRP;

    BRGCON2 = PHSEG1 << 3;
    BRGCON2 |= PROPSEG;

    if ( !(flags & CAN_CONFIG_SAMPLE_BIT) )
        BRGCON2_SAM = 1;

    if ( flags & CAN_CONFIG_PHSEG2_PRG_BIT )
        BRGCON2_SEG2PHTS = 1;


    BRGCON3 = PHSEG2;
    if ( flags & CAN_CONFIG_LINE_FILTER_BIT )
        BRGCON3_WAKFIL = 1;

}

//////////////////////////////////////////////////////////////////////
/*********************************************************************
 * Function:        void CANIDToRegs(BYTE* ptr,
 *                                      unsigned long val,
 *                                      enum CAN_CONFIG_FLAGS type)
 *
 * PreCondition:    None
 *
 * Input:           ptr     - Starting address of a buffer to be updated
 *                  val     - 32-bit value to be converted
 *                  type    - Type of message - either
 *                            CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
 *
 * Output:          Given CAN id value 'val' is bit adjusted and copied
 *                  into corresponding PIC18CXX8 CAN registers
 *
 * Side Effects:    None
 *
 * Overview:        If given id is of type standard identifier,
 *                  only SIDH and SIDL are updated
 *                  If given id is of type extended identifier,
 *                  bits val<17:0> is copied to EIDH, EIDL and SIDH<1:0>
 *                  bits val<28:18> is copied to SIDH and SIDL
 *
 ********************************************************************/
static void CANIDToRegs(BYTE* ptr,
                        unsigned long val,
                        enum CAN_CONFIG_FLAGS type)
{
    CAN_MESSAGE_ID *Value;

    Value =  (CAN_MESSAGE_ID*)&val;

    if ( type & CAN_CONFIG_MSG_TYPE_BIT )
    {
        // Standard Identifier
        *ptr = Value->BYTES.BYTE_1 >> 3;        // Copy SID<7:3> to SIDH<4:0>
        *ptr |= (Value->BYTES.BYTE_2 << 5);     // Copy SID<10:8> to SIDH<7:5>
        ptr++;                                  // Point to SIDL
        *ptr = Value->BYTES.BYTE_1 << 5;        // Copy SID<2:0> to SIDL<7:5>
    }
    else
    {
        // Extended Identifier
        *ptr = Value->BYTES.BYTE_3 >> 5;        // Copy EID<23:21> to SIDH<2:0>
        *ptr |= Value->BYTES.BYTE_4 << 3;       // Copy EID<28:24> to SIDH<7:3>
        ptr++;                                  // Point to SIDL
        *ptr = (Value->BYTES.BYTE_3 << 3) & 0xE0; // Copy EID<20:18> to SIDL<7:5>
                                                // mask out EID<17:16> bits
        *ptr |= 0b00001000;                     // Set EXIDEN bit  to SIDL<3>
        *ptr |= Value->BYTES.BYTE_3 & 0x03;     // Copy EID<17:16> to SIDL<1:0>
        ptr++;                                  // Point to EIDH
        *ptr = Value->BYTES.BYTE_2;             // Copy EID<15:8> to EIDH<7:0>
        ptr++;                                  // Point to EIDL
        *ptr = Value->BYTES.BYTE_1;             // Copy EID<7:0> to EIDL<7:0>
    }
}

//////////////////////////////////////////////////////////////////////
/*********************************************************************
 * Function:        void RegsToCANID(BYTE *ptr,
 *                                      unsigned long *val,
 *                                      enum CAN_CONFIG_FLAGS type)
 *
 * PreCondition:    None
 *
 * Input:           ptr     - Starting address of a buffer to be updated
 *                  val     - 32-bit buffer to hold value
 *                  type    - Type of message - either
 *                            CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG

⌨️ 快捷键说明

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