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

📄 lindriver.c

📁 基于MC908QY4的LIN从站通信例程
💻 C
📖 第 1 页 / 共 2 页
字号:
            {
                //Dummy is the index for the checksum
                /* check how many messages (data bytes) the frame has */
                Dummy = ((MessageCountTbl[MessageIndex] & 0xF) - 1);  
                
                /////////////////////////lin2.0 checksum///////////////////////
                asm	
                {
                    PSHA
                    CLRA
                    CLC
                    LDX	Dummy
                 loop:				/* Calculate checksum */
                    ADC		@FrameBuffer - 1,X			
                    DBNZX	loop
                    ADC Id
                    ADC		#0
                    COMA
                    STA 	i
                    PULA
                }
                ///////////////////////////////////////////////////////////////
                	
                if (i == FrameBuffer[Dummy]) 	/* If calculated Checksum = received checksum */
                {
                    /* Load data to variables */
                    for (i=0 ; i < ((MessageCountTbl[MessageIndex] & 0xF)-1);i++)  //initial error fixed ->stored checksum+1 so overwriting next msg
                    {
                        *(MessagePointerTbl[MessageIndex] + i) = FrameBuffer[i]; 
                    }    
                }
                else 
	            {
                    ChecksumERROR=1;	/* Error - Set ChecksumERROR flag  */
                }
                LinState = Idle;
                ByteCount = 0;
                BitCount = 0; 		/* Reset process and wait for next break */
	        	
                /* JA added msg status */
                /* set appropriate status for received message */
                /* After message received at node, status is changed to LIN_MSG_UPDATED
                if previously it was in LIN_MSG_NODATA, LIN_MSG_OK or LIN_MSG_NOCHANGE.
                If it was in LIN_MSG_UPDATED it is changed to LIN_MSG_OVERRUN. 
                If it was in LIN_MSG_OVERRUN it will stay the same.*/

                if (( LinMsgStatus[MessageIndex] == LIN_MSG_OK) || 
                    ( LinMsgStatus[MessageIndex] == LIN_MSG_NODATA) ||
                    ( LinMsgStatus[MessageIndex] == LIN_MSG_NOCHANGE))  
                {
                    LinMsgStatus[MessageIndex] = LIN_MSG_UPDATED; 
                }
                else     
                {
                    LinMsgStatus[MessageIndex] = LIN_MSG_OVERRUN; 
                }
                /* end msg status add by JA */ 
            }
                    	 	
            else 	//All bytes are not received yet
            {
                 LinState = ReceivingWFS;	/* Switch state to catch the next expected start bit */ 
            }
        }
    }
    /*****************************************/

    else if (LinState == Idle)	  /* case idle = waiting for falling edge break pulse */
    {
        TCH0HBuff = TCH1H; 		  /* Save IC value, later used to calculate the puls length (in Possiblesynk)*/
        TCH0LBuff = TCH1L;  	  /* Save IC value, later used to calculate the puls length (in Possiblesynk)*/
        TSC1_ELS1A = 1;		
        TSC1_ELS1B = 0;			  /* Set for rising edge int. trig */
        LinState = PossibleSynk;  /* Switch state */
        SyncFieldBits = 0;
    }
    /******************************/		
    else if (LinState == PossibleSynk)	/* case PossibleSynk = waiting for rising edge break pulse */
    {
        asm
        {	
            PSHA
            LDA	TCH1L				//Check current timer
            SUB	TCH0LBuff			//Subtract timer value saved in Idle state 
            STA	BreakL				//store difference in BreakL
            BHI	lbl3
            LDA	TCH1H
            DECA
            BRA lbl33
         lbl3:
            LDA	TCH1H			/* Calculate pulse length between falling and rising edge */
         lbl33:
            SUB	TCH0HBuff       //Subtract timer value saved in Idle state
            STA	BreakH   		//store difference in BreakH
            LDA	TCH1L
            PULA	
         }
        /* Check if longer than 11 bit times (BreakLimitH = val found in Unsyncronized) */	        				
        if (BreakH > BreakLimitH) 	
        {
            LinState = Syncbreak;	//It has found the syncbreak
        }	 
        else if ((BreakH == BreakLimitH) && (BreakL >= BreakLimitL)) 
        {
            LinState = Syncbreak; /* If yes - It has found the syncbreak */ 
        }
        else 
        {
            LinState = Idle; /* If No - did not find syncbreak - look again*/
        }
        TSC1_ELS1A = 0;		
        TSC1_ELS1B = 1;		/* Set for falling edge int. trig */
    }
    /*****************************/
    /* Case Syncbreak = Start at syncfield first falling edge, 
       count 4 edges and calculate and save Bit time,Bit time x 1.5 and x 8 */ 
    else if (LinState == Syncbreak)
    {	
    	if (SyncFieldBits == 0)
    	{ 
    		TCH0HBuff = TCH1H; 	//save away timer values
   			TCH0LBuff = TCH1L;
   		}
  		else if (SyncFieldBits == 4)  //now calculate how long time has passed
  		{  
  			asm{	
                PSHA
                LDA	TCH1L
                SUB	TCH0LBuff	//subtract saved timer value from new timer value
                STA	BreakL		//difference (TCH1L-TCH0LBuff) is stored in BreakL
                BHI	lblsb5		//Branch if Higher
                LDA	TCH1H
                DECA
                BRA lblsb55
            lblsb5:
                LDA	TCH1H
            lblsb55:
                SUB	TCH0HBuff			// Calculate time between 4 falling edges
                STA	BreakH
                MOV BreakH,BitClockReload8H
                MOV BreakL,BitClockReload8L		// save 8 x bit time value 
                LSR	BreakH					
                ROR BreakL
                LSR	BreakH				
                ROR BreakL
                LSR	BreakH				
                ROR BreakL				// BreakL + BreakH >> 3 ie. / 8
                LDA	TCH1L				// Read needed not to stall TCH1 IC
                MOV BreakH,BitTimeH
                MOV BreakL,BitTimeL		// save bit time value
                LSR	BreakH				
                ROR BreakL				// divide by 2 to get 1/2 bit time
                LDA BitTimeL
                ADD	BreakL
                STA	HBitTimeL
                LDA	BitTimeH
                ADC	BreakH
                STA HBitTimeH			// Calculate 1,5 x Bit time value and save in HBitTimeL/H
                PULA
        }
            LinState = Syncronised;
        }
        asm INC SyncFieldBits;			//Increase SyncFieldBits by 1, when SyncFieldBits =2 or =3.
     }
  	/**************************/		
		
    else if (LinState == Syncronised)
  	{
        AddBitTimeH();		/* Add 1,5 bit time */
        TSC1 = 0x50;		/* Output compare no pin action */
        LinState = ReceiveId;
        BitCount = 0;
        Id = 0;	
    }
 	/**************************/		
    else if (LinState == ReceivingWFS)		/* WFS = WaitForStartbit */
    {
        AddBitTimeH();	/* Add 1,5 bit time */ 
        TSC1 = 0x50; 	/* Output compare no pin action */
        LinState = Receiving;
    }
  	/*****************************/		
    else if (LinState == Unsyncronized) 		/* Unsyncronized state = Untrimmed RC Osc. */
    {
        BitCount++;								/* BitCount var. used to keep falling edge IC count */
        if (BitCount >= SyncBitCount)		    //Now it knows how long 2bit times are
  		{
            BreakLimitH = BreakH;		
            BreakLimitL = BreakL;
            asm{
                PSHA
                PSHX
                LDX  BreakH
                LDA	 BreakL
                ASLA				
                ROLX				//multiply by 2
                ASLA
                ROLX				// multiply by 2 - so X:A has now 2bit times x 4
                ADD	 BreakL
                STA	 BreakLimitL	// BreakLimitL has now the LSB of 10 bit times
                TXA	 
                ADC	 BreakH
                STA	 BreakLimitH	// BreakLimitH has now the MSB of 10 bit times
                LSR	 BreakH			
                ROR	 BreakL			// divide by 2 to get 1 bit time
                LDA	 BreakLimitL
                ADD  BreakL			
                STA	 BreakLimitL	// BreakLimitL = 11 bit times LSB 
                LDA	 BreakLimitH
                ADC  BreakH			
                STA	 BreakLimitH	// BreakLimitH = 11 bit times MSB
                PULX
                PULA
            }   							 
            LinState = Idle;		//Ready to look for SyncBreak
        }
        if (SyncFieldBits == 0)   	//Loop to save away current timer values
        {
            TCH0HBuff = TCH1H; 		// Start by saving away timer values
            TCH0LBuff = TCH1L;
            SyncFieldBits++;
        }
        //Calculate how long time has passed to find out the time between 2 falling edges
  		else if (SyncFieldBits == 1)	
  		{
            asm{	
                PSHA
                PSHH
                PSHX
                LDA	  TCH1L			//read timer
                SUB	  TCH0LBuff
                TAX
                BHI	  lblus1
                LDA	  TCH1H
                DECA
                BRA   lblus2
            lblus1:
                LDA	  TCH1H
            lblus2:
                SUB	  TCH0HBuff			// Calculate time between 2 falling edges
                PSHA
                PULH
                CPHX  BreakH			// Compare to previously captured value
                BCC   endus				//Branch if value in memory is bigger
                STX	  BreakL
                PSHH
                PULA
                STA	  BreakH			// store if lower
            endus:
                LDA	  TCH1L				//"release" TCH1L+H 
                PULX
                PULH
                PULA
            }
            SyncFieldBits = 0;	
        }
   }

