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

📄 elinmint.c

📁 这个是我在microchip公司的网站下载的PIC18系列单片的一些驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
 *
 *              LIN-Master Software
 *
 *********************************************************************
 * FileName:        ELINMInt.c
 * Dependencies:    ELINMInt.h
 * Processor:       18Fxxxx
 * Compilers:	    Microchip C Compiler -> mcc C18 v2.20 or better
 * Assembler:       MPASMWIN 02.70.02 or higher
 * Linker:          MPLINK 2.33.00 or higher
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the "Company") is intended and supplied to you, the Company抯
 * 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 FW provides the necessary functions to create a Master LIN 
 * node driver using an EUSART enabled 18F part.
 *
 * Author               Date            Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * CG			09/4/03	        Initial Release (Maestro 1.0)
 *
 ********************************************************************/

#define    _LINM18ESOURCE

#include "ELINMInt.h"


BYTE _ELINMIntMessageTag;					        // message tag -> identifies one specific message
ELINMINT_CRC _ELINMIntRXCRC;					        // reception CRC buffer
ELINMINT_STATUS _ELINMIntStatus;                                        // main status byte
ELINMINT_STATUS1 _ELINMIntStatus1;				        // second status byte
ELINMINT_MESSAGE_SIZE _ELINMIntMessageSize;		        	// message size
ELINMINT_MESSAGE_SIZE _ELINMIntRXMessageSize;		                // reception message size
BYTE _ELINMIntMessageBuffer[ELINMINT_MAX_MESSAGE_SIZE+3];       	// message buffer
BYTE _ELINMIntReadBack;					        	// saves the last transmitted byte to be compared with feedback

BYTE _ELINMIntMessageBufferPointer;				        // TX byte position pointer
char _ELINMIntSpace;                                    	        // interbyte and interframe space
unsigned int _ELINMIntTFrameMin;				        // timing control variables
unsigned int _ELINMIntTFrameMax;
unsigned int _ELINMIntTHeaderMin;
unsigned int _ELINMIntTHeaderMax;
unsigned long _ELINMIntSleepTimeout;                                    // sleep time-out count variable


/*********************************************************************
 * Function:    BYTE _ELINMIntInitialize(void)
 *
 * PreCondition:
 *
 * Input:

 * Output:      0=NO Error
 *              !0=ERROR CODE
 *
 * Side Effects:
 *
 * Stack Requirements:
 *
 * Overview:	This procedure Initializes:
 *                      The Baud Rate
 *                      Reception Interrupt (enabled)
 *                      Protocol Status bytes - > put protocol in IDLE 
 *                      Interbyte timing
 *                      
 ********************************************************************/
BYTE _ELINMIntInitialize(void)
{
 SPBRG 	=ELINMINT_SPBRG;				        	// set Baud Rate (16 bits)
 SPBRGH =ELINMINT_SPBRGH;
 TXSTA 	=ELINMINT_TXSTA_INIT;					        // initiates transmission and reception
 RCSTA	=ELINMINT_RCSTA_INIT;
 BAUDCON=ELINMINT_BAUDCON_INIT;
 PIE1	|=ELINMINT_PIE1_INIT;			        	        // 
 _ELINMIntSleepTimeout=ELINMINT_SLEEP_TIMEOUT;                          // init bus idle-to-sleep timing
 _ELINMIntSpace=ELINMINT_INTERBYTE_SPACE;		                // start interbyte space
 _ELINMIntStatus.ELINMIntStatusByte=0;                                  // clear status
 _ELINMIntStatus1.ELINMIntStatusByte=0;                                 // clear status1
 _ELINMIntStatus.ELINMINTSTS.IDLE=1;                                    // return to idle state
 return(0);                                                             // return 0 - OK 
}

/*********************************************************************
 * Function:    void _ELINMIntResetProtocol(BYTE code)
 *
 * PreCondition:
 *
 * Input:	BYTE code - any eventual error code
 *					
 * Output:			
 *
 * Side Effects:
 *
 * Stack Requirements:
 *
 * Overview:	This procedure resets the protocol and if necessary 
 * 		sets the error flags
 *
 ********************************************************************/
void _ELINMIntResetProtocol(BYTE code)
{
 _ELINMIntReadBack=RCREG;	        		                // read the receive register to clear RCIF flag
 _ELINMIntStatus1.ELINMIntStatusByte=0;                                 // reset all aux. status conditions including
                                                                        // sleep timeout
 _ELINMIntRXCRC.CRC=0;			        			// reset CRC 
 _ELINMIntStatus.ELINMIntStatusByte=code;	        		// status code set. 
 _ELINMIntSleepTimeout=ELINMINT_SLEEP_TIMEOUT;                          // init bus idle-to-sleep timing
}


/*********************************************************************
 * Function:    void interrupt ELINMIntHandler(void)
 *
 * PreCondition:	
 *
 * Input:

 * Output:
 *
 * Side Effects:
 *
 * Stack Requirements:
 *
 * Overview:	Interrupt Handler for EUSART based Master node LIN
 *		To be called by a timer based interrupt routine 		
 *
 ********************************************************************/

