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

📄 lin_low_level.c

📁 针对日本瑞莎单片机r8c/23 开发的LIN网络通讯程序包括主节点和从节点
💻 C
📖 第 1 页 / 共 5 页
字号:
            for (j = 0; j < signal_byte; j++)
            {
               *dptr++ = *p++;
            }
         }
      }
   #endif   /* ENABLE_ODD_SIGNAL_WIDTHS.  */
   return;
}

/**********************************************************************
 *    Function Name: lin_make_signal_data()
 *      Description: Reads out the data in a received message frame and
 *                   updates the signal values.
 *       Parameters: frame_name - index value of the frame just received.
 *          Returns: Nothing.
 *  Ext. References: LIN_frame_type, LIN_data[], LIN_id_table[], LIN_signal_table[].
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_make_signal_data(unsigned char frame_name)
{
   int i, j;
   unsigned char *p, *fstp, *dptr;
   unsigned char max_sig;
   union {
      unsigned int     d_int;
      unsigned char    d_byte[2];
   } buf;
   union {
      unsigned int     d_int;
      unsigned char    d_byte[2];
   } save;
   unsigned char    set_byte, set_bit, signal_name, offset, signal_byte, signal_bit;
   unsigned char    start_byte, signal_change;
   #ifdef ENABLE_ODD_SIGNAL_WIDTHS
      unsigned int     mask_int;
   #endif

   start_byte = 0;

   #ifndef ENABLE_ODD_SIGNAL_WIDTHS /* Limits scalar signal data size to 8 or 16 bits.  */
      /* Save the number of signals in the frame.  */
      max_sig = LIN_id_table[frame_name].num_sigs;
      /* Set the pointer to point to the first signal in the frame table.  */
      fstp = LIN_id_table[frame_name].data_address;
      /* Loop through all of the signals associated with a LIN message frame ID.  */
      for (i = 0; i < max_sig; i++)
      {
         /* Get the index number of a signal.  */
         signal_name = *fstp++;
         /* Determine the bit offset of the signal data in the LIN data buffer.  */
         offset = *fstp++;
         /* Get the number of bytes in the signal value.  */
         signal_byte = LIN_signal_table[signal_name].signal_byte;
         set_byte = offset / (unsigned char)8;
         /* Set a pointer to the first data byte of the signal value.  */
         p = LIN_signal_table[signal_name].signal_address + 1;
         /* Set a pointer to the (initial) source byte in "LIN_data[]".  */
         dptr = (unsigned char *)&LIN_data[set_byte + start_byte];
         signal_change = 0x00;   /* Initialize "signal_change" to "no_change".  */
         /* Read the signal value from the LIN data buffer at the appropriate
          * location.  */
         for (j = 0; j < signal_byte; j++)
         {
            /* If the new and old values are not equal, set "signal_change" to mark the
             * signal as updated.  */
            if (*p != *dptr)
            {
               signal_change = 0x80;
            }
            *p++ = *dptr++;
         }
         /* Mark the signal as updated, if needed.  If all data bytes were equal to the
          * current state of the signal data, "signal_change" will still be 0x00 - no change.  */
         if (signal_change != 0x00)
         {
            *LIN_signal_table[signal_name].signal_address = signal_change;
         }
      }
   #else /* Odd length signals allowed (signal size not evenly divisable by 8).  */
      /* Save the number of signals in the frame.  */
      max_sig = LIN_id_table[frame_name].num_sigs;
      /* Set the pointer to point to the first signal in the frame table.  */
      fstp = LIN_id_table[frame_name].data_address;
      /* Loop through all of the signals associated with a LIN message frame ID.  */
      for (i = 0; i < max_sig; i++)
      {
         /* Get the index number of a signal.  */
         signal_name = *fstp++;
         /* Determine the bit offset of the signal data in the LIN data buffer.  */
         offset = *fstp++;
         /* Get the number of bytes in the signal value - 1 or 2.  */
         signal_byte = LIN_signal_table[signal_name].signal_byte;
         /* Get the number of bits in the signal value - 0 through 15.  */
         signal_bit = LIN_signal_table[signal_name].signal_bit;
         /* "offset" is the number of bits (0 through 63) that lie "below" the
          * LSB of this signal in the "LIN_data[]" array.  "offset" must be
          * divided up to produce "set_byte" number of bytes completely offset (0
          * through 7) and "set_bit" number of bits offset in the last byte (also
          * 0 through 7).  */
         set_byte = offset >> 3;
         set_bit = offset & (unsigned char)0x07;
         /* Set a pointer to the first data byte of the signal value.  */
         p = LIN_signal_table[signal_name].signal_address + 1;
         /* Set a pointer to the (initial) destination byte in "LIN_data[]".  */
         dptr = (unsigned char *)&LIN_data[set_byte + start_byte];
         signal_change = 0x00;   /* Initialize "signal_change" to "no_change".  */
         /* If "signal_byte" is 1 or 2, the signal may be a scalar signal with a
          * length of between 1 and 16 bits.  A scalar signal may be packed into
          * the "LIN_data[]" array starting at any given bit (0 to 63) within the
          * array, but a scalar value may cross only a single byte boundary within
          * the array.  If "signal_byte" is 1 or 2, the signal may also be a byte
          * array.  However, a byte array may be stored only in byte locations
          * within the "LIN_data[]" array, meaning that the starting bit must
          * always be bit 0 of some byte.  If "signal_byte" is 3 or greater (max
          * of 8), the signal is a byte array.  */
         if (signal_byte < 3)
         {
            /* Set a mask for the bit size of the signal.  */
            mask_int = LIN_bit_masks[signal_bit];
            /* Read the signal data into "buf.d_int" to allow it to be bit shifted as
             * a complete value.  */
            buf.d_byte[0] = *dptr++;
            buf.d_byte[1] = *dptr;
            /* Shift the signal value toward the LSbit by "set_bit" number of positions.
             * A LIN scalar value may be 1 to 16 bits in length, but the value may
             * cross only a single byte boundary.  This means the the 16-bit "buf.d_int"
             * will always be able to hold any (valid) combination of signal length and
             * bit shifts without losing any bits.  */
            buf.d_int >>= set_bit;
            /* Mask off the unused MSBits.  */
            buf.d_int &= mask_int;
            /* Load the LSByte of the read value into the signal data buffer.  If the new
             * and old values are not equal, set "signal_change" to mark the signal as updated.  */
            if (*p != buf.d_byte[0])
            {
               signal_change = 0x80;
            }
            *p++ = buf.d_byte[0];
            /* If necessary, load the MSByte of the read value into the signal data buffer.  */
            if (signal_bit > 8)
            {
               /* If the new and old values are not equal, set "signal_change" to mark the
                * signal as updated.  */
               if (*p != buf.d_byte[1])
               {
                  signal_change = 0x80;
               }
               *p = buf.d_byte[1];
            }
         }
         else
         {
            /* This is a byte array.  Read the signal value from the LIN data buffer at
             * the appropriate locations.  */
            for (j = 0; j < signal_byte; j++)
            {
               /* If the new and old values are not equal, set "signal_change" to mark the
                * signal as updated.  */
               if (*p != *dptr)
               {
                  signal_change = 0x80;
               }
               *p++ = *dptr++;
            }
         }
         /* Mark the signal as updated, if needed.  If all data bytes were equal to the
          * current state of the signal data, "signal_change" will still be 0x00 - no change.  */
         if (signal_change != 0x00)
         {
            *LIN_signal_table[signal_name].signal_address = signal_change;
         }
      }
   #endif   /* ENABLE_ODD_SIGNAL_WIDTHS.  */
   return;
}

