【51单片机】

51单片机任务调度与中断处理
本文介绍了一种51单片机的任务调度系统,通过定义任务结构体和周期,实现了任务的创建、事件发布和更新。在中断处理函数中,实现了任务的查询和调度,确保各个任务按周期运行。同时,提供了硬件复位和IO控制的示例代码。

#include <reg51.h>              //51 单片机头文件

#define GPIO0_CONCTRON P0              // 定义 IO

#define GPIO1_CONCTRON P1

#define GPIO2_CONCTRON P2

#define GPIO3_CONCTRON P3

#define true 1

#define flase 0

#define MaxTask 3               // 总任务数

#define Task_one 0               // 任务 0

#define Task_two 1               // 任务 1

#define Task_three 2               // 任务 2

#define Task_one_Period 100               // 任务 0 的挂起周期 // 也就是说 它过了这个时间再运行

#define Task_two_Period 4000               // 任务 0 的挂起周期

#define Task_three_Period 70               // 任务 0 的挂起周期

int count = 0;

typedef struct               // 结构体

{

unsigned int wTaskPeriod;               // 运行周期

unsigned int wTaskCount;              // 运行周期计数器

unsigned int wEvent;              // 任务信号

}OSTCB;

OSTCB OS_TCB[MaxTask];

void OS_Create_Task(unsigned int mTaskPro,unsigned int mTaskPreiod)              // 创建任务第一个参数 任务 ID 号 第二个参数 任务运行周期

{

OS_TCB[mTaskPro].wTaskPeriod= mTaskPreiod;              // 把任务运行周期加载到  TCB 结构体

}

void OS_Event_Post(unsigned char mTask,unsigned int mEvent)             // 任务信号邮箱

{

OS_TCB[mTask].wEvent =( 1<<mEvent);

}

void OS_Updata_Task(void)             // 任务加载

{

int mTemp;

for(mTemp = 0;mTemp < MaxTask;mTemp ++)              // 查询三个任务,

{

OS_TCB[mTemp].wTaskCount ++;

if(OS_TCB[mTemp].wTaskCount == OS_TCB[mTemp].wTaskPeriod)             // 如果运行周期计数器 = 运行周期 则任务发送信号量 说明改任务要运行了

{

OS_TCB[mTemp].wTaskCount = 0;

OS_Event_Post(mTemp,mTemp);             // 第一个参数任务 ID 号 第二个参数 任务信号量

}

}

}

void OS_Task_Int(void)             // 任务初始化

{

unsigned char mTemp;

for(mTemp = 0;mTemp < MaxTask;mTemp ++)

{

OS_TCB[mTemp].wTaskPeriod = 0;

OS_TCB[mTemp].wTaskCount = 0;

OS_TCB[mTemp].wEvent = 0;

}

}

unsigned int OS_Event_Pend(unsigned char mTask)             // 发送任务邮箱

{

unsigned int mTaskEvent;            // 发送这个任务的信号量

mTaskEvent = OS_TCB[mTask].wEvent;

OS_TCB[mTask].wEvent &=~mTaskEvent;             // 运行完后就清这个任务的信号量

return mTaskEvent;

}

void Int_Hardware(void)            //51 单片机复位

{

GPIO0_CONCTRON = 0xff;

GPIO1_CONCTRON = 0x01;

GPIO2_CONCTRON = 0xff;

GPIO3_CONCTRON = 0xff;

}

void Task1(void)            // 任务 1 运行函数

{

unsigned int GetEvent;

while(1)

{

GetEvent = OS_Event_Pend(Task_one);

if(GetEvent == 0)

{

return;

}

if(GetEvent &(1<<Task_one))

{

GPIO0_CONCTRON = ~GPIO0_CONCTRON;

}

}

}

void Task2(void)            // 任务 2 行函数

{

unsigned int GetEvent;

while(1)

{

GetEvent = OS_Event_Pend(Task_two);

if(GetEvent == 0)

{

return;

}

if(GetEvent & (1<<Task_two))

{

GPIO1_CONCTRON = ~GPIO1_CONCTRON;

}

}

}

void Task3(void)           // 任务 3 行函数

{

unsigned int GetEvent;           // 获取信号量

while(1)

{

GetEvent = OS_Event_Pend(Task_three);          // 查任务是否运行完 返回信号量

if(GetEvent == 0)          // 如任务运行完成任务挂起,等待下次运行

{

return;

}

if(GetEvent & (1<<Task_three))          // 有任务在运行,就运行这个任务

{

GPIO2_CONCTRON = ~GPIO2_CONCTRON;          // 单片机 IO 取反

}

}

}

void OS_start(void)          // 任务开始

{

while(1)

{

Task1();

Task2();

Task3();

}

}

void main(void)

{

IE = 0x82;          // 开中断

TMOD = 0x01;

TH0 = (65536-1)/256;

TL0 = (65536-1)%256;

TR0 = 1;           // 开定时器

Int_Hardware();           // 硬件复位

OS_Task_Int();          // 任务初始化

while(1)

{

OS_Create_Task(Task_one,Task_one_Period);           // 在 TCB 结构体里任务加载下面 3 个任务

OS_Create_Task(Task_two,Task_two_Period);

OS_Create_Task(Task_three,Task_three_Period);

OS_start();

}

}

void inter(void) interrupt 1           // 任务毫秒 查循一次进行任务调度

{

TH0 = (65536-1)/256;

TL0 = (65536-1)%256;

OS_Updata_Task();          // 任务查询,更新 和 发送

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值