亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
51單片機多任務(wù)os源程序
[打印本頁]
作者:
wdliming
時間:
2019-11-22 20:53
標題:
51單片機多任務(wù)os源程序
調(diào)用系統(tǒng)服務(wù)使任務(wù)切換時不保存寄存器變量
中斷服務(wù)執(zhí)行任務(wù)切換時,保存寄存器變量
支持7個任務(wù),支持7級中斷嵌套
基于優(yōu)先級調(diào)度,0號任務(wù)具有最高優(yōu)先級
包含K_FLG K_SEM K_MSG K_TMO這幾個系統(tǒng)服務(wù),每種類型的系統(tǒng)服務(wù)最多提供16個
單片機源程序如下:
#define _IN_LQ51_C_
#include "lq51.h"
#include<reg52.h>
/******************************************
/ 定義全局變量
/******************************************/
unsigned char data lqTaskStack[lqMaxID+1]; /*任務(wù)堆棧指針*/
unsigned char data lqSPtemp; /*記錄ID號=當前任務(wù)ID+1的堆棧底部*/
unsigned char data lqTaskTimer[lqMaxID]; /*任務(wù)定時器*/
unsigned char data lqTaskState[lqMaxID]; /*任務(wù)狀態(tài)表*/
unsigned char data lqRdyTbl; /*就緒表*/
unsigned char data lqSwitchType; /*任務(wù)切換類型,如果通過中斷切換任務(wù)則在相應(yīng)位置1,否則置0*/
unsigned char data lqIntNum; /*進入中斷服務(wù)子程序后系統(tǒng)把中斷號傳給這個變量*/
unsigned char data lqCrt; /*當前正在運行的任務(wù)*/
#if LQ_FLG_EN /*該事件的最高位表示該標志位是否置位,其他位表示等待該標志量的任務(wù),當標志位置位時,所有等待這個標志的任務(wù)都被激活*/
unsigned char data lqFlgData[lqFlgMax]={
0,0
};
#endif
#if LQ_SEM_EN /*信號量數(shù)據(jù)結(jié)構(gòu)*/
/*一個信號量數(shù)據(jù)結(jié)構(gòu)包含兩個字節(jié),第一個字節(jié)為信號量值*/
unsigned char data lqSemData[lqSemMax*2]={ /*第二個字節(jié)為等待這個信號量的任務(wù)*/
0,0,
0,0};
#endif
#if LQ_MSG_EN /*消息郵箱數(shù)據(jù)結(jié)構(gòu)*/
/*一個消息郵箱數(shù)據(jù)結(jié)構(gòu)包含兩個字節(jié),第一個字節(jié)為消息郵箱的消息*/
unsigned char data lqMsgData[lqMsgMax*2]={ /*第二個字節(jié)的最高位表示當前郵箱是否有消息0表示沒有1表示有,其他為表示等待這個消息的任務(wù)*/
0,0,
0,0};
#endif
const unsigned char code lqMap[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
/*****************************************
/ 開始函數(shù)
/這個函數(shù)必須在0號任務(wù)的最開始的部分調(diào)用
/ void lqStart(void);
/*****************************************/
void lqStart(void)
{
char i;
for(i=0;i<lqMaxID;++i){
lqTaskTimer[i] = 0;
lqTaskState[i] = 0;
}
lqRdyTbl=0xFF;
lqSwitchType=0x00;
EA = 1;
lqCrt=0;
}
#if LQ_DELAY_EN
/***************************************************
/ 任務(wù)延遲一段時間
/ void lqDelay(unsigned char tmo)
/ tmo:延遲時間,如果tmo=0,那么當前任務(wù)休眠,永遠不會被激活
/***************************************************/
void lqDelay(unsigned char tmo)
{
EA=0;
lqRdyTbl &= ~lqMap[lqCrt];
lqTaskState[lqCrt] |= K_TMO;
lqTaskTimer[lqCrt] = tmo;
EA=1;
lqSche();
}
#endif
#if LQ_FLG_EN
/**************************************************
/ 等待標志
/ char lqWaitFlg(unsigned char index,unsigned char tmo)
/ index :標志量索引
/ tmo :超時等待時限,如果為0則無限等待
/ 返回值:
/ 標志量有效返回 K_FLG
/ 在規(guī)定的時件內(nèi)標志量未發(fā)生返回 K_TMO
/*************************************************/
unsigned char lqWaitFlg(unsigned char index,unsigned char tmo)
{
EA=0;
lqTaskState[lqCrt] &= 0xF0;
lqTaskState[lqCrt]|= index; /*將當前索引值保存到任務(wù)狀態(tài)的低四位,因為函數(shù)是不可重入的*/
if(lqFlgData[index] & 0x80){ /*標志量置位*/
lqFlgData[index] = 0;
EA=1;
return K_FLG;
}
lqFlgData[index] |= lqMap[lqCrt];
lqRdyTbl &= ~lqMap[lqCrt];
lqTaskState[lqCrt] |= K_FLG;
if(tmo){
lqTaskState[lqCrt] |= K_TMO;
lqTaskTimer[lqCrt] = tmo;
}
EA=1;
lqSche();
EA=0;
index = 0x0F & lqTaskState[lqCrt];
if(lqTaskState[lqCrt] & K_FLG){ /*等待超時返回*/
lqTaskState[lqCrt] &= ~K_FLG;
lqTaskState[lqCrt] |= K_TMO; /*超時標記*/
lqFlgData[index] &= ~lqMap[lqCrt];
EA=1;
return K_TMO;
}
EA=1;
return K_FLG;
}
/************************************************
/ 中斷服務(wù)子程序發(fā)送標志
/ char lqSendFlgISR(unsigned char index)
/ index :標志量索引
/ 返回值:
/ 1 -- 有更高優(yōu)先級的任務(wù)就緒,需要執(zhí)行任務(wù)切換
/ 0 -- 不需要執(zhí)行任務(wù)切換
/************************************************/
char lqSendFlgISR(unsigned char index)
{
char i,j;
EA=0;
if(lqFlgData[index] & 0x7F){ /*有任務(wù)在等待這個標志事件*/
i=lqMaxID;
for(j=0;j<lqMaxID;++j){
if(lqFlgData[index] & lqMap[j]){ /*任務(wù)等待這個標志事件*/
lqTaskState[j] &= ~K_FLG;
lqTaskState[j] &= ~K_TMO;
lqTaskTimer[j] = 0;
lqRdyTbl |= lqMap[j];
if(j<i){
i=j;
}
}
}
lqFlgData[index] = 0;
if(i<lqCrt){
EA=1;
return 1;
}
EA=1;
return 0;
}
lqFlgData[index] = 0x80;
EA=1;
return 0;
}
/********************************************
/ 任務(wù)發(fā)送標志事件
/ void lqSendFlg(unsigned char index)
/********************************************/
void lqSendFlg(unsigned char index)
{
if(lqSendFlgISR(index)){
lqSche();
}
}
#endif
#if LQ_SEM_EN
/************************************************
/ 等待一個信號量
/ char lqWaitSem(unsigned char index,unsigned char tmo)
/ index :信號量索引
/ tmo :超時等待時限,如果為0則無限等待
/ 返回值:
/ 信號量有效返回 K_SEM
/ 在規(guī)定的時件內(nèi)信號量未發(fā)生返回 K_TMO
/************************************************/
unsigned char lqWaitSem(unsigned char index,unsigned char tmo)
{
EA=0;
lqTaskState[lqCrt] &= 0xF0;
lqTaskState[lqCrt]|= index; /*因為函數(shù)不可重,所以存儲信號量索引*/
index *= 2;
if(lqSemData[index]){
--lqSemData[index];
EA=1;
return K_SEM;
}
lqRdyTbl &= ~lqMap[lqCrt];
lqSemData[index+1] |= lqMap[lqCrt];
lqTaskState[lqCrt] |= K_SEM;
if(tmo){
lqTaskState[lqCrt] |= K_TMO;
lqTaskTimer[lqCrt] = tmo;
}
EA=1;
lqSche();
EA=0;
index = 0x0F & lqTaskState[lqCrt];
if(lqTaskState[lqCrt] & K_SEM){
lqTaskState[lqCrt] &= ~K_SEM;
lqTaskState[lqCrt] |= K_TMO;
lqSemData[index*2+1] &= ~lqMap[lqCrt];
EA=1;
return K_TMO;
}
EA=1;
return K_SEM;
}
/*********************************************
/ 中斷子程序發(fā)送信號量
/ char lqSendSemISR(unsigned char index)
/ index :信號量索引
/ 返回值:
/ 1 -- 有更高優(yōu)先級的任務(wù)就緒,需要執(zhí)行任務(wù)切換
/ 0 -- 不需要執(zhí)行任務(wù)切換
/*********************************************/
char lqSendSemISR(unsigned char index)
{
char j;
EA=0;
index*=2;
if(lqSemData[index+1]){
for(j=0;j<lqMaxID;++j){
if(lqSemData[index+1] & lqMap[j]){
break;
}
}
lqSemData[index+1] &= ~lqMap[j];
lqTaskTimer[j] = 0;
lqTaskState[j] &= ~K_SEM;
lqTaskState[j] &= ~K_TMO;
lqRdyTbl |= lqMap[j];
if(j<lqCrt){
EA=1;
return 1;
}
EA=1;
return 0;
}
++lqSemData[index];
EA=1;
return 0;
}
/************************************************
/ 任務(wù)發(fā)送信號量
/ void lqSendSem(unsinged char index)
/***********************************************/
void lqSendSem(unsigned char index)
{
if(lqSendSemISR(index)){
lqSche();
}
}
#endif
#if LQ_MSG_EN
/*********************************************
/ 等待消息郵箱
/ unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
/ index :郵箱索引
/ tmo :超時等待時限,如果為0則無限等待
/ 郵箱中的值為 0x00~0xFF
/ lqMsgData[2*index+1]的最高為0表示當前沒郵件,
/ 否則表示當前有郵件
/ 返回值 :
/ 如果在規(guī)定的時間內(nèi)有消息送到這個郵箱,則返回這個消息
/ 如果在規(guī)定的時間內(nèi)沒有消息送到這個郵箱,則返回 MSG_TMO
/ MSG_TMO在lq51.h中有定義,如果 MSG_TMO 所代表的值是消息的一部分,
/ 那么在這個函數(shù)返回后建議執(zhí)行char lqIsTaskTmo(),檢查當前任務(wù)
/ 是否從超時返回
/********************************************/
unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
{
EA=0;
lqTaskState[lqCrt] &= 0xF0;
lqTaskState[lqCrt] |= index;
index *= 2;
if(lqMsgData[index+1] & 0x80){ /*當前郵箱有郵件*/
lqMsgData[index+1] &= 0x7F;
EA=1;
return lqMsgData[index];
}
lqRdyTbl &= ~lqMap[lqCrt];
lqMsgData[index+1] |= lqMap[lqCrt];
lqTaskState[lqCrt] |= K_MSG;
if(tmo){
lqTaskState[lqCrt] |= K_TMO;
lqTaskTimer[lqCrt] = tmo;
}
EA=1;
lqSche();
EA=0;
index = lqTaskState[lqCrt] & 0x0F;
index *= 2;
if(lqTaskState[lqCrt] & K_MSG){
lqTaskState[lqCrt] &= ~K_MSG;
lqTaskState[lqCrt] |= K_TMO;
lqMsgData[index] = MSG_TMO;
lqMsgData[index+1] &= ~lqMap[lqCrt];
}
lqMsgData[index+1] &= 0x7F;
EA=1;
return lqMsgData[index];
}
/*******************************************
/ char lqIsMsgEmpty(unsigned char index)
/ index :郵箱索引
/ 返回值:
/ 0 -- 郵箱中有消息
/ 1 -- 郵箱中沒有消息
/******************************************/
#if LQ_CHK_MSG_EN
char lqIsMsgEmpty(unsigned char index)
{
EA=0;
if(lqMsgData[index*2+1] & 0x80){
EA=1;
return 0; /*郵箱不為空,郵箱中有消息*/
}
EA=1;
return 1; /*郵箱為空,郵箱中無消息*/
}
#endif
/*******************************************
/ 中斷子程序發(fā)送郵件
/ char lqSendMsgISR(unsigned char index,unsigned char Msg)
/ index :郵箱索引
/ Msg :被發(fā)送的消息
/ 如果郵箱中已經(jīng)存在消息,原來的消息不會被覆蓋,函數(shù)之間返回
/ 返回值:
/ 1 -- 有更高優(yōu)先級的任務(wù)就緒,需要執(zhí)行任務(wù)切換
/ 0 -- 不需要執(zhí)行任務(wù)切換
/*******************************************/
char lqSendMsgISR(unsigned char index,unsigned char Msg)
{
EA=0;
index *= 2;
if(lqMsgData[index+1] & 0x80){
EA=1;
return 0; /*郵箱不為空*/
}
lqMsgData[index] = Msg;
++index;
lqMsgData[index] |= 0x80;
if(lqMsgData[index] & 0x7F){ /*有任務(wù)在等待這個郵件*/
for(Msg=0;Msg<lqMaxID;++Msg){
if(lqMsgData[index] & lqMap[Msg]){
break;
}
}
lqMsgData[index] &= ~lqMap[Msg];
lqTaskState[Msg] &= ~K_MSG;
lqRdyTbl |= lqMap[Msg];
if(Msg < lqCrt){
EA=1;
return 1;
}
}
EA = 1;
return 0;
}
/********************************************
/ 任務(wù)發(fā)送郵件
/ void lqSendMsg(unsigned char index,unsigned char Msg)
/ index :郵箱索引
/ Msg :被發(fā)送的消息
/*******************************************/
void lqSendMsg(unsigned char index,unsigned char Msg)
{
if(lqSendMsgISR(index,Msg)){
lqSche();
}
}
#endif
#if LQ_TASK_TMO_CHK_EN
/***********************************************
/ 任務(wù)超時返回檢查
/ char lqIsTaskTmo()
/ 如果當前任務(wù)是超時返回,那么任務(wù)狀態(tài)(lqTaskState)的B_TMO位置位,否則該標志位被清零
/ 一般情況下只針對郵箱事件返回后做超時檢查
/ 返回值:
/ 1 -- 當前任務(wù)是超時返回
/ 0 -- 當前任務(wù)不是超時返回
/************************************************/
char lqIsTaskTmo()
{
if(lqTaskState[lqCrt] & K_TMO){
return 1;
}
return 0;
}
#endif
復(fù)制代碼
所有資料51hei提供下載:
lq51-master.zip
(216.94 KB, 下載次數(shù): 18)
2019-11-22 20:53 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1