/**********************************************************************
 *    Function Name: lin_signal_write()
 *      Description: Copies a new signal value into "LIN_signal_table"
 *                   if the signal value has changed.  Marks the signal
 *                   as changed or unchanged appropriately.
 *       Parameters: signal_name - index number assigned to the signal.
 *                   bit_size - bit length of the signal.
 *                   write_data - new signal value.
 *          Returns: Nothing.
 *  Ext. References: LIN_signal_table
 *      Preemptible: Yes.
 *        Reentrant: No.
 *********************************************************************/
void lin_signal_write(unsigned char signal_name, unsigned char bit_size, unsigned int write_data)
{
   unsigned char flag_state;
   unsigned char *p;
   union {
      unsigned int     d_int;
      unsigned char    d_byte[2];
   } write_buf;
   union {
      unsigned int     d_int;
      unsigned char    d_byte[2];
   } buf;
   #ifdef ENABLE_ODD_SIGNAL_WIDTHS
      union {
         unsigned int     d_int;
         unsigned char    d_byte[2];
      } mask;
   #endif

   #ifndef ENABLE_ODD_SIGNAL_WIDTHS    /* Limits scalar signal data size to 8 or 16 bits.  */
      /* Load the pointer "p" to point to the first data byte of the current signal value.  */
      p = LIN_signal_table[signal_name].signal_address + 1;
      /* Copy current signal value into "buf".  */
      if (bit_size <= 8)
      {
         buf.d_int = 0;
      }
      else
      {
         buf.d_byte[1] = *(p + 1);
      }
      buf.d_byte[0] = *p;
      /* Copy new value into "write_buf".  */
      write_buf.d_int = write_data;
      /* If the values are not equal, copy the new value into the signal data array
       * and mark the signal as changed.  */
      if (buf.d_int != write_buf.d_int)
      {
         /* Not equal.  */
         flag_state = l_sys_irq_disable();   /* Disable the global interrupt.  */
         /* Copy the new value into the signal data array and mark the signal as changed.  */
         if (bit_size > 8)
         {
            *(p + 1) = write_buf.d_byte[1];
         }
         *p-- = write_buf.d_byte[0];
         *p = 0x80;  /* Mark the signal as being changed.  */
         l_sys_irq_restore(flag_state);   /* Restore the global interrupt.  */
      }
   #else /* Odd length signals allowed (signal size not evenly divisable by 8).  */
      /* Set a mask for the bit size of the signal.  */
      mask.d_int = LIN_bit_masks[bit_size];
      /* Load the pointer "p" to point to the first data byte of the current signal value.  */
      p = LIN_signal_table[signal_name].signal_address + 1;
      /* Copy current signal value into "buf".  */
      if (bit_size <= 8)
      {
         buf.d_int = 0;
      }
      else
      {
         buf.d_byte[1] = *(p + 1) & mask.d_byte[1];
      }
      buf.d_byte[0] = *p & mask.d_byte[0];
      /* Copy new value into "write_buf".  */
      write_buf.d_int = write_data & mask.d_int;
      /* If the values are not equal, copy the new value into the signal data array
       * and mark the signal as changed.  */
      if (buf.d_int != write_buf.d_int)
      {
         /* Not equal.  */
         flag_state = l_sys_irq_disable();   /* Disable the global interrupt.  */
         /* Copy the new value into the signal data array and mark the signal as changed.  */
         if (bit_size > 8)
         {
            *(p + 1) = write_buf.d_byte[1];
         }
         *p-- = write_buf.d_byte[0];
         *p = 0x80;  /* Mark the signal as being changed.  */
         l_sys_irq_restore(flag_state);   /* Restore the global interrupt.  */
      }
   #endif   /* ENABLE_ODD_SIGNAL_WIDTHS.  */
   return;
}


/**********************************************************************
 *
 * Modification Record
 *
 **********************************************************************
 *
 *    Version 1.1 for R8C 16 Mar 2006   Bob Chamberlain
 *    01.08.2007 RTA-CSS version 1.17. id0x8 fix done in lin_low_level.c by Bob C.
 *    08.24.2007 RTA-CSS defines EVENT_TRIG_FRAME and SPORADIC_FRAME removed 
 *    from LIN Starter Demo version.
 *********************************************************************/

⌨️ 快捷键说明

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