多任务 51单片机纯C语言内核V1.03

发布者:chaxue1987最新更新时间:2020-04-27 来源: eefocus关键字:多任务  51单片机  纯C语言  内核V1 手机看文章 扫描二维码
随时随地手机看文章

#include


#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long


/*

Task_creat(1),Task_creat(2),Task_creat(3)

[task1][task2][task3][idel]...

...

Task_destroy(2)

[task1][idel][task3][idel]...

...

Task_destroy(1)

[idel][idel][task3][idel]...

...

Task_creat(4)

[task4][idel][task3][idel]...

//----------------------------------------------

TaskOrder[i]<->TaskCounter[i]<->TaskCountValue[i]

*/


#define TASKNUM 10 //任务空间

#define TASKREALNUM 9

#define STACKLENGTH 10

//---------------------------------------

uchar TaskCharge = TASKNUM;

uchar TaskNowRuning = 0;

//函数调用原型


uchar TaskOrder [TASKNUM] = {0};  //任务表

uchar TaskCounter [TASKNUM] = {0};

uchar TaskCountValue [TASKNUM] = {0};

uchar TaskPriority [TASKNUM] = {0};


uchar TaskStack [STACKLENGTH] = {0}; //任务栈

uchar TaskStackHead;

uchar TaskStackEnd;


struct flag

{

 uchar TaskFinish :1;

};

struct flag SysBit;

//-----------------调试用---------------------

uint Timerlengh;

uint Timerlenghhigh;

uint Timerlenghlow;

/*

ulong SysCounter;

ulong SysCountShow;

uint SysOnems;

*/


//---------------------------------------    

void Core_ini (void);

void Idel (void);

void Task_creat (uchar task_id,uchar task_count,uchar task_pri);

void Task_destory (uchar task_id);

//---------------------------------------

void Idle (void)

{}


void Core_ini (void)

{

 TaskLib[0] = &Idle;

 TaskLib[1] = &f1;

 TaskLib[2] = &f2;

 TaskLib[3] = &f3;

 TaskLib[4] = &f4;

 TaskLib[5] = &f5;

 TaskLib[6] = &f6;

 TaskLib[7] = &f7;

 TaskLib[8] = &f8;

 TaskLib[9] = &f9;


 TaskOrder [0] = 0;    //生成系统任务task0

 

 TaskStackHead = 0;

 TaskStackEnd = 0;

 

 SysBit.TaskFinish = 0;

//-----------------------------------------------

 Timerlengh = 0;

 Timerlenghhigh = 0;

 Timerlenghlow = 0xffff;

/*

 SysCounter = 0;

 SysCountShow = 0;

 SysOnems = 0;

*/ 

}

//-------------------------------------------------

void Task_creat (uchar task_id,uchar task_count,uchar task_pri)

{

 uchar i;

 uchar taskseat;

 i = 1;

 taskseat = 0;

            

 while (taskseat == 0)

 {  

  if (TaskOrder[i] == 0)

  {

   TaskOrder[i] = task_id;   //任务生成

   TaskPriority [i] = task_pri;

   TaskCounter[i] = 0;

   TaskCountValue[i] += task_count;

   taskseat = 1;

  }

  else

  {

   if (i < TASKREALNUM)

   {

    i++;

   }

   else

   {

    taskseat = 1;  //无空位

   }

  }

 }

}


 


void Task_destory (uchar task_id)

{

 uchar i;

 uchar taskaway;

 i = 1;

 taskaway = 0;


 while (taskaway == 0)

 {  

  if (TaskOrder[i] == task_id)

  {

   TaskOrder[i] = 0;   //任务删除

   TaskPriority [i] = 0;

   TaskCounter[i] = 0;

   TaskCountValue[i] = 0;

   taskaway = 1;

  }

  else

  {

   if (i < TASKREALNUM)

   {

    i++;

   }

   else

   {

    taskaway = 1;  //无空位

   }

  }

 } 

}


 


void WatchDog (void)

{}


 


#define timeH 0xfc

#define timeL 0x17 //1ms减去入栈误差


 


void timer0_ini (void)

