?? schedule._c
字號:
///////////////////////////////////////////////////////////////
/**************************************************************
公司名稱: 揚州恒博科技
模塊名 : 點動型STQ執行機構主控程序
創建人 : 章儉文
日期 : 2008/08/19
功能描述: 完成對本地旋鈕和遠程開關量的控制功能
其它說明: 編譯環境為ICCAVR V6.31A
版本 : V1.0
**************************************************************/
///////////////////////////////////////////////////////////////
#define SCHEDULE_GLOBAL
#include "schedule.h"
static void SCH_Updata(void);
// 在任一時刻要求的任務最大數目
#define SCH_MAX_TASKS (3)
// 任務隊列
sTask SCH_tasks_G[SCH_MAX_TASKS];
// 錯誤代碼
#define ERROR_SCH_TOO_MANY_TASKS (1)
#define ERROR_SCH_CANNOT_DELETE_TASK (2)
#define RETURN_NORMAL 0
#define RETURN_ERROR 1
/*---------------------------------------------------------*-
* 函數名稱: SCH_Dispatch_Tasks()
* 入 口:
* 出 口:
* 函數功能: 調度函數,當一個任務()需要運行時,此函數將運行它,
*
* 說 明: 這個函數必須被主循環(重復)調用
-*---------------------------------------------------------*/
void SCH_Dispatch_Tasks(void)
{
unsigned char Index;
// 調度(運行)下一個任務(如果有任務就緒)
for (Index=0; Index<SCH_MAX_TASKS; Index++)
{
if (SCH_tasks_G[Index].RunMe > 0)
{
// 運行任務
(*SCH_tasks_G[Index].pTask)();
// 復位 / 降低RunMe標志
SCH_tasks_G[Index].RunMe -= 1;
// 如果這個是'單次'任務,將它從隊列中刪除
if (SCH_tasks_G[Index].Period == 0)
{
SCH_Delete_Task(Index);
}
}
}
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Add_Task()
* 入 口: (*pFunction)任務指針,(DELAY)到第一次運行間隔時標,
* (PERIOD)每次運行的間隔時標
*
* 出 口: 返回SCH_MAX_TASKS表示任務隊列已滿
* 返回(Index)=任務位置
*
* 函數功能: 用來添加任務到任務隊列上,以保證它們在需要的時
* 候被調用
*
* 說 明: 使任務函數每隔一定間隔或在用戶的延遲之后執行.
-*---------------------------------------------------------*/
unsigned char SCH_Add_Task(void (*pFunction)(), // 任務指針
const unsigned int DELAY, // 延遲Delay個時標后函數將第一次運行
const unsigned int PERIOD) // 連續的運行之間的間隔(時標)
{
unsigned char Index = 0; // 首先在隊列中找到一個空隙
while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
{
Index++;
}
if (Index == SCH_MAX_TASKS)
{
return SCH_MAX_TASKS; // 同時返回錯誤代碼
}
// 如果能運行到這里,則說明任務隊列中有空間
SCH_tasks_G[Index].pTask = pFunction;
SCH_tasks_G[Index].Delay = DELAY;
SCH_tasks_G[Index].Period = PERIOD;
SCH_tasks_G[Index].RunMe = 0;
return Index; // 返回任務的位置(以便以后刪除)
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Delete_Task()
* 入 口: TASK_INDEX -任務索引.由SCH_Add_task()提供
*
* 出 口: 返回值: RETURN_ERROR(或)RETURN_NORMAL
*
* 函數功能: 從調度器刪除任務.
*
* 說 明: 請注意:并不是從存儲器中刪除相關的函數,僅僅是不再
* 由調度器調用這個任務.
-*---------------------------------------------------------*/
uchar SCH_Delete_Task(const unsigned char TASK_INDEX)
{
uchar Return_code; //返回錯誤代碼
if (SCH_tasks_G[TASK_INDEX].pTask == 0)
{
Return_code = RETURN_ERROR;
}
else
{
Return_code = RETURN_NORMAL;
}
// 刪除任務
SCH_tasks_G[TASK_INDEX].pTask = 0x00;
SCH_tasks_G[TASK_INDEX].Delay = 0;
SCH_tasks_G[TASK_INDEX].Period = 0;
SCH_tasks_G[TASK_INDEX].RunMe = 0;
return Return_code;
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Update()
* 入 口:
* 出 口:
* 函數功能: 在調度器的中斷服務程序中運行
*
* 說 明: "刷新"函數,確定某個任務需要運行時,將這個任務的
* RunMe標志加1,然后該任務將由調度程序執行.
-*---------------------------------------------------------*/
static void SCH_Updata(void)
{
unsigned char Index;
for (Index=0; Index < SCH_MAX_TASKS; Index++)
{
// 檢測這里是否有任務?
if (SCH_tasks_G[Index].pTask != 0)
{
if (SCH_tasks_G[Index].Delay == 0)
{
SCH_tasks_G[Index].RunMe += 1; // RunMer標志加1
if (SCH_tasks_G[Index].Period != 0)
{
// 調度定期的任務再次運行
SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
}
}
else
{
// 還沒有準備好運行,延遲減1
SCH_tasks_G[Index].Delay -= 1;
}
}
}
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Init_Timer2()
* 入 口:
* 出 口:
* 函數功能: 準備調度器數據結構并且設置定時器以所需的頻率中斷
*
* 說 明: 調度器初始化化函數,必須在使用調度器之前調用它
-*---------------------------------------------------------*/
void InitTimer1(void) //8MHz,10ms,64分頻
{
uchar i;
for (i=0; i<SCH_MAX_TASKS; i++)
{
SCH_Delete_Task(i);
}
TCCR1B = 0x00; //stop
TCNT1H = 0xFB; //setup
TCNT1L = 0x1E;
OCR1AH = 0x04;
OCR1AL = 0xE2;
OCR1BH = 0x04;
OCR1BL = 0xE2;
ICR1H = 0x04;
ICR1L = 0xE2;
TCCR1A = 0x00;
TCCR1B = 0x03; //start Timer
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Update_Server()
* 入 口:
* 出 口:
* 函數功能: 調度器的中斷服務程序
*
* 說 明: "刷新"函數,確定某個任務需要運行時,將這個任務的
* RunMe標志加1,然后該任務將由調度程序執行.
-*---------------------------------------------------------*/
#pragma interrupt_handler SCH_Update_Server:9 //定時器溢出中斷
void SCH_Update_Server(void)
{
TCNT1H = 0xFB; //reload counter value
TCNT1L = 0x1E;
TimeTick++;
MotorDelayTime++;
if(TimeTick%100 == 0) //1s喂狗
{
if(TimeTick == 200)TimeTick = 0;
OutWdServer();
}
SCH_Updata();
}
/*---------------------------------------------------------*-
* 函數名稱: SCH_Start()
* 入 口:
* 出 口:
* 函數功能: 通過允許中斷來啟動調度器
*
* 說 明: 在添加了所有定期的任務之后調用,從而使任務保持同步.
* 注意:應該只使能調度器中斷
-*---------------------------------------------------------*/
void SCH_Start(void)
{
SEI();
}
//**************END OF FILE*********************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -