【国民技术N32G430】4、做一个简单好用的多任务调度系统
[复制链接]
【国民技术N32G430】3、定时器 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)
【目的】早先学习单片机,延时都是用while来阻寒实现的,也没有任务调度系统等等,后来因为是需要协调几个外设,后来才学习状态机,再后面又接触的象freeRTos,RT-hread操作系。这次我在学习迪文屏的51编程中,学习到一个非常简单实用的多任务调度系统,今天把它移杆到N32F430这里来。用来加深对任务创建、调度、删除的印象。
1、继上篇定时器的创建,先新建一个task.c文件,文件如下:
#include "task.h"
#include <string.h>
#include "main.h"
typedef struct{
u32 countdown;
u32 interval;
TASK_FUNC func_cb;
u8 sta;
}TASK;
#define TASK_STA_IDLE 0x00 //空闲
#define TASK_STA_WAIT 0x01 //等待
#define TASK_TABLE_LEN 8
static TASK task_table[TASK_TABLE_LEN];
static double cur_tick,last_tick,elapsed_tick;
static u16 task_id;
void task_init()
{
cur_tick = 0;
last_tick = 0;
memset((void*)task_table,0,sizeof(task_table));
}
void task_tick(void)
{
cur_tick +=1;
}
//返回任务id,从1开始的,0代表失败
u16 task_create(u32 countdown, u32 interval, TASK_FUNC func_cb)
{
u16 i;
for(i=0; i<TASK_TABLE_LEN; i++)
{
if(task_table[i].sta == TASK_STA_IDLE)
{
task_table[i].countdown = countdown;
task_table[i].interval = interval;
task_table[i].func_cb = func_cb;
task_table[i].sta = TASK_STA_WAIT;
return i+1;
}
}
return 0; //创建失败
}
void task_delete(u16 id)
{
if(id>=1 && id<= TASK_TABLE_LEN)
{
id--;
task_table[id].countdown = 0;
task_table[id].interval = 0;
task_table[id].func_cb = 0;
task_table[id].sta = TASK_STA_IDLE;
}
}
void task_handler(void)
{
elapsed_tick = cur_tick - last_tick;//获得时间差
last_tick = cur_tick;
for(task_id = 0; task_id < TASK_TABLE_LEN; task_id ++)
{
if(task_table[task_id].countdown == 0)
continue;
if(task_table[task_id].countdown>elapsed_tick)
{
task_table[task_id].countdown -= elapsed_tick;
}
else{
task_table[task_id].countdown = 0;
}
if((task_table[task_id].countdown == 0) && (task_table[task_id].sta == TASK_STA_WAIT))
{
if(task_table[task_id].func_cb)
task_table[task_id].func_cb();
if(task_table[task_id].interval)
task_table[task_id].countdown = task_table[task_id].interval;
else
task_table[task_id].sta = TASK_STA_IDLE;
}
}
}
2、头文件:task.h:
#ifndef __TASK_H__
#define __TASK_H__
#include "main.h"
//变量申明
typedef void (*TASK_FUNC)(void);
void task_init(void);
void task_tick(void);
u16 task_create(u32 countdown, u32 interval, TASK_FUNC func_cb);
void task_delete(u16 id);
void task_handler(void);
#endif
3、把GPIOdemo的三个文件包话进来:
#include "bsp_led.h" //led驱动
#include "bsp_delay.h" //延时函数
#include "task.h" //任务调度
#include "log.h" //打印函数
4、main主函数:
#include "main.h"
#include "task.h"
u16 task1_id,task2_id;
u16 num1,num2;
//任务1
void task1()
{
num1++;
printf("hellow task1 num:%d\r\n",num1);
if(num1>20)
task_delete(task1_id);
}
//任务2
void task2()
{
num2 += 2;
printf("hellow task2 num2:%d\r\n",num2);
if(num2>30)
task_delete(task2_id);
}
/**
*\*\brief Main program
**/
int main(void)
{
log_init();
time6_init();
task_init();
num1 = num2 = 0;
task1_id = task_create(1000,1000,task1); //创建任务1
task2_id = task_create(1000,1000,task2); //创建任务2
while(1)
{
task_handler();
}
}
编译下载之后运行如下面视频。总之,这个非常好的任务系统短小精练。是学习任务创建的好示例。这里要感谢原子哥熊家余老师详细的讲解。
任务系统
|