f53x_linsnooper_lin.c

来自「8051试验程序 基础教材」· C语言 代码 · 共 264 行

C
264
字号
//-----------------------------------------------------------------------------
// F53x_LIN.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// File Description:
//
// This file contains all functions used by the LIN protocol implemented in the
// C8051F53x
//
// FID:
// Target:          C8051F53x
// Tool chain:      KEIL C51 7.20
// Command Line:    None
// Project Name:    LIN Snooper
//
// Release 1.0
//    -Initial Revision
//    -01 NOV 2006
//
// Fix formatting


//-----------------------------------------------------------------------------
// Header File Preprocessor Directive
//-----------------------------------------------------------------------------
#ifndef __LIN_C__
#define __LIN_C__


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <ioc8051f530.h>                 // SFR declarations
#include "F53x_LINSNooper_Main.h"      // Include common specific definitions
#include "F53x_LINSNooper_LIN.h"       // Include LIN specific definitions
#include "F53x_LINSNooper_Flash.h"     // Include Flash specific definitions


//-----------------------------------------------------------------------------
// Constant Definitions
//-----------------------------------------------------------------------------
#define  F53x_LIN_SOURCE


//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
unsigned char LIN_BUFFER[LIN_BUFFER_SIZE];      // Buffer for data received via LIN
unsigned char LIN_BUFFER_PUSH;         // Position to push byte in buffer
unsigned char LIN_BUFFER_GET;          // Position to get byte from buffer
volatile unsigned char LIN_ID_RECEIVED;         // ID received flag


//-----------------------------------------------------------------------------
// LIN_Initialize
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
// Description  : Initializes LIN interface
// Note: This function initialized the baud rate and slave mode
//-----------------------------------------------------------------------------
void LIN_Initialize(void)
{
    LINCF = _ENABLE;                    // Activate the interface
    mLIN_WaitUntilInactive();           // Wait until interface inactive

    LINCF |= LINSLAVE + _SLAVE_BAUD_MODE;
    mLIN_PointMul();
#if _SLAVE_BAUD_MODE == MANUALBAUD
    LINDATA = (_LINPRESCALER<<6) + (_LINMUL<<1) + ((_LINDIV&0x0100)>>8);
#else
    LINDATA = (_LINPRESCALER<<6) + ((_LINDIV&0x0100)>>8);
#endif
    mLIN_PointDiv();                    // Initialize the LOW(divider)
    LINDATA = (unsigned char)_LINDIV;

    mLIN_PointSize();
    LINDATA = CKHMODE;                  // Initialize the checksum mode

    LINADDR=LINCTRL;                    // Load LIN control address
    LINDATA=RSTERR+RSTINT;              // Select that the slave will receive

    LIN_BUFFER_PUSH = 0;
    LIN_BUFFER_GET = 0;

    EIE1 |= 0x20;                       // Enable LIN interrupt
}


