单片机无操作系统 多任务 无延时架构

edanLee edanLee 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
两年前一直在用前后台的方式编程。后来越来越不爽。觉得有些任务不能及时处理,或者代码会很乱。另外在程序中有很多delay()。在delay的时候CPU基本不做事,很浪费。

于是乎就想到多任务。第一个想到的就是ucos,但是这个东西不太适合用在资源有限的单片机上。很纠结。但是看过ucos之后对它的任务处理方式有一定的认识。然后就想得用它的理念放在单片机上。

在处理delay的时候想到让cpu跳出正在执行的任务去做其它的事情。在没有处理堆栈的时候要怎么做呢?用全局变量来保存任务的关键信息,用switch将任务分成N个小任务,任务之前用一个全局变量来联接。其实就是个状态机的思想。每遇到 一个需要等待的地方就作为一个小任务的结束。在下个小任务去判断是不是应该往下执行。

几个大的任务放在一个大循环里,一次循环下来,每个大的任务只会被执行一小段。有点想系统里面的时间片的概念了。合作式的高度器。

delay的事还没有完,要准确延时的地方要用定时器才可以。有很多个任务,硬件定器只用有限的几个,那怎么搞~?汲取了别人的经验就用了软件定时器,一个任务配一个。

如此一个多任务,无延时(长延时)的架构就出来了。 和高手们的架构有很多的差距,请高手拍砖;

软件定时器:

u16 times[ x];

硬件定时器中断()
{
for(i = 0; i < x;i++)
{
if(0 != times[i] )
{
times[i]--;
}
}
}

任务分割:

void pro0(void)
{
static u8 step = 0; //状态机

switch(step)
{
case 0:
.........
times[0] = 200; //延时准备
step++; //状态转换
break; //跳出程序

case 1:
if(0 != times[0]) //检测延时是否到
{
break;
} //延时到则继续执行
......
step++; //状态转换
break;

case 2:
............
step = 0; //状态复位
break;
}
}

void pro1(void)
{
static u8 step = 0;

if(0 != times[0]) //在程序头检测延时是否到
{
return;
}
switch(step)
{
case 0:

break;
......
}
}

主函数:

void main(void)
{
IO初始化;
其它初始化;
定时器初始化;
中断初始化;
开全局中断;

while(1)
{
pro0();
pro1();
.其它任务
}
}
...全文

相关推荐

评论 19
收藏 已收藏
分享
返回顶部
edanLee
单片机/工控 27,522 成员 28,796 内容