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

📄 lindriver.c

📁 基于MC908QY4的LIN从站通信例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************************
*                                                                                       
*       Copyright (C) 2003 Motorola, Inc.
*       All Rights Reserved
*
* Filename:     $RCSfile: LINdriver.c,v $
* Author:       $Author: ttz778 $
* Locker:       $Locker:  $
* State:        $State: Exp $
* Revision:     $Revision: 1.2 $
*
* Functions:    LIN908QY4 Driver
*
* History:      Use the RCS command log to display revision history
*               information.
*
*                                                                                       
*                                                                                                        
*****************************************************************************************/

/*		Includes				*/
#include <MC68HC908QY4.h>
#include "LINdriver.h"
#include "Tx_Config.h"

#pragma DATA_SEG SHORT _DATA_ZEROPAGE


/*		Global Variables		*/
U8 volatile near TCH0LBuff, TCH0HBuff, BreakH, BreakL, BreakLimitH, BreakLimitL;
U8 volatile near BitTimeH, BitTimeL, HBitTimeH, HBitTimeL;
U8 volatile near LinState; 
U8 volatile near MessageIndex;
U8 volatile near SyncFieldBits;
U8 volatile BitCount, ByteCount;
U8 volatile near SWSCIDR, SWSCIDRB;  
U8 volatile near Id ;
U8 volatile near FrameBuffer[10];
U8 volatile near FrameTimeOut, NoRelevantID; 
U8 volatile near BitClockReload8H;
U8 volatile near BitClockReload8L;

volatile LINERRORSTR _LinERROR;		/* Look in the header file to see what this is */

#pragma DATA_SEG DEFAULT 

/* 		Prototypes		*/
void AddBitTime8(void);
void AddBitTimeH(void);
void AddBitTime(void);


/******************************************************************************************/

