51多任务系统,可以运行
时间:2022-07-24
本文章向大家介绍51多任务系统,可以运行,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
根据网上的资料,采用定时器2自动装载模式。每10ms进一次中断。
图中可以看出,调用rtos_wait(100)后,PC=PC+3=0x0163,SP=SP+2;把PC值压栈,可以参考LCALL addr16这条汇编指令
PC是16位,所以需要两个8位的空间,因此SP需要加2。
/*
使用keil4
可运行8个任务
任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来。
使用定时器2作为系统始终
*/
#include <regx52.H>
#include <INTRINS.H>
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;
//两个宏定义是为了保护现场,不被定时中断打乱。
//主要用于需要一次性运行完毕的代码中。
#define OPEN_SYS_ISR() {EA=1;TR2=1;}
#define CLOSE_SYS_ISR() {EA=0;TR2=0;TF2=0;}
//#define TIMER_RELOAD() {TL0=0xF0;TH0=0xD8;} //使能T/C 初始10ms
#define MAX_TASKS 2 //任务槽最大个数.
//任务堆栈. PC指针为16位,需2个字节task_stack[][0]L task_stack[][1]H。
u8 idata task_stack[MAX_TASKS][2];
//定时时间 (0-255)*10ms
u8 idata task_time[MAX_TASKS];
//当前活动任务号
u8 task_id = 0;
/*******************************************************************************
* 函 数 名 : Timer2 Init
* 函数功能 : 定时器0初始化,用于系统时钟
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void timer2_init()
{
RCAP2H = (0xFFFF - 10000) / 256;
RCAP2L = (0xFFFF - 10000) % 256; //12MHz晶振下定10ms,自动重装
TH2 = RCAP2H;
TL2 = RCAP2L; //定时器2赋初值
T2CON = 0; //配置定时器2控制寄存器,这里其实不用配置,T2CON上电默认就是0,这里赋值只是为了演示这个寄存器的配置
T2MOD = 0; //配置定时器2工作模式寄存器,这里其实不用配置,T2MOD上电默认就是0,这里赋值只是为了演示这个寄存器的配置
IE = 0xA0; //1010 0000开总中断,开外定时器2中断,可按位操作:EA=1; ET2=1;
TR2 = 1; //启动定时器2
}
void rtos_wait(u8 time)
{
static u8 i;
task_time[task_id] = time; //保存当前任务时间
//保存当前断点 并把SP=SP-2,任务切换到下一任务;
task_stack[task_id][1] = *((u8 data*) SP);
SP--;
task_stack[task_id][0] = *((u8 data*) SP);
SP--;
//任务号设为最大,越过最大则回到0
for (i = 0; i < MAX_TASKS; i++)
{
if (task_time[i] == 0) //根据定时时间判断
{
task_id = i;
break;
}
}
}
void task_sw() //任务时间是否到,任务时间到 实时切换回
{
//从把定时时间减1 ,找看哪个任务到 ,任务时间到 实时切换回
static u8 i;
for (i = 0; i < MAX_TASKS; i++)
{
if (task_time[i]) //time[0] = 10 if(10)
{
task_time[i]--; //10--
if (task_time[i] == 0) //多个定时时间同时到,任务越靠后,越优先执行。
{
task_id = i; //当前任务号
//保存的PC指针调出来
SP++;
(*((u8 data*)(SP))) = task_stack[i][0];
SP++;
(*((u8 data*)(SP))) = task_stack[i][1] ;
}
}
}
}
void tm2_isr() interrupt 5 //using 1
{
//EA=0;
//ET2=0;
//TF2=0;
//!!!注意!!!定时器2必须由软件对溢出标志位清零,TF2=0;硬件不能清零,
//这里与定时器0和定时器1不同!!!
CLOSE_SYS_ISR();
task_sw(); //任务时间是否到,任务时间到,则实时切换回
OPEN_SYS_ISR();
}
//****************************************************************示例
void task_test()
{
while (1)
{
LED1 = ~LED1;
rtos_wait(100); //1sec 执行完后,记录下一步地址,返回
}
}
void task_test2()
{
while (1)
{
LED2 = ~LED2;
rtos_wait(200); //2sec 执行完后,记录下一步地址,返回
}
}
void sys_init()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
void main()
{
sys_init();
timer2_init();
/* while(1)
{
task_test();
task_test2();
} */
task_test();
task_test2();
while (1);
}
- 通过自定义配置实现插件式设计
- 让IoC动态解析自定义配置(提供基于Unity的实现)
- 如何让ASP.NET默认的资源编程方式支持非.ResX资源存储
- 在VS中通过建立依赖关系使文件结构更清晰
- 一个关于ConfigurationManager.GetSecion方法的小问题
- 追踪记录每笔业务操作数据改变的利器——SQLCDC
- 一个完整的用于追踪数据改变的解决方案
- C# 4.0新特性-"协变"与"逆变"以及背后的编程思想
- 通过内存分析工具来证明字符串驻留机制
- 如果在BackgroundWorker运行过程中关闭窗体…
- 从数据到代码——基于T4的代码生成方式
- 解决T4模板的程序集引用的五种方案
- 编写T4模板进行代码生成无法避免的两个话题:"Assembly Locking"&"Debug"
- 从yield关键字看IEnumerable和Collection的区别
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 自我加戏,在自闭的边缘尝试高可用的Eureka
- 视频直播系统源码,图片叠加
- SpringCloud初体验--Hello Eureka
- Android自定义View实现水平带数字百分比进度条
- AndResGuard编译速度优化
- Android自定义带拼音音调Textview
- Android仿音乐播放器带进度的播放暂停按钮
- 一个比较自闭的SpringIOC问题
- 我在大厂写React,学到了什么?
- leetcode(4)寻找正序数组中位数
- jvm源码解析(二)HashMap
- 硬件笔记(23)---- PCB的保护走线
- TabLayout+ViewPager实现切页的示例代码
- jvm源码分析(四)ThreadPoolExecutor
- python zip,lambda,map函数代码实例