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

📄 lintongxun.cpp

📁 LIN通讯的基本步骤
💻 CPP
字号:





/*define*/
#define MAX_DATA      1               // Max bytes lin frame data

#define SCI_BAUDRATE  19200           // SCI baud rate    
#define SCI_CLOCK     200 0000         // Bus clock in Hz     

#define EVER (;;)   

#define FALSE -1

#define TRUE 0

#define DEBOUNCE 1                                   /* 20.5ms x (1+1) = 41ms */
#define LOW_POWER 195                                /* 20.5ms x (195+1) = 4s */


l_bool sleep_mode = 0;

static l_u16  previous_start_time = 0;      /* Wraps around but usage is safe */

enum lin_state { IDLE, _BREAK, SYNCH, PROTECTED_IDENTIFIER, DATA_0, DATA_1,    
                 DATA_2, DATA_3, DATA_4, DATA_5, DATA_6, DATA_7, CHECKSUM }; 

struct message {   
  unsigned char identifier;   
  unsigned char data_field[MAX_DATA];   
};   
   
struct frame {   
  unsigned char protected_id;   
  unsigned char data[MAX_DATA];   
  unsigned char check;   
  enum lin_state state;   
  unsigned char error;   
};   

struct frame rx;  

// Functions    
/////////////////////////////////////////////////////////////////////////////////////////    
void LINInit(void);   
Bool LINGetMsg(Bool get_data, struct  message *msg);   
Bool LINSendMsg(Bool master, Bool send_data, struct message msg);   
enum lin_state LINCheckState(void);   




/*LIN初始化*/
void LINInit(void)   
{   
   
  int sbr,i;   
     
  sbr=(SCI_CLOCK/SCI_BAUDRATE/16);                           //设置波特率
  SCI1BDH =(unsigned char)(sbr>>8);   
  SCI1BDL =(unsigned char)sbr;   

  SCI1C2 =0x2C;                                              //SCI中断使能
  // Break character is 13 or 14 bit long    
  SCI1S2=0x04;                                               // 设置中断字节长度 (13或14位)   
  // Initializes LIN receive frames    
  rx.protected_id=0;                                         //初始化LIN的接收帧
  rx.state=IDLE;   
  rx.error=0;   
  rx.check=0;  


 
  for (i=0;i<MAX_DATA;I++) 
  	msg- FALSE; 
  return PROTECTED_IDENTIFIER) 
  if (get_data)   
  {   
    if(rx.state == CHECKSUM)    
    {   
      for(i = 0; i < MAX_DATA; i++)   
        msg->data_field[i] = rx.data[i];   
      rx.state = IDLE;   
    }   
    else   
      for(i = 0; i < MAX_DATA; i++)   
        msg->data_field[i] = 0;   
  }         
  return(TRUE);   
        
}   





/*SCI接收中断子程序*/
interrupt void SCI1_RX(void)                                 // SCI 的接收中断子程序
{    
    
  if(!LINGetChar())           // 如果LIN  未接收到字符 
  {   
    rx.error = 1;   
    rx.state = IDLE;   
  }   
     
} 




/*LIN发送字符子程序*/
Bool LINSendChar(Bool brk, unsigned char ch)                               // LIN的发送字符子程序  
{   
   
  // Waits until transmit data registry is empty (TDRE=1)    
  while(!(SCI1S1&0x80))   
    ; 

  
  // If break field, transmits one break character (13-14 bits of dominant value)     
  if(brk)    
  {   
    SCI1C2 |= 0x01;   
    SCI1C2 &= ~0x01;   
  }   
  else   
    SCI1D = ch;   
  return(TRUE);   






/*LIN  发送校验子程序*/
Bool LINCheckSend(enum lin_state status, unsigned char val)                  //LIN发送校验发送子程序
{   
   
  // While until sci data has been received     
  while(rx.state < status)   
    if(rx.error)   
      return(FALSE);   
       
  switch(status)    
  {   
    case _BREAK:   
    case SYNCH:   
      break;   
         
    case PROTECTED_IDENTIFIER:   
      if(rx.protected_id != val)   
        return(FALSE);   
      break;   
           
    case DATA_0:   
    case DATA_1:   
    case DATA_2:   
    case DATA_3:   
    case DATA_4:   
    case DATA_5:   
    case DATA_6:   
    case DATA_7:   
      if(rx.data[status-DATA_0] != val)   
        return(FALSE);   
      break;   
           
    case CHECKSUM:   
      if(rx.check != val)   
        return(FALSE);   
      break;   
           
  }   
  return(TRUE);   
     
}   






/*LIN发送帧子程序*/
Bool LINSendMsg(Bool master, Bool send_data, struct message msg)             // LIN 发送帧子程序 
{   
   
  unsigned char check_sum, parity_id, i;   
     
  rx.error = 0;   
     
  if(master)    
  {   
    // Sends break feald    
    if(!LINSendChar(TRUE, 0x00))   
      return(FALSE);   
    // Check break sending    
    if(!LINCheckSend(_BREAK, 0x00))   
      return(FALSE); 
	
    // Sends synch feald    
    if(!LINSendChar(FALSE, 0x55))   
      return(FALSE);   
    // Checks synch sending    
    if(!LINCheckSend(SYNCH, 0x55))   
      return(FALSE); 
	
    parity_id=LINCalcParity(msg.identifier);   
    // Sends protected identifier field    
    if(!LINSendChar(FALSE, parity_id))   
      return(FALSE);   
    // Checks protected identifier sending    
    if(!LINCheckSend(PROTECTED_IDENTIFIER, parity_id))   
      return(FALSE);     
  }     

    if(send_data)   
  {   
  
    for(i=0; i < MAX_DATA; i++)    
    {   
      // Sends data field     
      if(!LINSendChar(FALSE, msg.data_field[i]))   
        return(FALSE);   
      // Checks data sending    
      if(!LINCheckSend(DATA_0+i, msg.data_field[i]))   
        return(FALSE);    
    }  
	
    check_sum = LINCalcChecksum(msg.data_field);   
    // Sends checksum field    
    if(!LINSendChar(FALSE, check_sum))   
      return(FALSE);   
    // Checks checksum sending    
    if(!LINCheckSend(CHECKSUM, check_sum))   
      return(FALSE);   
    rx.state = IDLE;   
  }   

   
  return(TRUE);   
   
}   
   




  



/*LIN 校验状态*/
enum lin_state LINCheckState(void)                             // LIN 的校验状态(结果)  
   
  return rx.state;     
     
}   
   


/*校验是否为睡眠模式*/
void CheckLowPower(void)
{
    l_u16 status;

    status = l_ifc_read_status_i1();                
                                                                /* Sleep command received? */
    if ((status & 0x0008)== L_SLEEP_REQUEST)        /* 判断是否为睡眠模式*/
    {
        LIN_EN_PIN = 0;      /* yes, disable MC33399 LIN interface turn off */
                             /* LT1121 to reache low power consumption */
    }

    if ((status & 0x00FF) == 0x00)                     /* No activity on LIN? */
    {
        low_power_delay--;                      /* yes, decrement the counter */
    }
    else
    {
        low_power_delay = LOW_POWER;
    }
    if (low_power_delay == 0)            /* no activity on LIN for 4 seconds? */
    {
        LIN_EN_PIN = 0;        /* yes, disable MC33399 LIN interface turn off */
                               /* LT1121 to reache low power consumption */
    }
}




/*校验返回值*/
void Check (l_bool return_value)
{
    if (return_value)
    {
        NodeFailure();
    }
}


/*返回值不正确进入死循环*/
void NodeFailure (void)
{
    for EVER                                      /* To avoid warning message */
    {
        /* forever */
    }
}




/*进入睡眠模式
*/void GotoSleep (void)
{
    while (l_sch_tick_i1() != 1)                                 /* one round */
    {
        BusyWaitUntilNextPeriod();
    }
    l_ifc_goto_sleep_i1();                         /* send the sleep commnand */
    sleep_mode = 1;                                /* set the sleep mode flag */
}





void BusyWaitUntilNextPeriod (void)
{
    l_u16         t_now;                    /* The time counter value for now */
    l_u16         elapsed;    /* Time elapsed since previous ideal start time */
    do
    {
        #ifdef PET_WATCHDOG
        PET_WATCHDOG();
        #endif
        
        t_now   = l_get_us_counter();
        elapsed = (l_u16) (t_now - previous_start_time);
    }
    while (elapsed < HW_DELAY);
    
    previous_start_time += HW_DELAY;
   /* This construct avoids time drift, previous_start_time = t_now, wouldn't */
}







/*主函数  main */
void main (void)
{
    l_u8   button_request_id = 0;
    l_bool result;
    
    low_power_delay = LOW_POWER;          /* initialize the low power counter */     
    BUTTON_DDR = 0;                            /* set the button pin as input */
    
    LED_DDR |= LED_MASK;                            /* set LED port as output */
    LED_PORT &= ~LED_MASK;                                /* turn the LED off */
  
    LIN_EN_DDR = 1;                           /* set LIN enable pin as output */
    LIN_EN_PIN = 1;                             /* enable 33399 LIN interface */
    
    init_target();
    result = l_sys_init();
    Check(result);
	
    l_ifc_init_i1();
    ENABLE_INTS();  	                                /* turn on interrupts */
    result = l_ifc_connect_i1();
    Check(result);
    
    TSC = 0x00;                                         /* timer prescaler /1 */
    TSC &= ~(0x20);                                            /* start timer */
    
    l_u8_wr_SlaveRespB0_demo_net(0x81);             /* set the slave response */    

    for EVER
    {
        PET_WATCHDOG();
        
        if (l_flg_tst_res_done())        /* conflict resolving done flag set? */
        {
                                             /* yes, clear the slave response */
            l_u8_wr_SlaveRespB0_demo_net(0x80);  
            l_flg_clr_res_done();                           /* clear the flag */
        }
        
        if (TSC & 0x80)                              /* is overflow flag set? */
        {
            TSC &= ~(0x80);                                  /* yes, clear it */
            count++;                                 /* used for LED flashing */
            ReadButton();                       /* read button on button port */
            LedDisplay();                          /* update LEDs on LED port */
            LinResponse();                            /* provide LIN response */
            CheckLowPower();                      /* check the low power mode */            
        }
    }
}



void main (void)
{
/* Initialize the LIN interface */
	if (l_sys_init ())
		{
		/* The init of the LIN software failed */
		}
	else
		{
			l_ifc_init_MyLinIfc (); /* Initialize the interface */
			if (l_ifc_connect_MyLinIfc ())
				{
					/* Connection of the LIN interface failed */
				}
			else
				{
					/* Connected, now ready to send/receive set the normal
					/* schedule to run from beginning for this specific interface */
					l_sch_set_MyLinIfc (MySchedule1, 0);
				}
			}
		
		start_main_application (); /* Ready with init, start actual applic */
		}
	
		/* main */
		/* 10 ms based on the minimum LIN tick time, in LIN description file... */
		void main_application_10ms (void)
		{
			/* Do some application specific stuff... */
			/* Just a small example of signal reading and writing */
			if (l_flg_tst_RxInternalLightsSwitch ())
				{
					l_u8_wr_InternalLightsRequest (l_u8_rd_InternalLightsSwitch());
					l_flg_clr_RxInternalLightsSwitch ();
				}	
			/* In-/output of signals, do not care about the return value, as we
			/* will never switch schedule anyway... */
			(void) l_sch_tick_MyLinIfc();
	} /* main_application_10ms */

⌨️ 快捷键说明

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