混合式调度器C51源代码及相关注释
/*==============================================================
1ms时标 混合式调度器(一个抢占式任务,多个合作式任务)
作者:shadow.hu
===============================================================*/
#includereg52.h>
#define uchar unsigned char
#define ushort unsigned short
#define SCH_MAX_TASKS 9
#define ERROR_SCH_TOO_MANY_TASKS 9
#define ERROR_SCH_CANOT_DELETE_TASK 0
#define RETURN_ERROR 0
#define RETURN_NORMAL 1
#define INTERRPT_Timer_2_Overflow 5
#define SCH_REPORT_ERRORS
#ifdef SCH_REPORT_ERRORS
#define Error_Port P1
#endif
typedef data struct
{
void (code *pTask)(void);
ushort Delay;
ushort Period;
ushort RunMe;
uchar Co_op;//如果任务是合作式的,设置为1,如果任务是抢占式的,设置为0
}sTask;
sTask SCH_tasks_G[SCH_MAX_TASKS];
void SCH_Init_T2(void);
uchar SCH_Add_Task(void (code * pFunction)(),const ushort Delay, ushort PERIOD);
// 函数名指针 延时的时标数 执行任务的时间间隔
// 为0则立即执行 如果为0,表示单次任务
void SCH_Dispatch_Tasks(void);
void SCH_Start(void);
bit SCH_Delete_Task(const ushort TASK_INDEX);
void SCH_Go_To_Sleep(void);
void SCH_Report_Status(void);//报告系统状况
void LED_Flash_Init(void);
void LED_Flash_Update_A(void);
void LED_Flash_Update_B(void);
void LED_Flash_Update_C(void);
void LED_Flash_Update_D(void);
void LED_Flash_Update_E(void);
void LED_Flash_Update_F(void);
void LED_Flash_Update_G(void);
void LED_Flash_Update_H(void);
uchar Error_code_G = 0;//
static ushort Error_tick_count_G;//记住自从上一次纪录错误以来的时间
static uchar Last_error_code_G;//上次的错误代码(在1分钟之后复位)
uchar LED_State_G_A = 0;
uchar LED_State_G_B = 0;
uchar LED_State_G_C = 0;
uchar LED_State_G_D = 0;
uchar LED_State_G_E = 0;
uchar LED_State_G_F = 0;
uchar LED_State_G_G = 0;
uchar LED_State_G_H = 0;
sbit LED_pin_A = P1^0;
sbit LED_pin_B = P1^1;
sbit LED_pin_C = P1^2;
sbit LED_pin_D = P1^3;
sbit LED_pin_E = P1^4;
sbit LED_pin_F = P1^5;
sbit LED_pin_G = P1^6;
sbit LED_pin_H = P1^7;
//Error_code_G = ERROR_SCH_TOO_MANY_TASKS;
//Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
//Error_code_G = ERROR_SCH_WAITING_FOR_START_COMAND_FROM_MASTER;
//Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
//Error_code_G = ERROR_SCH_LOST_SLAVE;
//Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
//Error_code_G = ERROR_I2C_WRITE_BYTE_AT24C64;
void main(void)
{
SCH_Init_T2();
LED_Flash_Init();
SCH_Add_Task(LED_Flash_Update_A,0,1000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_B,0,2000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_C,0,3000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_D,0,4000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_E,0,5000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_F,0,6000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_G,0,7000);//添加一个任务
SCH_Add_Task(LED_Flash_Update_H,0,8000);//添加一个任务
SCH_Start();//开全局中断
while(1)
{
SCH_Dispatch_Tasks();
}
}
/*------------------------------------------------------------
这是调度器的中断服务程序,初始化函数中的定时器设置决定了它
的调度频率,这个版本的调度器由定时器2触发中断,定时器自动重装。
-------------------------------------------------------------*/
void SCH_Update(void) interrupt INTERRPT_Timer_2_Overflow
{
//刷新任务队列
uchar Index;
TF2 = 0;//必须手工清除
//注意:计算单位为时标(不是毫秒)
for(Index = 0;Index SCH_MAX_TASKS;Index++)
{ //检测这里是否有任务
if(SCH_tasks_G[Index].pTask)
{
if(SCH_tasks_G[Index].Delay == 0)
{
//任务需要运行,间隔的时间已经到了
if(SCH_tasks_G[Index].Co_op)
{
//如果是合作式任务,RunMe标志加1
SCH_tasks_G[Index].RunMe += 1;//要执行任务的标志加1
}
else//如果它是抢占式任务,立即运行它
{
(*SCH_tasks_G[Index].pTask)();//运行任务
SCH_tasks_G[Index].RunMe -= 1;
//周期性的任务将自动再次运行,单次任务就删除
if(SCH_tasks_G[Index].Period == 0)
{
SCH_tasks_G[Index].pTask = 0;
}
}
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;
}
}
}
}
- 基于DSP的实时互相关测速系统设计与实现 (10-07)
- 一款用DSP+FPGA实现的数字相关器 (10-10)
- 基于FPGA滑动相关法伪码捕获的实现(06-06)
- Profinet相关名词解释(12-19)
- can总线相关知识(12-14)
- 电机相关知识(12-12)