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

📄 scc_s515.c

📁 基于8051共享时钟调度器的can总线通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
         // Message is correct
         Start_slave = 1;

         // Send ack
         CAN_messages[1].Data[0] = 0x00;     // Set data byte 0
         CAN_messages[1].Data[1] = SLAVE_ID; // Set data byte 1
         CAN_messages[1].MCR1 = 0xE7;  // Send it
         }
      else
         {
         // Not yet received correct message - wait
         Start_slave = 0;
         }
      } while (!Start_slave);

   // Start the scheduler
   IRCON = 0;
   EAL = 1;
   }

/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Update

  This is the scheduler ISR.  It is called at a rate 
  determined by the timer settings in SCC_A_SLAVE_Init().

  This Slave is triggered by USART interrupts.

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Update(void) interrupt INTERRUPT_CAN_c515c  
   {
   tByte Index;

   // Reset this when tick is received
   Network_error_pin = NO_NETWORK_ERROR;

   // Check tick data - send ack if necessary
   // NOTE: 'START' message will only be sent after a 'time out'
   if (SCC_A_SLAVE_Process_Tick_Message() == SLAVE_ID)
      {
      SCC_A_SLAVE_Send_Ack_Message_To_Master();

      // Feed the watchdog ONLY when a *relevant* message is received
      // (noise on the bus, etc, will not stop the watchdog...)
      //
      // START messages will NOT refresh the slave
      // - Must talk to every slave at regular intervals 
      SCC_A_SLAVE_Watchdog_Refresh();
      }

   // Check the last error codes on the CAN bus via the status register
   if ((CAN_sr & 0x07) != 0)
      {
      Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
      Network_error_pin = NETWORK_ERROR;
   
      // See Infineon c515c manual for error code details
      CAN_error_pin0 = ((CAN_sr & 0x01) == 0);
      CAN_error_pin1 = ((CAN_sr & 0x02) == 0);
      CAN_error_pin2 = ((CAN_sr & 0x04) == 0);
      }
   else
      {
      CAN_error_pin0 = 1;
      CAN_error_pin1 = 1;
      CAN_error_pin2 = 1;
      }

   // NOTE: calculations are in *TICKS* (not milliseconds)
   for (Index = 0; Index < SCH_MAX_TASKS; Index++)
      {
      // Check if there is a task at this location
      if (SCH_tasks_G[Index].pTask)
         {
         if (SCH_tasks_G[Index].Delay == 0)
            {
            // The task is due to run
            SCH_tasks_G[Index].RunMe = 1;  // Set the run flag
   
            if (SCH_tasks_G[Index].Period)
               {
               // Schedule periodic tasks to run again
               SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
               }
            }
         else
            {
            // Not yet ready to run: just decrement the delay 
            SCH_tasks_G[Index].Delay -= 1;
            }
         }         
      }
   }   

/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Process_Tick_Message()

  The ticks messages are crucial to the operation of this shared-clock
  scheduler: the arrival of a tick message (at regular intervals) 
  invokes the 'Update' ISR, that drives the scheduler.

  The tick messages themselves may contain data.  These data are 
  extracted in this function. 

-*------------------------------------------------------------------*/
tByte SCC_A_SLAVE_Process_Tick_Message(void)
   {
   tByte Tick_ID;

   if ((CAN_messages[0].MCR1 & 0x0c) == 0x08)  // if MSGLST set
      {
      // Indicates that the CAN controller has stored a new 
      // message into this object, while NEWDAT was still set,
      // i.e. the previously stored message is lost.

      // We simply IGNORE this here and reset the flag
      CAN_messages[0].MCR1 = 0xf7;  // reset MSGLST
      }

   // The first byte is the ID of the slave for which the data are
   // intended
   Tick_ID = CAN_messages[0].Data[0];   // Get data byte 0 (Slave ID)

   if (Tick_ID == SLAVE_ID)
      {
      // Only if there is a match do we need to copy these fields
      Tick_message_data_G[0] = CAN_messages[0].Data[1];   
      Tick_message_data_G[1] = CAN_messages[0].Data[2];   
      Tick_message_data_G[2] = CAN_messages[0].Data[3];   
      Tick_message_data_G[3] = CAN_messages[0].Data[4];   
      }

   CAN_messages[0].MCR0 = 0xfd;  // reset NEWDAT, INTPND
   CAN_messages[0].MCR1 = 0xfd;  

   return Tick_ID;
   }


/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Send_Ack_Message_To_Master()

  Slave must send and 'Acknowledge' message to the master, after
  tick messages are received.  NOTE: Only tick messages specifically
  addressed to this slave should be acknowledged.

  The acknowledge message serves two purposes:
  [1] It confirms to the master that this slave is alive & well.
  [2] It provides a means of sending data to the master and - hence
      - to other slaves.

  NOTE: Data transfer between slaves is NOT permitted!

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Send_Ack_Message_To_Master(void)
   {
   // First byte of message must be slave ID
   CAN_messages[1].Data[0] = SLAVE_ID;   // data byte 0

   CAN_messages[1].Data[1] = Ack_message_data_G[0];   
   CAN_messages[1].Data[2] = Ack_message_data_G[1];   
   CAN_messages[1].Data[3] = Ack_message_data_G[2];   
   CAN_messages[1].Data[4] = Ack_message_data_G[3];   

   // Send the message on the CAN bus
   CAN_messages[1].MCR1 = 0xE7;  // TXRQ, reset CPUUPD
   }


/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Watchdog_Init()

  This function sets up the watchdog timer.

  If the Master fails (or other error develop), 
  no tick messages will arrive, and the scheduler
  will stop.  

  To detect this situation, we have a (hardware) watchdog
  running in the slave.  This watchdog - which should be set to
  overflow at around 100ms - is used to set the system into a
  known (safe) state.  The slave will then wait (indefinitely)
  for the problem to be resolved.

  NOTE: The slave will not be generating Ack messages in these 
  circumstances.  The Master (if running) will therefore be aware
  that there is a problem.  

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Watchdog_Init(void)   
   {
   // Watchdog timer prescaler (1/16) enabled 
   // Watchdog timer reload value is 0x6B
   // Watchdog period is 103.2 ms (10.0 MHz xtal, c515c)
   WDTREL = 0xEB;
  
   // Start watchdog timer
   WDT  = 1;
   SWDT = 1;     
   }


/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Watchdog_Refresh()

  Feed the watchdog.

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Watchdog_Refresh(void) reentrant
   {
   WDT  = 1;
   SWDT = 1;
   }    

/*------------------------------------------------------------------*-

  SCC_A_SLAVE_Enter_Safe_State()

  This is the state enterted by the system when:
  (1) The node is powerec up or reset
  (2) The Master node fails, and no working backup is available
  (3) The network has an error
  (4) Tick messages are delayed for any other reason

  Try to ensure that the system is in a 'safe' state in these 
  circumstances.

-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Enter_Safe_State(void)
   {
   // USER DEFINED 
   TRAFFIC_LIGHTS_Display_Safe_Output();
   }   

/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/

⌨️ 快捷键说明

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