目前共有4篇帖子。 內容轉換:不轉換▼
 
點擊 回復
540 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)
 

本帖信息

點擊數:540 回複數:3
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2017-1-29 10:03
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。