STM32基于时间片轮询机制

发布者:太和清音最新更新时间:2022-10-19 来源: csdn关键字:STM32  函数 手机看文章 扫描二维码
随时随地手机看文章

1. 基于时间片的轮询调度算法(仅局限单核CPU芯片):


利用定时器为每个任务函数设定执行时间间隔,保证使用频率高的函数多次被调用,提高单核芯片的资源利用率。如果只是简单地将A、B两个函数放在while中,那么在一定时间内这两个函数调用的次数是一致的,,这样就浪费了单核芯片的资源。


2. 例子:


函数A(100μs执行一次----使用频率高),

函数B(1000μs执行一次----使用频率低)。

那么在1ms 内 函数A 执行了10次,而函数B只执行1次

当然你要保证函数A在100μs内执行完毕、函数B在1000μs内执行完毕

如果超出时间的话系统会变得卡顿。有部分的函数可能没有别执行到。毕竟单核芯片只在很短时间内只做一件事。


3. PS


1、从微观上单核芯片在某一个和短时间时间段只执行一件事。从宏观上 (比如:1S):单核芯片执行多件事情;

2、任务函数最好不要出现delay等延时函数,不然整个系统变得卡顿。


4. 为了更好地理解上述描述,可以结合以下代码理解(基于STM32F103C8T6芯片编写)


API_Schedule.c

#include "API_Schedule.h"

#include "stdlib.h"


/************任务初始化,每一个结构体都代表一个任务,添加任务和删减任务都在这里完成************/

struct TaskStruct TaskST[]=

{

 //  计时   多少ms调用一次    任务运行标志位    任务函数指针

{ 0,       5000,              0,           LedFlash},

{ 0,       1000,              0,    UARTFC},

{ 0,        500,              0,           UserTestMode},

};


/*******************************搭建时间片轮询机制代码框架********************************/


//记录任务数量

u8 TaskCount= sizeof(TaskST)/sizeof(TaskST[0]);


//放在“TIM2_IRQHandler”中断执行,用于任务计时

void OS_IT_RUN(void)

{

u8 i;

for(i=0;i {

if(!TaskST[i].TaskStatus)

{

if(++TaskST[i].TaskTickNow >= TaskST[i].TaskTickMax)//计时,并判断是否到达定时时间

{

TaskST[i].TaskTickNow = 0;

TaskST[i].TaskStatus = 1;

}

}

}

}


//放在main函数中执行,自带死循环,用于执行挂起的任务

void PeachOSRun(void)

{

u8 j=0;

while(1)

{

if(TaskST[j].TaskStatus)//判断一个任务是否被挂起

{

TaskST[j].FC(); //执行该任务函数

TaskST[j].TaskStatus=0; //取消任务的挂起状态

}

if(++j>=TaskCount)//相当于不断循环遍历所有的任务

j=0;

}

}



/*************************计划表中的任务*****************************/

void LedFlash(void)

{

//printf("Led n");//调试用,需要自己添加uart外设后再使用这段代码

}

void UARTFC(void)

{

//printf("UARTFC n");//调试用

}

void UserTestMode(void)

{

//printf("UserTestMode n");//调试用

}


API_Schedule.h

#ifndef __API_SCHEDULE_H__

#define __API_SCHEDULE_H__

#include "stm32f10x.h"


//框架运行所需的函数声明

void PeachOSRun(void);

void OS_IT_RUN(void);


/*

用与存储一个任务运行的数据

*/

struct TaskStruct

{

u16 TaskTickNow;//用于计时

u16 TaskTickMax;//设置计时时间

u8 TaskStatus;//任务运行标志位

void (*FC)();//任务函数指针

};


extern struct TaskStruct TaskST[]; //声明为结构体数据,那样多个任务时方便管理


//用于示例的任务函数声明

void LedFlash(void);

void UARTFC(void);

void UserTestMode(void);

#endif


bsp_time.c

#include "bsp_time.h" 


//中断初始化

void Time2_NVIC_Init()

{

NVIC_InitTypeDef NVIC_InitStruct;

NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_Init(&NVIC_InitStruct);

}


//定时器初始化

void Time2_Init(u16 arr,u16 psr)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period = arr;

TIM_TimeBaseInitStruct.TIM_Prescaler = psr;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter     = 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE);

TIM_Cmd(TIM2, ENABLE);

Time2_NVIC_Init();

}


//定时器中断

void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)

{

OS_IT_RUN();

TIM_ClearITPendingBit(TIM2,TIM_IT_Update);

}

}


bsp_time.h

#ifndef __TIME_H

#define __TIME_H


#include "stm32f10x.h"

#include "API_Schedule.h"


void Time2_Init(u16 arr,u16 psr);


#endif


main.c

#include "stm32f10x.h"

#include "bsp_time.h"

#include "API_Schedule.h"



int main(void)

{

Time2_Init(71,1000);

PeachOSRun();

}


关键字:STM32  函数 引用地址:STM32基于时间片轮询机制

上一篇:STM32F1系列HAL库配置串口通信(2)——串口重定向以及log信息格式输出
下一篇:STM32串口空闲中断的使用