Dummy = TSC1;    	// Read byte...
TSC1_CH1F = 0;     // ...and reset CH1F in case of a pending interrupt 
  		
}

/************************************************/
/* This function adds 8 bit times*/
void AddBitTime8(void)
{
asm {		
    PSHA
    LDA	TCH1L
    ADD	BitClockReload8L
    STA	TCH1L
    LDA	TCH1H
    ADC	BitClockReload8H
    STA TCH1H
    LDA	TCH1L
    STA TCH1L
    PULA
  }
} 			

/*****************************************/
/* This function adds 1 bit time*/
void AddBitTime(void)
{
asm {		
    PSHA
    LDA	TCH1L
    ADD	BitTimeL   
    STA	TCH1L
    LDA	TCH1H
    ADC	BitTimeH
    STA TCH1H
    LDA	TCH1L
    STA TCH1L
    PULA
  }
} 			


/************************************************/
/* This function adds 1.5 bit times*/
void AddBitTimeH(void)
{
asm {		
    PSHA
    LDA	TCH1L
    ADD	HBitTimeL
    STA	TCH1L
    LDA	TCH1H
    ADC	HBitTimeH
    STA TCH1H
    LDA	TCH1L
    STA TCH1L
    PULA
    } 			
}

⌨️ 快捷键说明

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