{

 TMOD = 0x01;

   TH0 = timeH;

   TL0 = timeL;

   TR0 = 1;

   ET0 = 1;

   EA = 1;

}


 


void timer0 (void) interrupt 1

{

 uchar i;

 TR0 = 0;

 TL0 = timeL;

 TH0 = timeH;

 TR0 = 1;

//---------------------watchdog更新--------------------

//---------------------计数维护---------------------------  

....

//-------------------优先级排序(倒排序)----------------- 

....

//------------------------任务出栈------------------------   

....

//-------------------------调试用--------------------------

 Timerlengh = (TH0 * 256 + TL0) - 0xfc17;

 if (Timerlenghhigh < Timerlengh)

 {

  Timerlenghhigh = Timerlengh;

 }

 if (Timerlenghlow > Timerlengh)

 {

  Timerlenghlow = Timerlengh;

 }

}


 


void main (void)

 SP = 0x70;

 Core_ini ();

//----------------------------

 Task_creat (1,10,1);

 Task_creat (2,10,2);

 Task_creat (3,10,3);

 Task_creat (4,10,4);

 Task_creat (5,10,5);

 Task_creat (6,10,6);

 Task_creat (7,10,7);

 Task_creat (8,10,8);

 Task_creat (9,10,9);

// Task_destory (4);

 timer0_ini ();

 WatchDog ();

//------------------------------------

 for ( ; ; )

 {

//函数调用原型

  SysBit.TaskFinish = 1;

  while (SysBit.TaskFinish)

  {

//   SysCounter++;

  }

//------------------------------------ 

 }

}


特点:


1.时间片轮转调度


2.多任务


3.优先级并发控制


4.内核消耗小


5.任务任意载入删除


6.实时性强

关键字:多任务  51单片机  纯C语言  内核V1 引用地址:多任务 51单片机纯C语言内核V1.03

上一篇:简单的51单片机多任务操作系统(C51)
下一篇:pc上用C语言模拟51多任务的案例程序

推荐阅读最新更新时间:2024-11-20 17:32

如何快速零基础到入门51单片机(二)
此讲我们主要介绍如何安装Keil5与STC-ISP 一 Keil5软件一共有许多版本,我们现在学的是51单片机所以我们要选择C51这个版本。(建议使用破解版) 华维单片机编程:免费领!单片机入门到高级开挂学习路径(附教程+工具) 37 赞同 · 8 评论 文章 破解版使用方法:先打开Keil_Lic.exe,然后进入Keil软件时不能双击进入,要先点击鼠标右键,选择以管理员的身份进入. 点击File然后选中License Management(许可证管理),把CID中的内容复制下来,填入Keil_Lic.exe中的CID处,点击生成按钮,然后把生成的代码复制,退出Keil_Lic.exe,回到K
[单片机]
如何快速零基础到入门<font color='red'>51单片机</font>(二)
51单片机是什么_51单片机入门自学
  51单片机是什么   51单片机是对所有兼容Intel8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flashrom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。   51单片机入门自学   作为一个初学者,如何51单片机入门?   实际上,其实不需要多少东西,会简单的C语言,知道51单片机的基本结构就可以了。
[单片机]
基于51单片机多功能太阳能路灯的设计与实现
    随着社会发展的步伐日益加快,人们对新型能源地开发利用程度不断加大,太阳能作为一种新型能源,越来越受到人们的重视,合理有效的利用好太阳能,已逐步成为节能环保的一种趋势。西藏太阳能资源居中国首位,也是世界上最丰富的地区之一,全年平均日照时数在3 000小时左右。因此为了更环保、更加节能,合理有效地利用太阳能,我们设计出一款多功能太阳能路灯。文中采用C8051F020作为主控芯片,通过51单片机控制片内高速AD对紫外线传感器、温度传感器、光照度传感器等进行采样,对拉萨环境进行监测(特别是紫外线强度的监测),相关数据参数经过LCD显示,用户可通过需要显示广告信息,如进行公益广告,商业广告相关信息的宣传;同时利用具有高效节能的LED
