栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于STM32F4xx的多任务调用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于STM32F4xx的多任务调用

多任务的意思就是  多个函数可以同时进行使用 创建好函数后直接放到while循环中便可以了。这样的优势是在于 多个任务都需要及时运行 不希望程序卡在某个地方从而导致程序运行缓慢。

同时的意思 其实也不是同时 只是间隔的时间很小 10ms 5ms 甚至us级的也可以。这里我就用了10ms为最低反应的时间。设定好后可以调高但是不能调低。

下面直接上代码 代码有备注 看不懂可以私聊(在线就回)

task.c中的代码

#include "task.h"
#include 



task *MakeTask(void (*name)(void),unsigned int zhouqi)
{
	task *task1;          //在task.h定义的结构体
	task1 = (task *)malloc(sizeof(task) + 10);  //给该指针指向一个堆区地址 函数结束不释放
	task1->hanshu = name;    //指向函数的地址 主函数需要运行的函数
	task1->zhouqi = zhouqi;    //该函数运行的周期
	task1->flag = 0;    //用于第一次运行时候 获取当前时间片的值
	return task1;    //返回该地址
}


void DeleteTask(task * renwu)
{
	free(renwu); //释放堆区地址
}


#include "usart.h"
extern unsigned int time_period;
void TaskRun(task * renwu)
{
	if(renwu->flag == 0)  //第一次运行函数记录 当前时间片的值
	{
		if(time_period >= (0xFFFFFFFF - 100000)) //10s的函数就不可以使用了
		{
			time_period = 0;    
		}
		renwu->starttime = time_period; //记录的时间
		renwu->flag = 1;    //第一次运行函数记录完 改变该变量
	}
	if(renwu->starttime + renwu->zhouqi <= time_period) //如果时间到了 预定的时间 
	{
		renwu->hanshu();    //运行一下该函数
		if(time_period >= (0xFFFFFFFF - 100000)) //10s的函数就不可以使用了
		{
			time_period = 0;
		}
		renwu->starttime = time_period; //再次记录当前时间片的值
	}
}




















task.h

#ifndef _TASK_H_
#define _TASK_H_


#include "stm32f4xx.h"
typedef struct Task
{
	void (*hanshu)(void);
	unsigned int starttime;
	unsigned int zhouqi;
	unsigned char flag;
}task;



task *MakeTask(void (*name)(void),unsigned int zhouqi);

void TaskRun(task * renwu);





#endif







以上是关于任务的代码。代码可见思路

任务的创建和运行要搭配 系统滴答定时器使用 下面是滴答定时器的代码

delay.c

#include "delay.h"
unsigned int time_period;

void SysTick_Init(void)
{
	NVIC_SetPriority(SysTick_IRQn,NVIC_EncodePriority(USART1_IRQn,2,2));
	NVIC_EnableIRQ(SysTick_IRQn);
	
	SysTick->LOAD = 168000 - 1; //1ms   //分频8
	SysTick->CTRL |= (0x01 << 1); //滴答定时器中断使能
	SysTick->CTRL |= (0x01 << 2); //滴答定时器选择时钟源
	
	SysTick->VAL = 0; //定时前 让它重装载
	SysTick->CTRL |= (0x01 << 0); //滴答定时器使能
}



//void DelayNus(unsigned int delay_time)
//{
//	unsigned int current_time;
//	SysTick->VAL = 0; //定时前 让它重装载
//	SysTick->CTRL |= (0x01 << 0); //滴答定时器使能
//	current_time = time_period;
//	while((current_time+ delay_time) != time_period);
//}


void DelayNms(unsigned int delay_time)
{
	unsigned int current_time;
	SysTick->VAL = 0; //定时前 让它重装载
	SysTick->CTRL |= (0x01 << 0); //滴答定时器使能
	current_time = time_period;
	while((current_time+ delay_time) != time_period);
}

void SysTick_Handler(void)
{
  if((SysTick->CTRL & (0x01 << 16)))
	{
		time_period++;                  //在主函数中 初始化一下这个函数 SysTick_Init() 这个值就不断计算 用于获取上电以来的时间 我习惯说是时间片
		SysTick->CTRL &= ~(0x01 << 16);
	}
}

delay.h

#ifndef _DELAY_H_
#define _DELAY_H_


#include "stm32f4xx.h"
#include 

void SysTick_Init(void);
void DelayNus(unsigned int time);
void DelayNms(unsigned int time);







#endif





主函数中调用

创建 任务指针 task * task1,*task2,*task3;

SysTick_Init(); //系统滴答定时器初始化

task1 = MakeTask(haha,1000);   //1s运行一次的函数
task2 = MakeTask(haha1,3000);         //3s运行一次的函数 

task3 = MakeTask(haha2,5000);         //5s运行一次的函数

while循环中用这个

TaskRun(task1);
TaskRun(task2);
TaskRun(task3);

写的不好莫见怪 , 小白而已。欢迎交流。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1022508.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号