一、设置方法所需结构体

typedef struct TASK_COMPONENTS {
    unsigned char Run;                // 程序运行标记:0-不运行,1-运行  ,这里是程序会不会运行
    unsigned char Timer;              // 计时器, 这个是用于在定时器中减减的
    unsigned char ItvTime;         // 任务运行间隔时间, 这个是用于更新参数的
    void (*TaskHook)(void);       // 要运行的任务函数 函数指针
} TASK_COMPONENTS;                 // 任务定义

 二、构建任务表

/**************************************************************************************
* Variable definition 这里添加你的任务。。。。
**************************************************************************************/
static TASK_COMPONENTS TaskComps[] =
{ 
    {0, 0,2, RGB_MODE1},       //任务一
    {0, 0,1000, Led},      //任务二
};

三、任务标志检测,在定时器中断中调用

/**************************************************************************************
* FunctionName   : TaskRemarks()          //放到定时器中
* Description    : 任务标志处理
**************************************************************************************/
void TaskRemarks(void)                            //要放到  timer中断中
{
    uchar i;
    uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS);
    for(i = 0; i < TaskMax; i++)
    {
        if(TaskComps[i].Timer)   // 时间不为0 , 可是我有一个问题, 什么时候用 . 什么时候用 ->
        {
            TaskComps[i].Timer--; 
        }
        else
         {
                if(TaskComps[i].Timer == 0)            //如果计时到
             {
                  TaskComps[i].Timer = TaskComps[i].ItvTime;       // 恢复计时器值,从新下一次
                    TaskComps[i].Run = 1;                            // 任务可以运行, 任务的延迟已经过了, 可以继续运行了
              }
          }
    }
}

四、任务处理,在while(1)中调用

/**************************************************************************************
* FunctionName   : TaskProcess()
**************************************************************************************/
void TaskProcess(void)
{
    uchar i;
        uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS);
    for (i=0; i<TaskMax; i++)  // 逐个任务时间处理
    {
        if(TaskComps[i].Run)     //如果任务可以运行
        {
            TaskComps[i].TaskHook(); // 运行任务, 这个是一个函数, 在运行完这个函数后, 我们下一步操作就是清除标志位
            TaskComps[i].Run = 0;    // 标志清0
        }
    }
}

 完整程序

#include "WS51F0030.h"
#include "RGB.h"

#define Time0Def  65536-2668     //2ms
#define uchar unsigned char
#define uint  unsigned int
    
void Led(void)
{
        P14 = ~P14;
}

typedef struct TASK_COMPONENTS {
    unsigned char Run;            // 程序运行标记:0-不运行,1-运行  ,这里是程序会不会运行
    unsigned char Timer;        // 计时器, 这个是用于在定时器中减减的
    unsigned char ItvTime;    // 任务运行间隔时间, 这个是用于更新参数的
    void (*TaskHook)(void); // 要运行的任务函数 函数指针
} TASK_COMPONENTS;        // 任务定义

/**************************************************************************************
* Variable definition 这里添加你的任务。。。。
**************************************************************************************/
static TASK_COMPONENTS TaskComps[] =
{ 
    {0, 0,2, RGB_MODE1}, 
        {0, 0,1000, Led},
};
//2. 任务运行标志出来,此函数就相当于中断服务函数,需要在定时器的中断服务函数中调用此函数,这里独立出来,便于移植和理解。
/**************************************************************************************
* FunctionName   : TaskRemarks()          //放到定时器中
* Description    : 任务标志处理
**************************************************************************************/
void TaskRemarks(void)                            //要放到  timer中断中
{
    uchar i;
        uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS);
    for(i = 0; i < TaskMax; i++)
    {
        if(TaskComps[i].Timer)   // 时间不为0 , 可是我有一个问题, 什么时候用 . 什么时候用 ->
        {
            TaskComps[i].Timer--;  // 减去一个节拍
        }
                else
                {
                        if(TaskComps[i].Timer == 0)            //如果计时到
            {
                TaskComps[i].Timer = TaskComps[i].ItvTime;       // 恢复计时器值,从新下一次
                TaskComps[i].Run = 1;                            // 任务可以运行, 任务的延迟已经过了, 可以继续运行了
            }
                }
    }
}
//3. 任务处理:实现任务管理操作, 用于循环判断哪个任务需要运行了
/**************************************************************************************
* FunctionName   : TaskProcess()
**************************************************************************************/
void TaskProcess(void)
{
    uchar i;
        uchar TaskMax = sizeof(TaskComps)/sizeof(TASK_COMPONENTS);
    for (i=0; i<TaskMax; i++)  // 逐个任务时间处理
    {
        if(TaskComps[i].Run)     //如果任务可以运行
        {
            TaskComps[i].TaskHook(); // 运行任务, 这个是一个函数, 在运行完这个函数后, 我们下一步操作就是清除标志位
            TaskComps[i].Run = 0;    // 标志清0
        }
    }
}

void delay_1ms(void)
{
    int j;
    for(j=0; j<17700; ++j);
}
/***************************
*系统时钟初始化
***************************/
void System_Init(void)
{
    delay_1ms();
    SCCON = 0x00;//使能HRC
    HRCON |= 0x80;
    delay_1ms();
    SCCON = 0x00;//使能HRC
    HRCON |= 0x80;
    delay_1ms();
}

/*****************************************************
*全局中断打开
*****************************************************/
void ISR(void)
{
    EA = 1;
}

/*****************************************************
* 中断服务函数  1ms
*****************************************************/
void timer0_isr (void) interrupt 1
{
    TL0 = Time0Def & 0xff;       //初始值低字节,TL0 的高 3 位是无效的
    TH0 = Time0Def >> 8;         //初始值高字节(1ms@16MHz)  0.993ms
        TaskRemarks();
}

/*****************************************************
*函数功能:Timer0初始化配置
*****************************************************/
void Timer0_Init(void)
{
    ET0 = 0;
    TL0 = Time0Def & 0xff;       //初始值低字节,TL0 的高 3 位是无效的
    TH0 = Time0Def >> 8;         //初始值高字节(1ms@16MHz)  0.993ms
    TMOD = 0x01;                        //定时器,时钟为系统时钟 12 分频

    ET0 = 1;    //开中断 定时器 0 中断使能控制位
    TR0 = 1;    //启动定时器
}

void Gpio_Init(void)
{
    P14F = 0x02;   //LED
    P05F = 0x02;
}

int main(void)
{
    uint i = 0;
    System_Init();
    Gpio_Init();
    Timer0_Init();
    ISR();

    while(1)
    {
        TaskProcess();
    }
}

 

posted on 2022-10-20 17:22  xiao_fei  阅读(163)  评论(0编辑  收藏  举报