📄 os_tick.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 + -