STM32定时器分时操作系统

发布者:huanguu最新更新时间:2020-05-13 来源: eefocus关键字:STM32  定时器  分时操作系统 手机看文章 扫描二维码
随时随地手机看文章

前后台系统,RTOS与定时器任务管理系统


前后台系统

  在裸机上写程序,通常把程序分为两部分:前台系统和后台系统。

  简单的小系统通常是前后台系统,这样的程序包括一个死循环和若干个中断服务程序:应用程序是一个无限循环,循环中调用API函数完成所需的操作,这个大循环就叫做后台系统。中断服务程序用于处理系统的异步事件,也就是前台系统。前台是中断级,后台是任务级。


RTOS

  RTOS全称为:Real Time OS,就是实时操作系统,强调的是:实时性。实时操作系统又分为硬实时和软实时。硬实时要求在规定的时间内必须完成操作 ,硬实时系统不允许超时,在软实时里面处理过程超时的后果就没有那么严格。在实时操作系统中,我们可以把要实现的功能划分为多个任务,每个任务负责实现其中的一部分,每个任务都是一个很简单的程序,通常是一个死循环。


  RTOS操作系统:UCOS,FreeRTOS,RTX,RT-Thread,DJYOS等。

  RTOS操作系统的核心内容在于:实时内核。RTOS的内核负责管理所有的任务,内核决定了运行哪个任务,何时停止当前任务切换到其他任务,这个是内核的多任务管理能力。多任务管理给人的感觉就好像芯片有多个CPU,多任务管理实现了CPU资源的最大化利用,多任务管理有助于实现程序的模块化开发,能够实现复杂的实时应用。


  可剥夺内核顾名思义就是可以剥夺其他任务的CPU使用权,它总是运行就绪任务中的优先级最高的那个任务。


定时器管理系统

  对于以上两种系统,前后台系统整个程序运行严格遵守先后顺序,对于有实时性要求的任务无法做到周期性运行。RTOS可以完美得做到,但是开发要求有一定知识基础,对RTOS有一定了解。因此第三种发难应运而生:定时器任务管理系统。


  定时器任务管理系统由定时器中断提供时钟基础,对每个任务进行定时处理。在大多数情况下,可以做到对单个任务周期性运行处理。对一些有实时性要求但是要求不苛刻的场景还是很方便的。


定时器任务管理系统原理

  定时器任务管理系统,通过定时器定时提供一个时间基准。例如定时器1ms中断一次,在中断处理函数中将时间变量累加,就可以得到整个系统运行时间,当时间变量累加到n,就将对应的标志位置1,认为n ms到了,系统检测到标志位为1就执行对应的任务。


时间变量结构体

typedef struct

{

    u8 uCount10ms;

    u8 uCount50ms;

    u8 uCount100ms;

    u8 uCount1000ms;

    u8 uFlag5ms;

    u8 uFlag10ms;

    u8 uFlag50ms;

    u8 uFlag100ms;

    u8 uFlag1000ms;

} TimerDef;


定时器时间基准

  定时器初始化函数:


//定时器初始化

//0.5ms进入中断一次

void TimerInit()

{

    NVIC_InitTypeDef NVIC_InitStructure;

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);


    //enable Time2 gloabal Interrupt

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    TIM_DeInit(TIM2);

    TIM_TimeBaseInitStruct.TIM_Period = 719;   //100KHz  //定时器计数频率=系统时钟/分频系数

    TIM_TimeBaseInitStruct.TIM_Prescaler = 49;  //定时器自动重装载值 //2K // //0.5ms

    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);


    TIM_ClearFlag(TIM2, TIM_FLAG_Update);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);

}


  定时器中断处理:


void TIM2_IRQHandler(void)   //0.5ms

{


    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//判断中断

    {

        TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);//清除中断标志位

        Timer.uCount ++; //时间累积变量 0.5ms累加一次

        if(Update_tim > 0)Update_tim--;//定时器延时,0.5ms减少1,为零时定时到达

    }

}


时间管理

void updateTimerTask(TimerDef *Timer)

{

    if (Timer->uCount >= 10) //0.5*10=5 ms到达

    {

        Timer->uCount = 0;


        Timer->uFlag5ms = 1; //5 ms标志位置1

        Timer->uCount10ms ++;

        Timer->uCount50ms ++;

        Timer->uCount100ms ++;

        Timer->uCount1000ms ++;

    }


    if (Timer->uCount10ms >= 2)//10ms到达

    {

        Timer->uCount10ms = 0;

        Timer->uFlag10ms = 1;

    }

    if (Timer->uCount50ms >= 10)//50ms到达

    {

        Timer->uCount50ms = 0;

        Timer->uFlag50ms = 1;

    }

    if (Timer->uCount100ms >= 20)//100ms到达

    {

        Timer->uCount100ms = 0;

        Timer->uFlag100ms = 1;

    }

    if (Timer->uCount1000ms >= 200)//1000ms到达

    {

        Timer->uCount1000ms = 0;

        Timer->uFlag1000ms = 1;

    }

}


时间任务管理

//大循环任务

void EverWhile_tasks()

{

}

//5ms 任务

void Per_5ms_tasks()

{

    if(Timer.uFlag5ms != 1)//5ms未到达

        return;//退出函数

task1();//用户函数

    Timer.uFlag5ms = 0;//清空5ms标志位

}

//10ms 任务

void Per_10ms_tasks()

{

    if(Timer.uFlag10ms != 1)

        return;

task2();//用户函数

    DIU.Timer.uFlag10ms = 0;

}

//50ms 任务

void Per_50ms_tasks()

{

    if(Timer.uFlag50ms != 1)

        return;

task3();//用户函数

    Timer.uFlag50ms = 0;

}

//100ms 任务

void Per_100ms_tasks()

{

    if(DIU.Timer.uFlag100ms != 1)

  return;

task4();//用户函数

    DIU.Timer.uFlag100ms = 0;// //

}

//1s 任务

void Per_1s_tasks()

{

    if(DIU.Timer.uFlag1000ms != 1)

        return;

task5();//用户函数

DIU.Timer.uFlag1000ms = 0;

}

关键字:STM32  定时器  分时操作系统 引用地址:STM32定时器分时操作系统

上一篇:STM32学习记录之看门狗
下一篇:STM32串口接收数据卡死问题解决办法

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved