目前共有4篇帖子。 字體大小:較小 - 100% (默認)▼  內容轉換:台灣正體▼
 
點擊 回復
740 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)
 

本帖信息

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