一、设置方法所需结构体

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();
    }
}

 

原文地址:http://www.cnblogs.com/yuanyongfei/p/16810612.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性