久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2311|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)多任務(wù)os源程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:20672 發(fā)表于 2019-11-22 20:53 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
調(diào)用系統(tǒng)服務(wù)使任務(wù)切換時(shí)不保存寄存器變量
中斷服務(wù)執(zhí)行任務(wù)切換時(shí),保存寄存器變量
支持7個(gè)任務(wù),支持7級(jí)中斷嵌套
基于優(yōu)先級(jí)調(diào)度,0號(hào)任務(wù)具有最高優(yōu)先級(jí)
包含K_FLG K_SEM K_MSG K_TMO這幾個(gè)系統(tǒng)服務(wù),每種類型的系統(tǒng)服務(wù)最多提供16個(gè)

單片機(jī)源程序如下:
  1. #define _IN_LQ51_C_
  2. #include "lq51.h"
  3. #include<reg52.h>
  4. /******************************************
  5. /                          定義全局變量
  6. /******************************************/
  7. unsigned char data lqTaskStack[lqMaxID+1];                        /*任務(wù)堆棧指針*/
  8. unsigned char data lqSPtemp;                                                /*記錄ID號(hào)=當(dāng)前任務(wù)ID+1的堆棧底部*/
  9. unsigned char data lqTaskTimer[lqMaxID];                        /*任務(wù)定時(shí)器*/
  10. unsigned char data lqTaskState[lqMaxID];                        /*任務(wù)狀態(tài)表*/
  11. unsigned char data lqRdyTbl;                                                /*就緒表*/
  12. unsigned char data lqSwitchType;                                        /*任務(wù)切換類型,如果通過中斷切換任務(wù)則在相應(yīng)位置1,否則置0*/
  13. unsigned char data lqIntNum;                                                /*進(jìn)入中斷服務(wù)子程序后系統(tǒng)把中斷號(hào)傳給這個(gè)變量*/
  14. unsigned char data lqCrt;                                                        /*當(dāng)前正在運(yùn)行的任務(wù)*/

  15. #if        LQ_FLG_EN                                /*該事件的最高位表示該標(biāo)志位是否置位,其他位表示等待該標(biāo)志量的任務(wù),當(dāng)標(biāo)志位置位時(shí),所有等待這個(gè)標(biāo)志的任務(wù)都被激活*/
  16. unsigned char data lqFlgData[lqFlgMax]={
  17. 0,0
  18. };
  19. #endif

  20. #if        LQ_SEM_EN                                                        /*信號(hào)量數(shù)據(jù)結(jié)構(gòu)*/
  21.                                                                                 /*一個(gè)信號(hào)量數(shù)據(jù)結(jié)構(gòu)包含兩個(gè)字節(jié),第一個(gè)字節(jié)為信號(hào)量值*/
  22. unsigned char data lqSemData[lqSemMax*2]={                        /*第二個(gè)字節(jié)為等待這個(gè)信號(hào)量的任務(wù)*/
  23.         0,0,
  24.         0,0};
  25. #endif                                                                                               

  26. #if        LQ_MSG_EN                                                        /*消息郵箱數(shù)據(jù)結(jié)構(gòu)*/
  27.                                                                                 /*一個(gè)消息郵箱數(shù)據(jù)結(jié)構(gòu)包含兩個(gè)字節(jié),第一個(gè)字節(jié)為消息郵箱的消息*/
  28. unsigned char data lqMsgData[lqMsgMax*2]={                /*第二個(gè)字節(jié)的最高位表示當(dāng)前郵箱是否有消息0表示沒有1表示有,其他為表示等待這個(gè)消息的任務(wù)*/
  29.         0,0,
  30.         0,0};       
  31. #endif               


  32. const unsigned char code lqMap[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

  33. /*****************************************
  34. /                        開始函數(shù)
  35. /這個(gè)函數(shù)必須在0號(hào)任務(wù)的最開始的部分調(diào)用
  36. /        void lqStart(void);
  37. /*****************************************/
  38. void lqStart(void)
  39. {
  40.         char i;
  41.         for(i=0;i<lqMaxID;++i){
  42.                 lqTaskTimer[i] = 0;
  43.                 lqTaskState[i] = 0;
  44.         }
  45.         lqRdyTbl=0xFF;
  46.         lqSwitchType=0x00;
  47.         EA = 1;
  48.         lqCrt=0;
  49. }

  50. #if LQ_DELAY_EN
  51. /***************************************************
  52. /                                任務(wù)延遲一段時(shí)間
  53. /        void lqDelay(unsigned char tmo)
  54. /        tmo:延遲時(shí)間,如果tmo=0,那么當(dāng)前任務(wù)休眠,永遠(yuǎn)不會(huì)被激活
  55. /***************************************************/
  56. void lqDelay(unsigned char tmo)
  57. {
  58.         EA=0;
  59.         lqRdyTbl &= ~lqMap[lqCrt];
  60.         lqTaskState[lqCrt] |= K_TMO;
  61.         lqTaskTimer[lqCrt] = tmo;
  62.         EA=1;
  63.         lqSche();
  64. }
  65. #endif

  66. #if        LQ_FLG_EN
  67. /**************************************************
  68. /                        等待標(biāo)志
  69. /        char lqWaitFlg(unsigned char index,unsigned char tmo)
  70. /        index        :標(biāo)志量索引
  71. /        tmo                :超時(shí)等待時(shí)限,如果為0則無限等待
  72. /        返回值:
  73. /        標(biāo)志量有效返回 K_FLG
  74. /        在規(guī)定的時(shí)件內(nèi)標(biāo)志量未發(fā)生返回 K_TMO
  75. /*************************************************/
  76. unsigned char lqWaitFlg(unsigned char index,unsigned char tmo)
  77. {
  78.         EA=0;
  79.         lqTaskState[lqCrt] &= 0xF0;
  80.         lqTaskState[lqCrt]|= index;                /*將當(dāng)前索引值保存到任務(wù)狀態(tài)的低四位,因?yàn)楹瘮?shù)是不可重入的*/
  81.         if(lqFlgData[index] & 0x80){        /*標(biāo)志量置位*/
  82.                 lqFlgData[index] = 0;
  83.                 EA=1;
  84.                 return        K_FLG;
  85.         }
  86.         lqFlgData[index] |= lqMap[lqCrt];
  87.         lqRdyTbl &= ~lqMap[lqCrt];
  88.         lqTaskState[lqCrt] |= K_FLG;
  89.         if(tmo){
  90.                 lqTaskState[lqCrt] |= K_TMO;
  91.                 lqTaskTimer[lqCrt] = tmo;
  92.         }
  93.         EA=1;
  94.         lqSche();
  95.         EA=0;
  96.         index = 0x0F & lqTaskState[lqCrt];
  97.         if(lqTaskState[lqCrt] & K_FLG){                /*等待超時(shí)返回*/
  98.                 lqTaskState[lqCrt] &= ~K_FLG;
  99.                 lqTaskState[lqCrt] |= K_TMO;        /*超時(shí)標(biāo)記*/
  100.                 lqFlgData[index] &= ~lqMap[lqCrt];
  101.                 EA=1;
  102.                 return K_TMO;
  103.         }
  104.         EA=1;
  105.         return K_FLG;
  106. }

  107. /************************************************
  108. /                中斷服務(wù)子程序發(fā)送標(biāo)志
  109. /        char lqSendFlgISR(unsigned char index)
  110. /        index        :標(biāo)志量索引
  111. /        返回值:
  112. /        1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
  113. /        0 -- 不需要執(zhí)行任務(wù)切換
  114. /************************************************/
  115. char lqSendFlgISR(unsigned char index)
  116. {
  117.         char i,j;
  118.         EA=0;
  119.         if(lqFlgData[index] & 0x7F){                /*有任務(wù)在等待這個(gè)標(biāo)志事件*/
  120.                 i=lqMaxID;
  121.                 for(j=0;j<lqMaxID;++j){
  122.                         if(lqFlgData[index] & lqMap[j]){        /*任務(wù)等待這個(gè)標(biāo)志事件*/
  123.                                 lqTaskState[j] &= ~K_FLG;
  124.                                 lqTaskState[j] &= ~K_TMO;
  125.                                 lqTaskTimer[j] = 0;
  126.                                 lqRdyTbl |= lqMap[j];
  127.                                 if(j<i){
  128.                                         i=j;
  129.                                 }
  130.                         }
  131.                 }
  132.                 lqFlgData[index] = 0;
  133.                 if(i<lqCrt){
  134.                         EA=1;
  135.                         return 1;
  136.                 }
  137.                 EA=1;
  138.                 return 0;
  139.         }
  140.         lqFlgData[index] = 0x80;
  141.         EA=1;
  142.         return 0;
  143. }
  144. /********************************************
  145. /                任務(wù)發(fā)送標(biāo)志事件
  146. /        void lqSendFlg(unsigned char index)
  147. /********************************************/
  148. void lqSendFlg(unsigned char index)
  149. {
  150.         if(lqSendFlgISR(index)){
  151.                 lqSche();
  152.         }
  153. }
  154. #endif

  155. #if        LQ_SEM_EN
  156. /************************************************
  157. /                等待一個(gè)信號(hào)量
  158. /        char lqWaitSem(unsigned char index,unsigned char tmo)
  159. /        index        :信號(hào)量索引
  160. /        tmo                :超時(shí)等待時(shí)限,如果為0則無限等待
  161. /        返回值:
  162. /        信號(hào)量有效返回 K_SEM
  163. /        在規(guī)定的時(shí)件內(nèi)信號(hào)量未發(fā)生返回 K_TMO
  164. /************************************************/
  165. unsigned char lqWaitSem(unsigned char index,unsigned char tmo)
  166. {
  167.         EA=0;
  168.         lqTaskState[lqCrt] &= 0xF0;
  169.         lqTaskState[lqCrt]|= index;                /*因?yàn)楹瘮?shù)不可重,所以存儲(chǔ)信號(hào)量索引*/
  170.         index *= 2;
  171.         if(lqSemData[index]){
  172.                 --lqSemData[index];
  173.                 EA=1;
  174.                 return K_SEM;
  175.         }
  176.         lqRdyTbl &= ~lqMap[lqCrt];
  177.         lqSemData[index+1] |= lqMap[lqCrt];
  178.         lqTaskState[lqCrt] |= K_SEM;
  179.         if(tmo){
  180.                 lqTaskState[lqCrt] |= K_TMO;
  181.                 lqTaskTimer[lqCrt] = tmo;
  182.         }
  183.         EA=1;
  184.         lqSche();
  185.         EA=0;
  186.         index = 0x0F & lqTaskState[lqCrt];
  187.         if(lqTaskState[lqCrt] & K_SEM){
  188.                 lqTaskState[lqCrt] &= ~K_SEM;
  189.                 lqTaskState[lqCrt] |= K_TMO;
  190.                 lqSemData[index*2+1] &= ~lqMap[lqCrt];
  191.                 EA=1;
  192.                 return K_TMO;
  193.         }
  194.         EA=1;
  195.         return K_SEM;
  196. }

  197. /*********************************************
  198. /                        中斷子程序發(fā)送信號(hào)量
  199. /        char lqSendSemISR(unsigned char index)
  200. /        index        :信號(hào)量索引
  201. /        返回值:
  202. /        1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
  203. /        0 -- 不需要執(zhí)行任務(wù)切換
  204. /*********************************************/
  205. char lqSendSemISR(unsigned char index)
  206. {
  207.         char j;
  208.         EA=0;
  209.         index*=2;
  210.         if(lqSemData[index+1]){
  211.                 for(j=0;j<lqMaxID;++j){
  212.                         if(lqSemData[index+1] & lqMap[j]){
  213.                                 break;
  214.                         }
  215.                 }
  216.                 lqSemData[index+1] &= ~lqMap[j];
  217.                 lqTaskTimer[j] = 0;
  218.                 lqTaskState[j] &= ~K_SEM;
  219.                 lqTaskState[j] &= ~K_TMO;
  220.                 lqRdyTbl |= lqMap[j];
  221.                 if(j<lqCrt){
  222.                         EA=1;
  223.                         return 1;
  224.                 }
  225.                 EA=1;
  226.                 return 0;
  227.         }
  228.         ++lqSemData[index];
  229.         EA=1;
  230.         return 0;
  231. }

  232. /************************************************
  233. /                        任務(wù)發(fā)送信號(hào)量
  234. /        void lqSendSem(unsinged char index)
  235. /***********************************************/
  236. void lqSendSem(unsigned char index)
  237. {
  238.         if(lqSendSemISR(index)){
  239.                 lqSche();
  240.         }
  241. }
  242. #endif

  243. #if        LQ_MSG_EN
  244. /*********************************************
  245. /                        等待消息郵箱
  246. /        unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
  247. /        index        :郵箱索引
  248. /        tmo                :超時(shí)等待時(shí)限,如果為0則無限等待
  249. /        郵箱中的值為 0x00~0xFF
  250. /        lqMsgData[2*index+1]的最高為0表示當(dāng)前沒郵件,
  251. /        否則表示當(dāng)前有郵件
  252. /        返回值        :
  253. /        如果在規(guī)定的時(shí)間內(nèi)有消息送到這個(gè)郵箱,則返回這個(gè)消息
  254. /        如果在規(guī)定的時(shí)間內(nèi)沒有消息送到這個(gè)郵箱,則返回 MSG_TMO
  255. /        MSG_TMO在lq51.h中有定義,如果 MSG_TMO 所代表的值是消息的一部分,
  256. /        那么在這個(gè)函數(shù)返回后建議執(zhí)行char lqIsTaskTmo(),檢查當(dāng)前任務(wù)
  257. /        是否從超時(shí)返回
  258. /********************************************/
  259. unsigned char lqWaitMsg(unsigned char index,unsigned char tmo)
  260. {
  261.         EA=0;
  262.         lqTaskState[lqCrt] &= 0xF0;
  263.         lqTaskState[lqCrt] |= index;
  264.         index *= 2;
  265.         if(lqMsgData[index+1] & 0x80){                /*當(dāng)前郵箱有郵件*/
  266.                 lqMsgData[index+1] &= 0x7F;
  267.                 EA=1;
  268.                 return lqMsgData[index];
  269.         }
  270.         lqRdyTbl &= ~lqMap[lqCrt];
  271.         lqMsgData[index+1] |= lqMap[lqCrt];
  272.         lqTaskState[lqCrt] |= K_MSG;
  273.         if(tmo){
  274.                 lqTaskState[lqCrt] |= K_TMO;
  275.                 lqTaskTimer[lqCrt] = tmo;
  276.         }
  277.         EA=1;
  278.         lqSche();
  279.         EA=0;
  280.         index = lqTaskState[lqCrt] & 0x0F;
  281.         index *= 2;
  282.         if(lqTaskState[lqCrt] & K_MSG){
  283.                 lqTaskState[lqCrt] &= ~K_MSG;
  284.                 lqTaskState[lqCrt] |= K_TMO;
  285.                 lqMsgData[index] = MSG_TMO;
  286.                 lqMsgData[index+1] &= ~lqMap[lqCrt];
  287.         }
  288.         lqMsgData[index+1] &= 0x7F;
  289.         EA=1;
  290.         return lqMsgData[index];
  291. }
  292. /*******************************************
  293. /        char lqIsMsgEmpty(unsigned char index)
  294. /        index        :郵箱索引
  295. /        返回值:
  296. /        0 -- 郵箱中有消息
  297. /        1 -- 郵箱中沒有消息
  298. /******************************************/
  299. #if        LQ_CHK_MSG_EN
  300. char lqIsMsgEmpty(unsigned char index)
  301. {
  302.         EA=0;
  303.         if(lqMsgData[index*2+1] & 0x80){
  304.                 EA=1;
  305.                 return 0;                                /*郵箱不為空,郵箱中有消息*/
  306.         }
  307.         EA=1;
  308.         return 1;                                        /*郵箱為空,郵箱中無消息*/
  309. }
  310. #endif
  311. /*******************************************
  312. /                中斷子程序發(fā)送郵件
  313. /        char lqSendMsgISR(unsigned char index,unsigned char Msg)
  314. /        index        :郵箱索引
  315. /        Msg                :被發(fā)送的消息
  316. /        如果郵箱中已經(jīng)存在消息,原來的消息不會(huì)被覆蓋,函數(shù)之間返回
  317. /        返回值:
  318. /        1 -- 有更高優(yōu)先級(jí)的任務(wù)就緒,需要執(zhí)行任務(wù)切換
  319. /        0 -- 不需要執(zhí)行任務(wù)切換
  320. /*******************************************/
  321. char lqSendMsgISR(unsigned char index,unsigned char Msg)
  322. {
  323.         EA=0;
  324.         index *= 2;
  325.         if(lqMsgData[index+1] & 0x80){
  326.                 EA=1;
  327.                 return 0;                                        /*郵箱不為空*/
  328.         }
  329.         lqMsgData[index] = Msg;
  330.         ++index;
  331.         lqMsgData[index] |= 0x80;
  332.         if(lqMsgData[index] & 0x7F){        /*有任務(wù)在等待這個(gè)郵件*/
  333.                 for(Msg=0;Msg<lqMaxID;++Msg){
  334.                         if(lqMsgData[index] & lqMap[Msg]){
  335.                                 break;
  336.                         }
  337.                 }
  338.                 lqMsgData[index] &= ~lqMap[Msg];
  339.                 lqTaskState[Msg] &= ~K_MSG;
  340.                 lqRdyTbl |= lqMap[Msg];
  341.                 if(Msg < lqCrt){
  342.                         EA=1;
  343.                         return 1;
  344.                 }
  345.         }
  346.         EA = 1;
  347.         return 0;
  348. }
  349. /********************************************
  350. /                任務(wù)發(fā)送郵件
  351. /        void lqSendMsg(unsigned char index,unsigned char Msg)
  352. /        index        :郵箱索引
  353. /        Msg                :被發(fā)送的消息
  354. /*******************************************/
  355. void lqSendMsg(unsigned char index,unsigned char Msg)
  356. {
  357.         if(lqSendMsgISR(index,Msg)){
  358.                 lqSche();
  359.         }
  360. }
  361. #endif

  362. #if        LQ_TASK_TMO_CHK_EN
  363. /***********************************************
  364. /                        任務(wù)超時(shí)返回檢查
  365. /        char lqIsTaskTmo()
  366. /        如果當(dāng)前任務(wù)是超時(shí)返回,那么任務(wù)狀態(tài)(lqTaskState)的B_TMO位置位,否則該標(biāo)志位被清零
  367. /        一般情況下只針對(duì)郵箱事件返回后做超時(shí)檢查
  368. /        返回值:
  369. /        1  --  當(dāng)前任務(wù)是超時(shí)返回
  370. /        0  --  當(dāng)前任務(wù)不是超時(shí)返回
  371. /************************************************/
  372. char lqIsTaskTmo()
  373. {
  374.         if(lqTaskState[lqCrt] & K_TMO){
  375.                 return 1;
  376.         }
  377.         return 0;
  378. }
  379. #endif
復(fù)制代碼

所有資料51hei提供下載:
lq51-master.zip (216.94 KB, 下載次數(shù): 18)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产一区二区三区在线观看 | 琪琪午夜伦伦电影福利片 | 男女网站在线观看 | 欧美日韩成人一区二区 | 久久国产视频一区 | 欧美三级成人理伦 | 精品欧美一区二区三区 | 亚洲性爰 | 日韩欧美国产一区二区三区 | 日韩精品中文字幕在线 | 欧美精品一区在线 | 久久高清国产 | 自拍偷拍亚洲视频 | 欧美亚洲国产日韩 | 黄免费观看视频 | 亚洲欧美日韩高清 | av一级在线观看 | 久热国产在线 | 日本淫视频 | 成人国产精品久久久 | 欧美精品在线免费 | 欧洲视频一区二区 | 国产一级片一区二区三区 | 国产精品欧美日韩 | 一区二区中文字幕 | 久久精品亚洲成在人线av网址 | 国产一区二区三区四区在线观看 | 欧美精品一区二区三区在线播放 | 国产精品视频二区三区 | 一区在线视频 | 欧美片网站免费 | 国产小视频精品 | 成人夜晚看av | 国产在线精品一区二区 | 秋霞影院一区二区 | 国产欧美在线播放 | 91在线资源| 午夜精品一区二区三区三上悠亚 | 99视频网 | 亚洲一区二区三区免费在线观看 | 久久青视频 |