目前共有4篇帖子。 内容转换:不转换▼
 
点击 回复
765 3
【程序】51单片机手动切换方式的多任务
一派护法 十九级
1楼 发表于:2017-1-29 09:57

#include <at89x52.h>


#define MAX_TASKS 2 // 最大任务数
#define MAX_TASK_DEP 12 // 每个任务的栈容量
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP]; // 任务栈
unsigned char idata task_sp[MAX_TASKS]; // 每个任务的运行位置
unsigned char task_id = 0; // 当前任务号


sbit LED = P1^4;
sbit LED2 = P1^5;


// 任务装入函数
void task_load(unsigned int fn, unsigned char tid)
{
    task_sp[tid] = (unsigned char)&task_stack[tid][1];
    task_stack[tid][0] = fn & 0xff;
    task_stack[tid][1] = fn >> 8;
}


// 任务切换函数
void task_switch(void)
{
    task_sp[task_id] = SP;
    if (++task_id == MAX_TASKS)
        task_id = 0;
    SP = task_sp[task_id];
}


void delay(unsigned char n)
{
    char i;
    while (n--)
        for (i = 0; i < 115; i++);
}


void task1(void)
{
    while (1)
    {
        LED = 0;
        delay(500);
        LED = 1;
        delay(500);
       
        task_switch();
    }
}


void task2(void)
{
    while (1)
    {
        LED2 = 0;
        delay(500);
        LED2 = 1;
        delay(500);
       
        task_switch();
    }
}


int main(void)
{
    task_load(task1, 0);
    task_load(task2, 1);
    SP = task_sp[task_id];
    return 0;
}

一派护法 十九级
2楼 发表于:2017-1-29 10:00
注意:任务装载函数中不能直接用unsigned int指针赋值,一次性访问16个字节,否则[0]和[1]中的内容是反的,也就是[0]里面装的是高位(fn>>8),[1]里面装的却是低位(fn&0xff),需要交换回来:
void task_load(unsigned int fn, unsigned char tid)
{
    unsigned char temp;
    task_sp[tid] = (unsigned char)&task_stack[tid][1];
    *(unsigned int *)task_stack[tid] = fn;
    temp = task_stack[tid][0];
    task_stack[tid][0] = task_stack[tid][1];
    task_stack[tid][1] = temp;
}
一派护法 十九级
3楼 发表于:2017-1-29 10:02
另外,main函数里面的return 0也不能去掉或换成while(1),否则单片机不会切换到SP所指向的函数地址。
一派护法 十九级
4楼 发表于:2017-1-29 10:03

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:765 回复数:3
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2017-1-29 10:03
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。