void ELINMIntHandler(void)
{
 if(TXSTA_SENDB==0)     				                // check if it is not sending break 
 {
  if(PIR1_RCIF)						                // also checks if received something	
  {
   if(_ELINMIntStatus.ELINMINTSTS.IDLE)			                // check if in IDLE state	
   {
    if((RCSTA&0x06)==0)				                        // if received without error
    {
     if(RCREG==ELINMINT_WAKEUP_BYTE)			                // then check if it was an wake-up request
     {						
      _ELINMIntSleepTimeout=ELINMINT_SLEEP_TIMEOUT;                     // reinit bus-idle-to sleep timing      
      _ELINMIntReadBack=RCREG;	        		                // read the receive register to clear RCIF flag                
      if(_ELINMIntStatus1.ELINMINTSTS.WAKEUP_SENT)                      // if an wake-up signal was sent from the master to the slave
       _ELINMIntStatus1.ELINMINTSTS.WAKEUP_SENT=0;                      // clear the flag
      else                                                              // if wake-up signal 
       _ELINMIntStatus1.ELINMINTSTS.WAKEUP=1;		                // set the wake-up flag
     } // else if(RCREG==ELINMINT_WAKEUP_BYTE)
    } // if((RCSTA&0x06)==0)
   } // if(_ELINMIntStatus.ELINMINTSTS.IDLE)
   else if(_ELINMIntStatus.ELINMINTSTS.TX)		                // check if transmitting
   {
    if((RCSTA&0x06)&&_ELINMIntMessageBufferPointer)	                // if error and it's not in the BREAK byte (pointer==0)
     _ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_FRAMING_ERROR);	// signal the error
    else						                // if no error detected or error detected in BREAK (expected)
    {  
     if(_ELINMIntMessageBufferPointer==2)		                // then check if it just sent the HEADER
      _ELINMIntStatus1.ELINMINTSTS.HEADER=0;		                // if so turn-off the header transmission flag (it will trigger the check of header max. time)
     if(_ELINMIntSpace)					                // if interbyte space not zero decrement and go away
      _ELINMIntSpace--;
     else if(_ELINMIntReadBack!=RCREG)			                // otherwise check if the byte read is the same as the sent one
      _ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_DATA_ERROR);	// if not signals the error
     else						                // if byte read is the same as the sent one
     {
      if(_ELINMIntMessageSize.SIZE)			                // and if there is still message to be sent
      {
       _ELINMIntReadBack=RCREG;	        		                // read the receive register to clear RCIF flag
       _ELINMIntReadBack=_ELINMIntMessageBuffer[_ELINMIntMessageBufferPointer];	// load next byte to be sent
       TXREG=_ELINMIntReadBack;				                // also load the read-back check byte
       _ELINMIntMessageSize.SIZE--;			                // decrement the counter
       _ELINMIntMessageBufferPointer++;         			// increment the pointer
       _ELINMIntSpace+=ELINMINT_INTERBYTE_SPACE;                        // start interbyte space counter
      }
      else								// if all message already transmitted
      {
       if(_ELINMIntStatus.ELINMINTSTS.RX)                		// and if it's set to receive
       {
        _ELINMIntStatus.ELINMINTSTS.TX=0;                                // then clear the transmission flag               
        _ELINMIntMessageBufferPointer=0;		                // and reset the pointer
       } 
       else															// however, if it's not going to receive
       {
        _ELINMIntStatus1.ELINMINTSTS.FRAME=0;		                // then clear frame check flag (force the max. frame time to be checked)
        _ELINMIntResetProtocol(ELINMINT_IDLEBIT);	                // reset the protocol without error
       } // else
      } // else
     } // else 
    } // else of "if((RCSTA&0x06)&&ELINMIntMessageBufferPointer)"
   } // else if(_ELINMIntStatus.ELINMINTSTS.TX)
   else if(_ELINMIntStatus.ELINMINTSTS.RX)		                // if receiving
   {
    if(RCSTA&0x06)					                // and if an error was detected
     _ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_FRAMING_ERROR);	// reset protocol with error
    else 
    {
     if(_ELINMIntRXMessageSize.SIZE)			                // if no error detected and if there is still message to be received
     {
      _ELINMIntMessageBuffer[_ELINMIntMessageBufferPointer]=RCREG;	// load message data byte in the buffer
      _ELINMIntRXMessageSize.SIZE--;			                // decrement the counter
      _ELINMIntRXCRC.CRC+=RCREG;					// add to CRC      
      if(_ELINMIntRXCRC.CRCbits.CRC8)					// if a carry bit from the lower byte
       _ELINMIntRXCRC.CRCL++;						// add the carry bit 
      _ELINMIntMessageBufferPointer++;      				// increment pointer
     } // if(ELINMIntRXMessageSize.SIZE)
     else															// if all data bytes already received
     {
      _ELINMIntStatus1.ELINMINTSTS.FRAME==0;
      _ELINMIntRXCRC.CRCL += RCREG+1;					// check CRC(checksum) by XORing received CRC
      if(_ELINMIntRXCRC.CRCL)
       _ELINMIntResetProtocol(ELINMINT_IDLEBIT+ELINMINT_ERRORBIT+ELINMINT_CHECKSUM_ERROR); // if error reset protocol and signal error									// if result != 0 error!
      else
       _ELINMIntResetProtocol(ELINMINT_IDLEBIT);			// otherwise just reset protocol without error
     } // else
    } // else	
   } // else if(_ELINMIntStatus.ELINMINTSTS.RX)
  } // if(PIR1_RCIF)
 } // if(SENDB==0) 
 if(_ELINMIntStatus.ELINMINTSTS.IDLE==0) 
 {

⌨️ 快捷键说明

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