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

📄 2_01_10i.c

📁 基于时间触发调度器的直流电机闭环控制
💻 C
字号:
/*------------------------------------------------------------------*-

   2_01_10i.c (v1.00)

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

   *** THIS IS A SCHEDULER FOR 80C515C (etc.) ***
   *** For use in single-processor applications  ***

   *** Uses T2 for timing, 16-bit auto reload ***

   *** This version assumes 10 MHz crystal on 515c ***
   *** 1 ms (approx) tick interval ***

   *** Includes display of error codes ***


   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 "2_01_10i.H"

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

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

// Used to display the error code
// See Main.H for details of error codes
// See Port.H for details of the error port
extern tByte Error_code_G;

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

  SCH_Init_T2()

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

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

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

   // Now set up Timer 2
   // 16-bit timer function with automatic reload
   // Crystal is assumed to be 10 MHz
   // Using c515c, so timer can be incremented at 1/6 crystal frequency
   // if prescalar is not used

   // Prescaler not used -> Crystal/6
   T2PS = 0;

   // The Timer 2 resolution is  0.0000006 seconds (0.6 祍)
   // The required Timer 2 overflow is 0.001 seconds (1 ms)
   // - this takes  1666.666666667 timer ticks (can't get precise timing)
   // Reload value is 65536 - 1667 = 63869 (dec) = 0xF97D
   TH2 = 0xF9; 
   TL2 = 0x7D;
     
   // Compare/capture Channel 0 
   // Disabled
   // Compare Register CRC on: 0x0000;
   CRCH = 0xF9;
   CRCL = 0x7D;

   //  Mode 0 for all channels
   T2CON |= 0x11;

   //  timer 2 overflow interrupt is enabled
   ET2 = 1;
   //  timer 2 external reload interrupt is disabled
   EXEN2 = 0;
  
   //  CC0/ext3 interrupt is disabled
   EX3 = 0;
  
   // Compare/capture Channel 1-3 
   // Disabled
   CCL1 = 0x00;
   CCH1 = 0x00;
   CCL2 = 0x00;
   CCH2 = 0x00;
   CCL3 = 0x00;
   CCH3 = 0x00;
  
   // Interrupts Channel 1-3 
   // Disabled
   EX4 = 0;
   EX5 = 0;
   EX6 = 0;
  
   // all above mentioned modes for Channel 0 to Channel 3 
   CCEN = 0x00;
   // ------ Set up Timer 2 (end) ----------------------------------
   }

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

  SCH_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 SCH_Start(void) 
   {
   // Comment out as required, depending on compiler used
   //EA = 1;   // Use with C51 v5.X
   EAL = 1;  // Use with C51 v6.X
   }

/*------------------------------------------------------------------*-
  
  SCH_Update()

  This is the scheduler ISR.  It is called at a rate determined by 
  the timer settings in SCH_Init_T2().  This version is 
  triggered by Timer 2 interrupts: timer is automatically reloaded.
 
-*------------------------------------------------------------------*/
void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow  
   {
   tByte Index;

   TF2 = 0; // Have to manually clear this. 

   // 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;  // Incr. 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;
            }
         }         
      }
   }   

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

⌨️ 快捷键说明

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