//-----------------------------------------------------------------------------
// LIN_ISR
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
// Description  : LIN Interrupt handling function. Processes all communications
//                in both master and slave modes.
// Note:
//-----------------------------------------------------------------------------
#pragma vector = MODE_int
__interrupt void LIN_ISR(void)
{
    unsigned char i,j;
    unsigned char id;

    mLIN_PointStatus();                     // Load LIN status address
    if( LINDATA & LININTREQ )               // If interrupt requested
    {
        if( LINDATA & DTREQ )               // If ID field received
        {
            /* Store status of LIN interface */
            LIN_BUFFER[LIN_BUFFER_PUSH] = ID_RECEIVED;
            Inc_LIN_BUFFER_PUSH();

            mLIN_PointID();                 // Load LIN ID register
            /* Store Identifier in buffer */
            id = LIN_BUFFER[LIN_BUFFER_PUSH] = LINDATA;
            Inc_LIN_BUFFER_PUSH();

            LIN_ID_RECEIVED = 0xFF;

           mLIN_SetRxMode();                // Message to be received
            if ( id < 64 )
            {
                if ( Flash_Read (id+66) == 'E' )
                {
                    mLIN_PointSize();
                    LINDATA = ENHANCEDCHK;  // Initialize the checksum mode
                }
                else
                {
                    mLIN_PointSize();
                    LINDATA = CLASSICCHK;   // Initialize the checksum mode
                }
                mLIN_SetMessageLength( Flash_Read ( id ) ); // Load the size of the message
            }
            else
            {
                mLIN_PointSize();
                LINDATA = CKHMODE;          // Initialize the checksum mode
                mLIN_SetMessageLength( LINLENGTH ); // Load the size of the message
            }
           mLIN_PointControl();             // Load LIN control address
           LINDATA |= DTACK;                // Ack properly
        }
        else if( LINDATA & ERROR )          // If an error was detected
        {
            mLIN_PointError();              // Load the error address
            /* Store status of LIN interface */
            LIN_BUFFER[LIN_BUFFER_PUSH] = LINDATA;
            Inc_LIN_BUFFER_PUSH();

            LINADDR = LINCTRL;              // Load LIN control register
            LINDATA |= RSTERR;              // Reset the error
        }
        else if( LINDATA & DONE )           // If reception completed
        {
            mLIN_PointControl();            // Point to Control reg.
            if( (LINDATA & TXRX)==0 )       // If not request to transmit
            {
                if ( LIN_ID_RECEIVED == 0xFF)
                {
                    LIN_ID_RECEIVED = 0x00;
                    /* Store status of LIN interface */
                    LIN_BUFFER[LIN_BUFFER_PUSH] = LIN_MSG_RECEIVED_OK;
                    Inc_LIN_BUFFER_PUSH();

                    mLIN_PointSize();               // Point to size register
                    i = LINDATA&0x0F;
                    mLIN_PointDataRegister(1);  // Point to data and read it into array
                    for( j=0; j<i; j++ )
                    {
                        /* Store received Data in buffer */
                        LIN_BUFFER[LIN_BUFFER_PUSH] = LINDATA;
                        Inc_LIN_BUFFER_PUSH();
                        LINADDR++;
                    }
                }
            }
            else
            {
                /* Store status of LIN interface */
                LIN_BUFFER[LIN_BUFFER_PUSH] = LIN_MSG_TRANSMITTED_OK;
                Inc_LIN_BUFFER_PUSH();
            }
        }
        else if( LINDATA & IDLTOUT )        // If a timeout in communications
        {
            /* Store status of LIN interface */
            LIN_BUFFER[LIN_BUFFER_PUSH] = SLEEPMODE;
            Inc_LIN_BUFFER_PUSH();

//          mLIN_PointControl();                // Load LIN control register
//          LINDATA |= SLEEP;                   // Select sleep state
        }
        else if( LINDATA & WUPREQ )     // If an wake-up detected
        {
            /* Store status of LIN interface */
            LIN_BUFFER[LIN_BUFFER_PUSH] = AWAKEN;
            Inc_LIN_BUFFER_PUSH();

//          mLIN_PointControl();                // Load LIN control register
//          LINDATA &= ~SLEEP;              // Put the part back in normal mode
        }

        mLIN_PointControl();                    // Load LIN control address
        LINDATA |= RSTINT;                  // Reset Interrupt
    }
}


//-----------------------------------------------------------------------------
// Inc_LIN_BUFFER_PUSH
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
// Description  : Increnents position to push byte in buffer
// Note:
//-----------------------------------------------------------------------------
void Inc_LIN_BUFFER_PUSH(void)
{
    if (++LIN_BUFFER_PUSH == LIN_BUFFER_SIZE)
    {
        LIN_BUFFER_PUSH = 0;
    }
    if (LIN_BUFFER_PUSH == LIN_BUFFER_GET)
    {
        LIN_BUFFER_PUSH--;
        if (LIN_BUFFER_PUSH > LIN_BUFFER_SIZE)
        {
            LIN_BUFFER_PUSH = LIN_BUFFER_SIZE;
        }
    }
}


//-----------------------------------------------------------------------------
// Inc_LIN_BUFFER_GET
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
// Description  : Increnents position to get byte from buffer
// Note:
//-----------------------------------------------------------------------------
void Inc_LIN_BUFFER_GET(void)
{
    if (++LIN_BUFFER_GET == LIN_BUFFER_SIZE)
    {
        LIN_BUFFER_GET = 0;
    }
}


#endif                                 // endif definition of __LIN_C__

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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