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

📄 os_tick.c

📁 时间触发式51单片机嵌入式多任务系统
💻 C
字号:
/*------------------------------------------------------------------*-

   0_05_11g.C (v1.00)

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

   *** THIS IS A SCHEDULER FOR THE STANDARD 8051 ***

   *** Uses T0 for timing, 16-bit, manual reload ***

   *** With 11.059 MHz crystal -> 5ms tick interval ***
   --- (see 'reload' function for details) ---


   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 "../a/main/main.h"
#include "os_cfg.h"
#include "os_cpu.h"
#include "OS_Tick.h"
#include "hSch51.h"
#include "intimers.h"


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

// The array of tasks (see Sch51.C)
extern sTaskH hSCH_tasks_G[hSCH_MAX_TASKS];


// ------ Private function prototypes ------------------------------
#define mTHL_DEF (65536 - (tWord)((tLong)mFosc_Tick * (tLong)OSC_FREQ / (tLong)OSC_PER_INST / 1000UL))
#define mTH_DEF  (mTHL_DEF / 256)
#define mTL_DEF  (mTHL_DEF % 256)

#if _OS_TICK_TIMER == 0
/*------------------------------------------------------------------*-

  SCH_Manual_Timer0_Reload()

  This scheduler uses a (manually reloaded) 16-bit timer.
  The manual reload means that all timings are approximate.
  THIS SCHEDULER IS NOT SUITABLE FOR APPLICATIONS WHERE
  ACCURATE TIMING IS REQUIRED!!!

  Timer reload is carried out in this function.

-*------------------------------------------------------------------*/
void hSCH_Manual_Timer0_Reload()
{
   // Stop Timer 0
   TR0 = 0;

   // Crystal is assumed to be 11.059 MHz
   // Assume 12 osc cycles per timer increment
   // -> timer resolution is 0.0000010850694 seconds (1.085 祍)
   //
   // The required Timer 0 overflow is 0.005 seconds (5 ms)
   // - this takes 4608 timer ticks
   //
   // Reload value is 65536 - 4608 = 60928 (dec) = 0xEE00
   // X = 65536 - ms * 1000 * Fosc / 12;

   TH0  = mTH_DEF;
   TL0  = mTL_DEF;

   //  Start Timer 0
   TR0  = 1;
}
#endif

#if _OS_TICK_TIMER == 2
/*------------------------------------------------------------------*-

  SCH_Manual_Timer2_Reload()

  This scheduler uses a (manually reloaded) 16-bit timer.
  The manual reload means that all timings are approximate.
  THIS SCHEDULER IS NOT SUITABLE FOR APPLICATIONS WHERE
  ACCURATE TIMING IS REQUIRED!!!

  Timer reload is carried out in this function.

-*------------------------------------------------------------------*/
void hSCH_Manual_Timer2_Reload()
{
   // Crystal is assumed to be 11.059 MHz
   // Assume 12 osc cycles per timer increment
   // -> timer resolution is 0.000001085069444444 seconds (1.085 祍)
   // The required Timer 2 overflow is 0.005 seconds (5 ms)

   TH2    = mTH_DEF;  // load timer 2 high byte
   TL2    = mTL_DEF;  // load timer 2 low byte
   RCAP2H = TH2;      // load timer 2 reload capture reg, high byte
   RCAP2L = TL2;      // load timer 2 reload capture reg, low byte

   TR2   = 1;  // Start Timer 2
}
#endif

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

  hSCH_Init()

  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 hSCH_Init(void)
{
   tByte i;

   for (i = 0; i < hSCH_MAX_TASKS; i++)
   {
      hSCH_Delete_Task(i);
   }


#if _OS_TICK_TIMER == 0
   // Using Timer 0, 16-bit manual reload
   TMOD &= 0xF0; // Clear all T0 bits (T1 left unchanged)
   TMOD |= 0x01; // Set required T0 bits (T1 left unchanged)

   // Sets up timer reload values
   hSCH_Manual_Timer0_Reload();

   //  Interrupt Timer 0 enabled
   ET0  = 1;
#endif

#if _OS_TICK_TIMER == 2
   // Now set up Timer 2
   // 16-bit timer function with automatic reload

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

   // Sets up timer reload values
   hSCH_Manual_Timer2_Reload();

   // Start timer
   ET2   = 1;  // Timer 2 interrupt is enabled

#endif
}

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

  hSCH_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 hSCH_Start(void)
{
#if _OS_REPORT_ERRORS > 0
   Error_code_G = 0;
#endif
   OS_EXIT_CRITICAL();
}

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

  hSCH_Go_To_Sleep()

  This scheduler enters 'idle mode' between clock ticks
  to save power.  The next clock tick will return the processor
  to the normal operating state.

  Note: a slight performance improvement is possible if this
  function is implemented as a macro, or if the code here is simply
  pasted into the 'dispatch' function.

  However, by making this a function call, it becomes easier
  - during development - to assess the performance of the
  scheduler, using the 'performance analyser' in the Keil
  hardware simulator. See Chapter 14 for examples for this.

  *** May wish to disable this if using a watchdog ***

  *** ADAPT AS REQUIRED FOR YOUR HARDWARE ***

-*------------------------------------------------------------------*/
void hSCH_Go_To_Sleep()
{
   PCON |= 0x01;    // Enter idle mode (generic 8051 version)

   // Entering idle mode requires TWO consecutive instructions
   // on 80c515 / 80c505 - to avoid accidental triggering
   //PCON |= 0x01;    // Enter idle mode (#1)
   //PCON |= 0x20;    // Enter idle mode (#2)
}

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

  hSCH_Update

  This is the scheduler ISR.  It is called at a rate
  determined by the timer settings in SCH_Init_T0().
  This version is triggered by Timer 0 interrupts.

-*------------------------------------------------------------------*/
#if _OS_TICK_TIMER == 0
#define INTERRUPT_Timer_Overflow 	INTERRUPT_Timer_0_Overflow
#endif
#if _OS_TICK_TIMER == 2
#define INTERRUPT_Timer_Overflow 	INTERRUPT_Timer_2_Overflow
#endif

void hSCH_Update(void) interrupt INTERRUPT_Timer_Overflow
{
#if _OS_TICK_TIMER == 0
   // Reload the timer
   hSCH_Manual_Timer0_Reload();
#endif

#if _OS_TICK_TIMER == 2
   TF2 = 0; // Have to manually clear this.
#endif

   hSCH_CtxSw();

#if _OS_INICHE_TIMERS > 0
   check_interval_timers();
#endif

#if _OS_USER_TICK_TIMER > 0
   UserTickTimer();        // 系统定时中断中调用的用户函数
#endif

}


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

⌨️ 快捷键说明

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