[电源管理]
基于<font color='red'>51单片机</font>多功能太阳能路灯的设计与实现
基于8051单片机的超声波发生器设计方案
本设计的超声波发生器是利用单片机生成初始信号,然后经过一系列处理电路的作用后生成用来杀灭水蚤的超声波,成本低、效果好,可以在农业上加以采用。在此对3个模块进行设计:   (1)信号发生模块。12 MHz的8051单片机硬件连接及其程序设计。   (2)信号处理模块。驱动电路设计(CD4069非门集成芯片);倍频电路设计(S9014或ECGl08三极管、104普通电容、11 257.9 nH自制电感、1 kΩ电阻);整波电路设计(CD4069非门集成芯片);和频电路设计(CD4081与门集成芯片);选频电路设计(S9014或ECGl08三极管、104普通电容、112.58 nH自制电感、1 kΩ电阻)。   (3)信号检
[单片机]
KST51单片机:通过中断实现矩阵按键的次数检测与消抖
以Key4为例,使用定时中断2ms进行消抖,对连续8次(16ms)的按键状态进行判断. 如果全部为1则弹起,将按键当前状态(Keysta)为1; 全部为0则按下,将按键当前状态(Keysta)置0; 其余状态都为抖动,按键当前状态不变。 在主程序里对按键状态进行判断,如果按键当前状态(Keysta)与按键历史状态(backup)不同,则说明按键状态发生变化。程序中是弹起时,按键次数改变,将最新的按键次数送给数码管显示,将按键历史状态更新为当前状态并进行下一次判断。源代码如下: #include reg52.h sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2
[单片机]
KST<font color='red'>51单片机</font>:通过中断实现矩阵按键的次数检测与消抖
使用51单片机点亮我们的点阵灯
通过前面我们都知道点亮我们的不管是点阵,数码管,还是LED灯,不仅要熟悉我们的代码还要会看我们的原理图和真值表,所以我们如果真的要写代码倒是其次的,首先我们得学会看我们的原理图和真值表,但是认识那个我们可以在网上找教程的,所以啊我这里就不去重诉别人的话了。那么我们今天要讨论什么问题勒!?我们今天讲一下点阵吧,点阵说实话对于单片机来说虽然并不是最重要的,但是点阵却是我们单片机中花样最多的之一。可能说到这么有人会说了,学了单片机我们有什么用呢,那么我们可以留意一下我们身边的一些物品,比如我们常在街上可以看见一些商店利用那些LED灯做出的花样,什么闪烁啊,各种图形变化啊,其实和我们的点阵原理都很像,不过他们那些控制的位更多,而我们51
[单片机]
51单片机演奏乐曲的程序
sbit SPK = P1^7 ;指定扬声器接口 ORG 0000H LJMP START ORG 000BH LJMP T0_INT ORG 001BH LJMP T1_INT ;------------------------------------------------------------ B_ZQ_TAB: ;定时半周期初始值数据表(数据的意义可见前一篇博文) DW 63625, 63833, 64019, 64104, 64260, 64400, 64524 ;低音区:1 2 3 4 5 6 7 DW 64580,
[单片机]
用优质开关稳压电源供电的STK6303合并式功放
大家知道,音频功率放大器实际上为电源调制器,故电源供给系统的地位的功放中举足轻重,有人甚至说一台好的功放,其电源成本应占一半以上。时下的功放,无论是国外的还是国内的,大都用传统的整流滤波电源,而选用理想的优秀高频高频高速开关电源的厂商还很少,究其原因除成本外,主要认为高频电源尚存在射频干扰、高频泄漏、反应速率稍差以及声染等问题。其实,有新型号为AA-12480的显示器精密开关电源,较好地解决了上述问题,成本也较低,把它们运用于功放,效果出色,现介绍给爱好者们参考。 电路原理如图3-51所示,功放部分采用日本三洋公司制造的STK6303大功率厚膜集成电路,其供电电压最大可达正负50V,输出电流可达10A左右。单片电路的稳压供电正
[电源管理]
用优质开关稳压电源供电的STK63<font color='red'>03</font>合并式功放
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved