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

📄 lin_low_level.c

📁 针对日本瑞莎单片机r8c/23 开发的LIN网络通讯程序包括主节点和从节点
💻 C
📖 第 1 页 / 共 5 页
字号:
             * Transmit enabled.  */
         #endif
         break ;

      case IDENTIFY_RECEIVE_STATE:
         LIN_DIAG_mode = 0;   /* Insure the diagnostic mode is off.  */
         /* Reload the break timer count.  */
         BRK_TMR_PRECNT_REG = LIN_break_prescale;
         BRK_TMR_CNT_REG = LIN_break_count;
         LIN_UART_OP_MODE = LIN_UART_OP_RCV;  /* Configure the serial port.  */
         LIN_UART_RX_INT_CTL = LIN_UART_RX_INT_PRIO;
         LIN_UART_TX_INT_CTL = 0x00;
            /* Receive interrupt enabled
             * Receive enabled
             * Transmit end interrupt disabled
             * Transmit enabled.  */
         break ;

      case DATA_RECEIVE_STATE:
         LIN_RX_count = 0;    /* Initialize the receive byte counter.  */
         /* Disable the bus collision interrupt and clear the flag.  */
         BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;
         #if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
            BRK_TMR_INT_CFG = 0xC0; /* Break detect not enabled for Master node.  */
         #else
            /* Configure the LIN function mode and interrupt sources.  The Break interrupt
             * is always enabled, the Bus Collision interrupt is never enabled and the Sync
             * interrupt is enabled in the SYNC_AUTO_MODE.  */
            #ifdef SYNC_AUTO_MODE
               BRK_TMR_INT_CFG = 0xA3;
            #else
               BRK_TMR_INT_CFG = 0x82;
            #endif
         #endif
         LIN_UART_OP_MODE = LIN_UART_OP_RCV;  /* Configure the serial port.  */
         LIN_UART_RX_INT_CTL = LIN_UART_RX_INT_PRIO;
         LIN_UART_TX_INT_CTL = 0x00;
            /* Receive interrupt enabled
             * Receive enabled
             * Transmit end interrupt disabled
             * Transmit enabled.  */
         break ;

      case DATA_SEND_STATE:
         LIN_TX_count = 0;    /* Initialize the transmit byte counter.  */
         /* Clear all break flags and enable the bus collision interrupt.  */
         BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;
         #if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
            BRK_TMR_INT_CFG = 0xC4; /* Break detect not enabled for Master node.  */
         #else
            /* Configure the LIN function mode and interrupt sources.  The Break interrupt
             * is always enabled, the Bus Collision interrupt is always enabled and the Sync
             * interrupt is enabled in the SYNC_AUTO_MODE.  */
            #ifdef SYNC_AUTO_MODE
               BRK_TMR_INT_CFG = 0xA7;
            #else
               BRK_TMR_INT_CFG = 0x86;
            #endif
         #endif
         /* Initialize the transmit check error flag.  */
         LIN_TX_check_error = 0;
         LIN_UART_OP_MODE = LIN_UART_OP_XMT;  /* Configure the serial port.  */
         LIN_UART_RX_INT_CTL = 0x00;
         LIN_UART_TX_INT_CTL = LIN_UART_TX_INT_PRIO;
            /* Receive interrupt disabled
             * Receive enabled
             * Transmit end interrupt enabled
             * Transmit enabled.  */
         break ;

      #ifdef USE_POWER_CONTROL
         case WAKEUP_SEND_STATE:
            LIN_UART_OP_MODE = LIN_UART_OP_IDLE;  /* Configure the serial port.  */
            LIN_UART_RX_INT_CTL = 0x00;
            LIN_UART_TX_INT_CTL = 0x00;
               /* Receive interrupt disabled
                * Receive disabled
                * Transmit end interrupt disabled
                * Transmit enabled.  */
            break;
      #endif   /* USE_POWER_CONTROL.  */
   }
   return;
}

