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

📄 sci_ti2m.c

📁 PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont This code is copyright (c) 200
💻 C
字号:
/*------------------------------------------------------------------*-

   SCI_Ti2m.c (v1.00)

  ------------------------------------------------------------------

   This is an implementation of SCI SCHEDULER (TICK) for 8051/52.

   --- See Chapter 26 ---

   *** MASTER NODE : TICK-ONLY (DUPLEX) ***
   *** CHECKS FOR SLAVE ACKNOWLEDEMENTS ***

   *** Uses T2 for timing, 16-bit auto reload ***
   *** 12 MHz oscillator -> 1 ms (precise) tick interval ***

   --- Assumes '1232' watchdog on Slave ---


   COPYRIGHT
   ---------

   This code is from the book:

   PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont 
   [Pearson Education, 2001; ISBN: 0-201-33138-1].

   This code is copyright (c) 2001 by Michael J. Pont.
 
   See book for copyright details and other information.

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

#include "Main.h"
#include "Port.h"

#include "SCI_Ti2m.H"
#include "Delay_T0.h"
#include "TLight_A.h"

// ------ Public variable definitions ------------------------------

// Used to detect slave activity
bit First_call_G;
bit Watchdog_input_previous_G;

// ------ Public variable declarations -----------------------------

// The array of tasks (see Sch51.c)
extern sTask SCH_tasks_G[SCH_MAX_TASKS];

// The error code variable (see Sch51.c)
extern tByte Error_code_G;

// Used to reset system in event of slave error (see Main.C)
extern bit System_reset_G;

// ------ Private function prototypes ------------------------------

static void SCI_TICK2_MASTER_Send_Tick_Message(void);
static bit  SCI_TICK2_MASTER_Process_Ack(void);

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

  SCI_TICK2_MASTER_Init_T2()

  Scheduler initialisation function.  Prepares scheduler data 
  structures and sets up timer interrupts at required rate.
  You must call this function before using the scheduler.  

-*------------------------------------------------------------------*/
void SCI_TICK2_MASTER_Init_T2(void) 
   {
   tByte i;

   // No interrupts (yet)
   EA = 0;

   // ------ Set up the scheduler ----------------------------------
   // Sort out the tasks
   for (i = 0; i < SCH_MAX_TASKS; i++) 
      {
      SCH_Delete_Task(i);
      }

   // Reset the global error variable
   // - SCH_Delete_Task() will generate an error code, 
   //   (because the task array is empty)
   Error_code_G = 0;

   // ------ Set up Timer 2 (begin) --------------------------------
   // Now set up Timer 2
   // 16-bit timer function with automatic reload

   // Crystal is assumed to be 12 MHz
   // The Timer 2 resolution is 0.000001 seconds (1 祍)
   // The required Timer 2 overflow is 0.001 seconds (1 ms)
   // - this takes 1000 timer ticks
   // Reload value is 65536 - 1000 = 64536 (dec) = 0xFC18

   T2CON = 0x04;   // load Timer 2 control register
   T2MOD = 0x00;   // load Timer 2 mode register

   TH2    = 0xFC;  // load timer 2 high byte
   RCAP2H = 0xFC;  // load timer 2 reload capture reg, high byte
   TL2    = 0x18;  // load timer 2 low byte
   RCAP2L = 0x18;  // load timer 2 reload capture reg, low byte
   
   ET2   = 1;  // Timer 2 interrupt is enabled

   TR2   = 1;  // Start Timer 2
   // ------ Set up Timer 2 (end) ----------------------------------
   }

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

  SCI_TICK2_MASTER_Start()

  Starts the scheduler, by enabling interrupts.

  NOTE: Usually called after all regular tasks are added,
  to keep the tasks synchronised.

  NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!! 
 
-*------------------------------------------------------------------*/
void SCI_TICK2_MASTER_Start(void) 
   {
   // Try to place system in 'safe' state at start or after errors
   SCI_TICK2_MASTER_Enter_Safe_State();

   // Delay here to cause the slave to time out and reset
   // Adjust this delay to match the timeout periods on the slaves
   Hardware_Delay_T0(500);

   // Now send first tick to start the slave
   // (starts on falling edge)
   Interrupt_output_pin = 1;
   Hardware_Delay_T0(5);
   Interrupt_output_pin = 0;
   Hardware_Delay_T0(5);

   Interrupt_output_pin = 1; // Ready for first tick

   // Start the scheduler
   EA = 1;
   }

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

  SCI_TICK2_MASTER_Update_T2

  This is the scheduler ISR.  It is called at a rate determined by 
  the timer settings in SCI_TICK2_MASTER_Init_T2().  This version is 
  triggered by Timer 2 interrupts: timer is automatically reloaded.

-*------------------------------------------------------------------*/
void SCI_TICK2_MASTER_Update_T2(void) interrupt INTERRUPT_Timer_2_Overflow  
   {
   tByte Index;

   TF2 = 0; // Must manually clear this. 

   // Get the ack message from the slave
   if (SCI_TICK2_MASTER_Process_Ack() == RETURN_ERROR)
      {
      // Did not receive ack!
      Error_code_G = ERROR_SCH_LOST_SLAVE;

      // Enter safe state and remain here until reset
      SCI_TICK2_MASTER_Enter_Safe_State();
      while(1); 
      }
 
   // Send 'tick' message to the slave
   SCI_TICK2_MASTER_Send_Tick_Message(); 

   // 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;  // Increment 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;
            }
         }         
      }

   // Prepare for next tick
   Interrupt_output_pin = 1;
   }   

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

  SCI_TICK2_MASTER_Send_Tick_Message()

  This function sends a tick message.

  The receipt of this message will cause an interrupt to be generated
  in the slave(s): this will, in turn, invoke the scheduler 'update' 
  function in the slave(s).

-*------------------------------------------------------------------*/
void SCI_TICK2_MASTER_Send_Tick_Message(void) 
   {
   // Send tick (falling edge) to the slave
   Interrupt_output_pin = 0;
   }


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

  SCI_TICK2_MASTER_Process_Ack()

  Checks that the slave is operating.

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

bit SCI_TICK2_MASTER_Process_Ack(void) 
   {
   if (First_call_G)
      {
      // This is the first time this function has been called
      First_call_G = 0;

      // Prepare for subsequent checking of the watchdog pin
      Watchdog_input_previous_G = Slave_watchdog_pin;
      }
   else
      {
      // Watchdog pin should change state every time
      // - if the slave is running correctly
      if (Watchdog_input_previous_G == Slave_watchdog_pin)
         {
         // Error!
         return RETURN_ERROR;
         }

      // Slave is OK
      Watchdog_input_previous_G = Slave_watchdog_pin;
      }

   return RETURN_NORMAL;
   }

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

  SCI_TICK2_MASTER_Enter_Safe_State()

  This is the state entered by the system when:
  (1) The node is powered up or reset
  (2) The slave node fails
  (3) The network has an error
  (4) Ack messages are delayed for any other reason

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

-*------------------------------------------------------------------*/
void SCI_TICK2_MASTER_Enter_Safe_State(void) reentrant
   {
   // USER DEFINED - Edit as required

   // Here we display a safe output
   TRAFFIC_LIGHTS_Display_Safe_Output();
   }  

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

⌨️ 快捷键说明

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