推荐阅读最新更新时间:2024-11-12 10:17

STM32开发笔记75: 使用STM32CubeMX点亮一个LED
今天调试在自己的程序框架下调试RTC始终不成功,只要初始化RTC就进入死机状态。现在重温一下STM32CubeMX的使用方法,看STM32CubeMX生成的程序是否有RTC初始化不成功的问题。本日志从工程的建立讲到点亮一个LED。 1、启动STM32CubeMX,我现在使用的版本是5.2.1。 2、File-New Project,选择相应的芯片类型。 3、双击相应的芯片类型后,进入配置界面。进行SYS配置,选中Debug Serial Wire,由于我习惯于使用FreeRTOS所以在我的项目中Timebase Source都选择定时器。 4、进行RCC设置。 5、时钟设置如下:
[单片机]
<font color='red'>STM32</font>开发笔记75: 使用STM32CubeMX点亮一个LED
STM32通用定时器(TIM2-5)基本用法
STM32的定时器是个强大的模块,定时器使用的频率也是很高的,定时器可以做一些基本的定时,还可以做PWM输出或者输入捕获功能。从系统框架图下看,名为TIMx的有八个,其中TIM1和TIM8挂在APB2总线上,而TIM2-TIM7则挂在APB1总线上。其中TIM1&TIM8称为高级控制定时器(advanced control timer).他们所在的APB2总线也比APB1总线要好。APB2可以工作在72MHz下,而APB1最大是36MHz。 由上图可知,当APB1 的预分频系数为1 时,这个倍频器不起作用,定时器的时钟频率等于APB1 的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8 或16)时,这个
[单片机]
<font color='red'>STM32</font>通用定时器(TIM2-5)基本用法
STM32寄存器的简介、地址查找,与直接操作寄存器
什么是寄存器 提到单片机,就不得不提到寄存器。根据百度百科介绍,寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。   简单来说,寄存器就是存放东西的东西。从名字来看,跟火车站寄存行李的地方好像是有关系的。只不过火车站行李寄存处,存放的行李;寄存器可能存放的是指令、数据或地址。   存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同
[单片机]
<font color='red'>STM32</font>寄存器的简介、地址查找,与直接操作寄存器
STM32一个定时器输出不同频率
1个定时器输出4路频率相同,占空比不同的PWM比较容易实现,只需要改变每个通道的比较值就可以了 要想输出频率不同,占空比相同,需要用到比较模式,当比较成功IO翻转。 同时还需要用到定时器中断去重新设置比较值。 稍微解释下面语句: Period是计数值 prescaler是对总线时钟的分频 这个函数是设置比较值 基本要点是理解上面这些。没接触过定时器的会比较抽象,不能理解。 下面直接上代码吧 定时器初始化: u16 capture = 0; vu16 CCR1_Val = 32768; vu16 CCR2_Val = 16384; vu16 CCR3_Val = 8192; vu16 CCR4
[单片机]
<font color='red'>STM32</font>一个定时器输出不同频率
STM32学习笔记一:选型与引脚说明
选型分类 STM32命名方法 如何分配原理图引脚 如何寺找引脚的功能说明 引脚功能解读
[单片机]
<font color='red'>STM32</font>学习笔记一:选型与引脚说明
UC_COS移植到STM32
1 在外设篇里面的点亮液晶屏(17)的基础上移植液晶屏 1 下载GUI解压放到工程的根目录下 图片1 2 将GUI里面的文件夹全部添加到工程文件里面。 图片2 3 把GUI里面每个文件夹里面的文件加入到工程。 1 在添加Config的时候,因为Config里面都是头文件所以需要选择Allfile文件类型然后在选择全部文件添加。 2 字体先不添加,以后编译的时候需要那个字体在添加那个字体。 3 添加不带操作系统的延时函数文件GUI_X.c 4 添加图片文件的时候JPGE文件夹下面还有两个文件夹DOC和Image不需要添加,只需要添加JPGE下面的点C文件。 5 液晶屏驱动文件LCDDriver下面的文件先不
[单片机]
UC_COS移植到<font color='red'>STM32</font>
stm32学习之十
USART,AD与GPIO的温度传感器: 注意的是: 1、ADC_RegularChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5); 2、ADC_TempSensorVrefintCmd(ENABLE); 依照上一节的程序,可以改写以下,形成现在的程序与效果: add.h和add.h(写成这种方式,原因与上一节一样) add.h的代码: #ifndef _ADD_H #define _ADD_H #include stm32f10x.h //对于12位的ADC,3.3V的ADC值为0xfff,温度为25度时对应的电压值为1.43V即0
[单片机]
<font color='red'>stm32</font>学习之十
stm32 mmc卡写文件然后读出来 串口输出
硬件环境:神州一号板 软件环境:MDK 1、sd卡硬件初始化 PA5---------CLK PA6---------MISO PA7---------MOSI PB7---------CS void TurnToSD(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_A
[单片机]
<font color='red'>stm32</font> mmc卡写文件然后读出来 串口输出
小广播
设计资源 培训 开发板 精华推荐

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

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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