/**********************************************************************
 *    Function Name: lin_init_checksum()
 *      Description: Initializes checksum value to 0 for a "classic"
 *                   checksum or to the LIN message ident byte for an
 *                   enhanced checksum.
 *       Parameters: check_sum_type - 0 = classic; 1 = enhanced.
 *          Returns: Nothing.
 *  Ext. References: LIN_ident_PB, LIN_sum_code
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *********************************************************************/
void lin_init_check_sum(unsigned char check_sum_type)
{
   /* If "check_sum_type" is LIN_ENHANCED (1), initialize "LIN_sum_code"
    * to the current value of "LIN_ident_PB".  */
   if (check_sum_type == LIN_ENHANCED)
   {
      LIN_sum_code = LIN_ident_PB;
   }
   else
   /* Otherwise (0 assumed), clear "LIN_sum_code".  */
   {
      LIN_sum_code = 0;
   }
   return;
}

/**********************************************************************
 *    Function Name: lin_make_check_sum()
 *      Description: Adds one data byte to the 1's compliment checksum.
 *       Parameters: data - data byte.
 *          Returns: Nothing.
 *  Ext. References: LIN_sum_code
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_make_check_sum(unsigned char data)
{
   int i;
   union {
    unsigned int  d_int ;
    unsigned char d_byte[2];
   } buf;

   buf.d_int = 0;                   /* Initialize the buffer.  */
   buf.d_byte[0] = LIN_sum_code;    /* Load the current checksum.  */
   buf.d_int += (unsigned int)data; /* Add in the data byte.  */
   /* If an 8-bit overflow occurs, subtract 255.  This is the equivalent of
    * adding 1 to the 8-bit sum, which is an 8-bit 1's compliment add.  */
   if (buf.d_int >= 256)
   {
      buf.d_int -= 255;
   }
   LIN_sum_code = buf.d_byte[0];    /* Save the new checksum.  */
   return;
}

/**********************************************************************
 *    Function Name: lin_make_protected_identifier()
 *      Description: Create a LIN Protected ID by setting the two parity
 *                   bits as appropriate for the frame ID.
 *       Parameters: id_data - the LIN message frame ID.
 *          Returns: The Protected ID.
 *  Ext. References: None.
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *********************************************************************/
unsigned char lin_make_protected_identifier(unsigned char id_data)
{
   union {
      unsigned char  BYTE;
      struct {
         unsigned char  D0:1;
         unsigned char  D1:1;
         unsigned char  D2:1;
         unsigned char  D3:1;
         unsigned char  D4:1;
         unsigned char  D5:1;
         unsigned char  P0:1;
         unsigned char  P1:1;
      } BIT;
   } BUF;

   /* Load the desired message frame ID into the LSBits of the buffer.  */
   BUF.BYTE = id_data & (unsigned char)0x3F;
   /* Set the two parity bits.  */
   BUF.BIT.P1 = ~(BUF.BIT.D1 ^ BUF.BIT.D3 ^ BUF.BIT.D4 ^ BUF.BIT.D5);
   BUF.BIT.P0 = BUF.BIT.D0 ^ BUF.BIT.D1 ^ BUF.BIT.D2 ^ BUF.BIT.D4;
   return (BUF.BYTE);
}

/**********************************************************************
 *    Function Name: lin_reset_signal_update_flg()
 *      Description: Clear all signal status flags associated with a frame
 *                   ID to indicate that the signals have not been updated.
 *       Parameters: frame_name - index number of the frame ID.
 *          Returns: Nothing.
 *  Ext. References: LIN_signal_table (indirectly).
 *      Preemptible: Yes.
 *        Reentrant: Yes.
 *********************************************************************/
void lin_reset_signal_update_flg(unsigned char frame_name)
{
   int i;
   unsigned char signal_name;

   /* Loop through all signals associated with a frame ID number and clear
    * the signal state flag for all signals.  */
   for (i = 0; i < LIN_id_table[frame_name].num_sigs; i++)
   {
      /* Determine the index number of the signal.  */
      signal_name = *(LIN_id_table[frame_name].data_address + (i * 2));
      /* Clear the status flag for this signal to indicate that it has not
       * been updated.  */
      *LIN_signal_table[signal_name].signal_address = 0x00;
   }
   return;
}

/* The following function is included only for Master nodes.  */
#if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
/**********************************************************************
 *    Function Name: lin_send_break()
 *      Description: Sends the LIN Break pulse.
 *       Parameters: break_period - the length of the break in bits.
 *          Returns: Nothing.
 *  Ext. References: None.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_send_break(void)
{
   /* Initialize the break timer for the Master break mode.  */
   BRK_TMR_FLAGS |= BRK_CLR_ALL_FLGS;
   BRK_TMR_MODE_REG = BRK_TMR_MST_MODE;
   BRK_TMR_PRECNT_REG = LIN_break_prescale;
   BRK_TMR_CNT_REG = LIN_break_count;
   BRK_INT_BREAK = 1;                     /* Configure the break detect interrupt.  */
   BRK_TMR_INT_CTL = BRK_TMR_INT_PRIO;    /* Enable the break timer interrupt.  */
   BRK_TMR_RUN = 1;                       /* Start the LIN break timer.  */
   return;
}
#endif   /* Master node.  */

/**********************************************************************
 *    Function Name: lin_send_response()
 *      Description: Outputs the data byte from the "LIN_data[]" that is
 *                   indicated by the current value of "LIN_TX_count".
 *       Parameters: None.
 *          Returns: Nothing.
 *  Ext. References: LIN_TX_count - index to the next byte to be sent.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_send_response(void)
{
   /* Make sure the transmit data register is empty.  */
   while (LIN_UART_TBUFE_FLG == 0);
   LIN_UART_TDAT = LIN_data[LIN_TX_count];  /* Output the data byte.  */
   LIN_TX_count++;   /* Pre-increment to next byte to be sent.  */
   return;
}

/**********************************************************************
 *    Function Name: lin_first_send_data()
 *      Description: This function prepares the "LIN_data[]" structure
 *                   for a transmit operation and causes the first byte
 *                   to be sent.
 *       Parameters: None.
 *          Returns: Nothing.
 *  Ext. References: LIN_data[], LIN_ident, LIN_ident_PB, LIN_sum_code.
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_first_send_data()
{
   signed char i;
   unsigned int temp_sum;

   #if (LIN_MASTER_NODE == LIN_MY_NODE_NAME)
      /* Master node processing.  "LIN_DIAG_mode" is only set to 1 for Master devices
       * when the command Go To Sleep is being sent.  Otherwise (even for "normal"
       * diagnostic frames), "LIN_DIAG_mode" is set to 0 and the frames are sent with
       * "LIN_frame_type" set to UNCONDITIONAL or EVENT_TRIG.  */
      if (LIN_DIAG_mode == 1)
      {
         /* This is the Go To Sleep command.  The command is already fully loaded into
          * "LIN_data[]", so there is nothing to do but send it.  */
         LIN_tx_send_length = 11;
      }
      else
      {
         /* By the time this code executes, "LIN_frame_type" is set to
          * Unconditional even if the original frame type was Sporadic.
          * If the original frame type was Event Triggered, that remains, but
          * the Master node never publishes Event Triggered data.  */
         if (LIN_frame_type == UNCONDITION_FRAME)
         {
            /* This is an Unconditional frame, which may have been a Sporadic
             * frame originally.  The Master node will always publish the data
             * for a Sporadic frame but might not publish the data for an
             * Unconditional frame.  Check to see if the Master node is supposed
             * to publish the data for the current frame.  */
            if (LIN_id_table[LIN_frame_name].node_name == LIN_MY_NODE_NAME)

⌨️ 快捷键说明

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