2758|8

6960

帖子

11

TA的资源

版主

楼主
 

【国民技术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();
  }
}

编译下载之后运行如下面视频。总之,这个非常好的任务系统短小精练。是学习任务创建的好示例。这里要感谢原子哥熊家余老师详细的讲解。

任务系统

 

最新回复

整体挺简单的,可以减下来抄一抄。   详情 回复 发表于 2022-9-7 16:08
点赞(1) 关注(3)
 
 

回复
举报

6450

帖子

10

TA的资源

版主

沙发
 

其实感觉不管是系统还是状态机,对于单核的MCU来说本质感觉是一样的,只是实现方式不同,通过状态去执行,总之就是不要在while中加延时等待

点评

原理都是一样的吧,这个感觉我接触到比较好用的一个,在这里推存一下,而且适用不同的单片机,可以说移植非常方便。  详情 回复 发表于 2022-9-5 16:06
 
 
 

回复

6960

帖子

11

TA的资源

版主

板凳
 
秦天qintian0303 发表于 2022-9-5 15:58 其实感觉不管是系统还是状态机,对于单核的MCU来说本质感觉是一样的,只是实现方式不同,通过状态去执行, ...

原理都是一样的吧,这个感觉我接触到比较好用的一个,在这里推存一下,而且适用不同的单片机,可以说移植非常方便。

点评

都说面向对象的需要编程最方便,对于面向过程的编程其差异性最明显,有个能普适的确实方便很多,大佬真是涉猎颇丰啊  详情 回复 发表于 2022-9-5 16:21
 
 
 

回复

6450

帖子

10

TA的资源

版主

4
 
lugl4313820 发表于 2022-9-5 16:06 原理都是一样的吧,这个感觉我接触到比较好用的一个,在这里推存一下,而且适用不同的单片机,可以说移植 ...

都说面向对象的需要编程最方便,对于面向过程的编程其差异性最明显,有个能普适的确实方便很多,大佬真是涉猎颇丰啊

点评

过奖了。。。  详情 回复 发表于 2022-9-5 17:41
 
 
 

回复

6960

帖子

11

TA的资源

版主

5
 
秦天qintian0303 发表于 2022-9-5 16:21 都说面向对象的需要编程最方便,对于面向过程的编程其差异性最明显,有个能普适的确实方便很多,大佬真是 ...

过奖了。。。

 
 
 

回复

2933

帖子

4

TA的资源

五彩晶圆(中级)

6
 

没有看到任务切换怎么实现的,要是操作系统那就好解释了

点评

任任轮询来实现的。这个是简单的任务切换,没有底层操作,实现不了复杂的操作。  详情 回复 发表于 2022-9-6 11:55
 
 
 

回复

6960

帖子

11

TA的资源

版主

7
 
bigbat 发表于 2022-9-6 09:36 没有看到任务切换怎么实现的,要是操作系统那就好解释了

任任轮询来实现的。这个是简单的任务切换,没有底层操作,实现不了复杂的操作。

 
 
 

回复

7158

帖子

2

TA的资源

版主

8
 

这就有点像微小型的系统,等于拿了操作系统的一小部分。
不过N32G430应该是支持RTThread的吧~

 
 
 

回复

7608

帖子

18

TA的资源

五彩晶圆(高级)

9
 

整体挺简单的,可以减下来抄一抄。

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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