interrupt void TimA1ISR(void)
{
    U8 Dummy,i;
	
		
    if (LinState == ReceiveId)
    { 
        asm 
        {	
            ASR Id				//Shift Rx into Id variable
            BRCLR 1,PTA,LBL8
            BSET 7,Id
            BRA END1
         LBL8:
            BCLR 7,Id
         END1:
             //Finished shifting one				  	.  
        }
        /* Keep updating the timer to catch the next bit until all 8 are in Id (asm code above)*/	  
        if (BitCount <= 6) 
        {	
            AddBitTime();
            BitCount++;		
        }
        
        else   //got the whole Id
        {
            if (Id == SLEEP)   //sleep defined in LINdriver.h, should be 0x80
            {		
                LINSleep = 1; /* If LIN sleep command set the flag */
            }
            else 
            { 
                LINSleep = 0;   //stay awake
            }
                        
            BitCount = 0;        //Reset BitCount and MessageIndex
            MessageIndex = 0xFF;
	             
            for (i=0;i < No_of_Ids;i++)  //loop through identifier table...
            {
                // ...to check if Id exist in the table, i.e. is relevant to this node.
                if (Id == IdTbl[i])       
	        	{
                    MessageIndex = i;    //If found, save away index
                }
            }
	              
            if (MessageIndex == 0xFF){   //Found no id for this node, keep waiting...
                LinState = Idle;
                TSC1 = 0x48;		/* Set for input capture on falling edge */
                NoRelevantID++; //Keep track of how many Ids have been sent out that are NOT relevant for this node
	        	ByteCount = 0;
	        }
            /* Check if master or slave task */							
            else if ((MessageCountTbl[MessageIndex] & 0xF0) == 0) 
            {	//Id is relevant for this node and is a "To Send" Id 
                LinState = Sending; 	
                NoRelevantID = 0;       //reset NoRelevantId since has received a relevant id
                
                
                //Loop from i=0 to "the Id's byte count" - 1 (1=checksum)
                for (i=0 ; i <= ((MessageCountTbl[MessageIndex] & 0xF) - 1);i++) 
                {  
                    // Copy data to framebuffer
                    FrameBuffer[i] = *(MessagePointerTbl[MessageIndex] + i); 
                }
                
                Dummy = ((MessageCountTbl[MessageIndex] & 0xF) - 1);	//check how many messages the frame has, e.g the Id's byte count
	   			
	   			//////////////////lin2.0 checksum/////////////////			
	 				asm	{			/* Calculate checksum */
	 					PSHA
	 					CLRA
	 					CLC
	 					LDX	Dummy
	 				Sloop:						
	   					ADC		@FrameBuffer - 1,X			
	   					DBNZX	Sloop
	   					ADC   Id
	   					ADC		#0
	   					COMA
	   					STA 	i
	   					PULA
	   				}
	   			///////////////////////////////////////////////////	
					FrameBuffer[Dummy] = i; 		// load Checksum in to the byte after last databyte
	  				AddBitTime8();		//Time has moved on so need to catch up and get ahead of time again - add 8 bit times
	  				TSC1 = 0x50;		// Output compare no pin action
	  				ByteCount = 0;
	  				BitCount = 0;
	       	}
			//else {      //Id is relevant for this node and is a "To Receive" Id
			else if ((MessageCountTbl[MessageIndex] & 0xF0) == 0x10) { 
					LinState = ReceivingWFS;
					TSC1 = 0x48;		// Set for input capture on falling edge
					NoRelevantID = 0;   //reset NoRelevantId since has received a relevant id
					ByteCount = 0;
					BitCount = 0;
	        }
	        
	        //************ added by JA to make sure only "new" msgs are sent if defined as F (ignore)
	        //Check if the message only should be sent if updated, and the msg has been updated
	        else if (((MessageCountTbl[MessageIndex] & 0xF0) == 0xF0) && 
                (LinMsgStatus[MessageIndex]!= LIN_MSG_NOCHANGE) && 
                (LinMsgStatus[MessageIndex]!= LIN_MSG_NODATA)) 
            {
                LinState = Sending; 	
                NoRelevantID = 0;       //reset NoRelevantId since has received a relevant id
                
                
                //Loop from i=0 to "the Id's byte count" - 1 (1=checksum)
                for (i=0 ; i <= ((MessageCountTbl[MessageIndex] & 0xF) - 1);i++) 
                {  
                    FrameBuffer[i] = *(MessagePointerTbl[MessageIndex] + i); // Copy data to framebuffer
                }
                //check how many messages the frame has, e.g the Id's byte count
                Dummy = ((MessageCountTbl[MessageIndex] & 0xF) - 1);	
                
                
                //////////////////lin2.0 checksum/////////////////			
	 				asm	{			/* Calculate checksum */
	 					PSHA
	 					CLRA
	 					CLC
	 					LDX	Dummy
	 				Sloop2:						
	   					ADC		@FrameBuffer - 1,X			
	   					DBNZX	Sloop2
	   					ADC   Id
	   					ADC		#0
	   					COMA
	   					STA 	i
	   					PULA
	   				}
	   			///////////////////////////////////////////////////	
                FrameBuffer[Dummy] = i; 	// load Checksum in to the byte after last databyte
                AddBitTime8();		//Sample 8 bit times ahead
                TSC1 = 0x50;		// Output compare no pin action
                ByteCount = 0;
                BitCount = 0;
            }
            //***************** END of send only new msgs
            
            else 
            {  //ignore this message
                LinState = Idle;
                TSC1 = 0x48;		/* Set for input capture on falling edge */
                ByteCount = 0;
	        }
	    }
	}
    /***************************************/    			
    else if (LinState == Sending)
    {
        switch(BitCount)
        {
            case 0:		//Has not started sending yet
                BitCount++;
                TxPIN = 0;		/* Start bit */
                SWSCIDR = FrameBuffer[ByteCount]; 	/* Load byte to transmit */
                AddBitTime();
                break;
      				
            case 9:		//Has sent all bits in the byte
                /* SWSCIDRB is used to store the read value from the LINbus for biterror checking */ 
                asm
                {   // Shift Rx pin in to SoftwareSCIDataRegBackup. for BitError checking
                    ASR SWSCIDRB	
                    BRCLR 1,PTA,S9LBL8
                    BSET 7,SWSCIDRB
                    BRA S9END1
                 S9LBL8:
                    BCLR 7,SWSCIDRB
                 S9END1:									  	
                }
                
                TxPIN = 1;	/* Stopbit */
                AddBitTime();
                /* check for Bit Error - e.g. when someone has messed with FrameBuffer */
                if (SWSCIDRB != FrameBuffer[ByteCount]) 
                {
                    BitERROR = 1; 
                    BitERROR2 = 1;	/* Set 2 biterror flags */
                } 	
                BitCount = 0;
                ByteCount++;
      				
                /* JA add msg status ---------------*/
                /* After data sent from node, its status is changed from
                 LIN_MSG_UPDATED or LIN_MSG_OVERRUN to LIN_MSG_OK. From 
                 LIN_MSG_OK to LIN_MSG_NOCHANGE. 
                 From LIN_MSG_NODATA or LIN_MSG_NOCHANGE it will stay the same.*/
      				 
                if (ByteCount >= (MessageCountTbl[MessageIndex] & 0xF))
                {  
                    if ((LinMsgStatus[MessageIndex] == LIN_MSG_UPDATED) || 
                       (LinMsgStatus[MessageIndex] == LIN_MSG_OVERRUN) )
                    {
                        LinMsgStatus[MessageIndex] = LIN_MSG_OK;
                    }
                    else if ((LinMsgStatus[MessageIndex] & LIN_MSG_OK) != 0 )
                    {
                        LinMsgStatus[MessageIndex] = LIN_MSG_NOCHANGE;
                    }	
                } 
                /* end msg status -------------------------*/	
      			    
                /* If all bytes are sent or BitError detected abort transmission */     
                if ((ByteCount >= (MessageCountTbl[MessageIndex] & 0xF)) || (BitERROR2 == 1)) 
                {   						
                    LinState = Idle;		//Back to waiting for Id again...
                    BitERROR2 = 0;			/* Reset bit error flag */
                    TSC1 = 0x48;			/* Set to IC on falling edge */   						
                }
                break;
                
            default:	//In the middle of sending....
                asm
                { 
                    ASR SWSCIDRB		/*  save the active state for Bit ERROR check */ 
                    BRCLR 1,PTA,SLBL8
                    BSET 7,SWSCIDRB
                    BRA SEND1
                 SLBL8:
                    BCLR 7,SWSCIDRB
                 SEND1:			  	//Shift Rx pin in to SoftSCIDataRegBackup.  
                    BRCLR 0,SWSCIDR,LBL1
                    BSET TxBIT, TxPORT
                    BRA END
                 LBL1:
                    BCLR TxBIT, TxPORT
                 END:	
                    ASR SWSCIDR
                }
                BitCount++;
                AddBitTime();	
                break;
        }	
    }	 	
    /********************************/					
    else if (LinState == Receiving)
    {
        asm 
        {	
            ASR SWSCIDR			/* Shift RxPin in to Data register variable. */
            BRCLR 1,PTA,RLBL8
            BSET 7,SWSCIDR
            BRA REND1
         RLBL8:
            BCLR 7,SWSCIDR
         REND1:				/* Shifted one */
        }
        /* Keep updating the timer to catch the next bit until all 8 are in SWSCIDR (asm code above)*/
        if (BitCount <= 6)
        {    
            AddBitTime();
            BitCount++;
        }
        else    //Whole byte is in
        {
            TSC1 = 0x48;					/* set for input capture on falling edge */
            FrameBuffer[ByteCount] = SWSCIDR;	/* Save data in buffer */
            BitCount = 0;
            ByteCount++;
            if (ByteCount >= (MessageCountTbl[MessageIndex] & 0xF))   /* If all bytes are received */      						

⌨️ 快捷键说明

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