×
单片机 > 单片机程序设计 > 详情

软件定时器和分时复用的实现

发布时间:2020-05-29 发布时间:
|

在单片机编程中,最主要的是掌握单片机工作的时间节拍,最大限度地利用CPU资源,下面提供一种基于基准定时器进行软件定时、任务执行采用分时复用的方法,规定每个任务执行的时间,执行时间到后切换下一任务。

u16 Timer_Count = 0,Timer_Count_OverFlow = 0;  

u16 this_time = 0,last_time = 0,time_overflow = 0;  

#define Timer_Period             60000  

#define OutofRunningTime(time)  (Timer_Period*Timer_Count_OverFlow+this_time-last_time >= time)  

#define TIME_MS(x)              (1*x)  

#define TIME_S(x)               (1000*x)  

#define TOTAL_TASK              3      //定义任务总数  

enum {TASK1,TASK2,TASK3};  

  

void 26 interrupt PIT0(void)     //中断定时器,1ms进入一次  

{  

    Timer_Count ++;  

    if(Timer_Count >= Timer_Period)  

    {  

        Timer_Count = 0;  

        Timer_Count_OverFlow ++;  

    }  

}  

  

static u8 task1(void)  

{  

    last_time = Timer_Count;  

    Timer_Count_OverFlow = 0;  

    for(;;)  

    {  

        this_time = Timer_Count;  

        do_some_thing();  

        if(OutofRunningTime(TIME_S(2)))  

            return TASK2;  

    }  

}  

  

static u8 task2(void)  

{  

    last_time = Timer_Count;  

    Timer_Count_OverFlow = 0;  

    for(;;)  

    {  

        this_time = Timer_Count;  

        do_some_thing();  

        if(OutofRunningTime(TIME_S(2)))  

            return TASK3;  

    }  

}  

  

static u8 task3(void)  

{  

    last_time = Timer_Count;  

    Timer_Count_OverFlow = 0;  

    for(;;)  

    {  

        this_time = Timer_Count;  

        do_some_thing();  

        if(OutofRunningTime(TIME_S(2)))  

            return TASK1;  

    }  

}  

  

u8 task_process(u8 task)  

{  

    u8 next_task;  

    switch(task)  

    {  

        case TASK1:  

            next_task = task1();  

        break;  

        case TASK2:  

            next_task = task2();  

        break;  

        case TASK3:  

            next_task = task3();  

        break;  

        default:  

        break;  

    }  

    return next_task;  

}  

  

u8 Current_Task = TASK1;  

void main(void)  

{  

    Current_Task = system_init();  

    for(;;)  

    {  

        Current_Task = task_process(Current_Task);  

    }  

}  

代码中定义了一个时基为1ms的中断定时器,用Timer_Count作为自由计数值,计数上限为Timer_Period,到达上限后将Timer_Count清零,同时统计一次溢出次数Timer_Count_OverFlow,溢出次数自由计数,直到溢出后清零,进入下一轮回。 main函数执行的时候进入task_process函数,同时传递进入当前需要执行的任务号,首次执行的时候传递进去的任务号是TASK1,从task1()开始执行,下面对task1()进行分析。

执行任务函数的时候先记录当前Timer_Count的值,将溢出次数Timer_Count_OverFlow清零,然后一直执行for循环中的do_some_thing(),同时记录和检测当前Timer_Count的值,根据当前Timer_Count值和进入任务时的Timer_Count比较,如果时间到达我们需要任务执行的时间,则跳出for循环,同时返回下次要执行的任务号,在main函数中根据返回的任务号进入下一任务的执行。

代码中实现的是基本的软件架构,并没有具体程序执行的功能代码,移植的时候只要使用单片机中的一个定时器,不断产生1ms的定时中断即可。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容