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 + -
显示快捷键?