欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

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

QQ登錄

只需一步,快速開始

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

51單片機(jī)的多任務(wù)實(shí)時(shí)系統(tǒng)開發(fā)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:70941 發(fā)表于 2015-4-5 22:28 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
    前言:
        此文章適合對(duì)51單片機(jī)感興趣,也想利用51實(shí)現(xiàn)簡(jiǎn)單的實(shí)時(shí)系統(tǒng)的程序管理,適合學(xué)習(xí)交流用,望謹(jǐn)慎吐槽。


   準(zhǔn)備一:
     所謂實(shí)時(shí)呢,這個(gè)概念三言兩語(yǔ)不好解釋, 在這里就不涉及太多的官方及專業(yè)名詞和術(shù)語(yǔ)。就像你用電飯煲做飯一樣,當(dāng)你啟動(dòng)后,是希望它一直工作,直到把 飯做好,而不希望它會(huì)中途出現(xiàn)故障什么的。然后在中斷,你希望想煮粥,那就停了電,再加水,調(diào)成煮粥模式,然后繼續(xù)工作,直到完成。這個(gè),就有點(diǎn)實(shí)時(shí)的解 釋吧,如果這個(gè)解釋不夠形象,要不再舉例另一個(gè),請(qǐng)私下聯(lián)系再作舉例。
   所謂多任務(wù)呢,這個(gè)應(yīng)該不難解釋了,不過,還是再羅嗦一下。51單片機(jī),就只有一個(gè)CPU,就像你在廚房做飯,只有你一個(gè)人,你又想煮飯,又想燒菜,還 想打掃衛(wèi)生,但你一個(gè)人,不可能同時(shí)做的。所以,一個(gè)重要的概念就在這里。一個(gè)CPU不可能同時(shí)做這么多做事的。所以,它不得不像人一樣,一會(huì)做這個(gè),一 會(huì)做那個(gè)。比如10分鐘掃一下地,然后10分鐘燒一個(gè)菜,然后10分鐘 去上個(gè)廁所,然后10分鐘再回來(lái)掃一下地。就這樣把時(shí)間分配好,但以一個(gè)小時(shí)來(lái) 看,就感覺你這一個(gè)小時(shí)是幾個(gè)工作同時(shí)在做,而且這幾個(gè)事互不影響的。
    好了,有了這兩個(gè)概念就差不多了。
    51單片機(jī)靠什么來(lái)得到這個(gè)確定的時(shí)間,并把它分割成一段一段的呢。
   下面就以一個(gè)多任務(wù)系統(tǒng)來(lái)說(shuō),因?yàn)?1單片機(jī)的儲(chǔ)存空間不夠,一般不適合做大的系統(tǒng)移植。玩過STM32的人應(yīng)該清楚uC/OS系統(tǒng)的移植,把uC /OS移植到51單片機(jī),也不無(wú)不可,只是光是把一個(gè)系統(tǒng)移植上去,單片機(jī)就沒有多少空間做其它事了。就好比說(shuō),你一個(gè)硬盤是40G的,你裝了個(gè)win 7系統(tǒng)后都差不多占了20G了,那你硬盤就沒有多少空間再做其它事了。
   uC/OS不好移植了,就更別說(shuō)把linux系統(tǒng)移植給51單片機(jī)了。那,就沒有合適給51單片機(jī)的嗎?答案是有的。
   如果你使用增強(qiáng)型的51單片機(jī),還是可以考慮對(duì)uC/OS裁剪移植的。
   不過,對(duì)于增強(qiáng)型,還是普通型,還是基本51內(nèi)核的單片機(jī),都有一個(gè)比較適合做簡(jiǎn)單的多任務(wù)系統(tǒng)開發(fā)的。

  在KEIL里,開發(fā)了一個(gè)適合對(duì)51使用的多任務(wù)實(shí)時(shí)系統(tǒng)的開發(fā)的。就是RTX51系統(tǒng)。
  RTX51分有兩個(gè),一個(gè)是RTX51FULL,一個(gè)是RTX51TINY。
  在這里介紹RTX51TINY。
  對(duì)系統(tǒng)的移植,也不算移植吧,
   從硬件的角度來(lái)說(shuō),就是對(duì)CPU的時(shí)間調(diào)度做出設(shè)置,用來(lái)管理內(nèi)存,時(shí)間等。越大的系統(tǒng)管理的越多,管理的也越周到,但操作也越復(fù)雜。
  從軟件的角度來(lái)說(shuō),就是添加把一系列的庫(kù)文件添加在程序里,然后,在程序里對(duì)庫(kù)里的子程序調(diào)用就可了。越大的系統(tǒng)里,提供的庫(kù)函數(shù)就越多,庫(kù)函數(shù)越多,調(diào) 用越來(lái)考慮的就越多。庫(kù)函數(shù)越少呢,程序應(yīng)該會(huì)清晰一些,當(dāng)然實(shí)現(xiàn)的功能及管理就跟不上去了。但對(duì)于51來(lái)說(shuō),RTX51TINY還是可以的。

   好,下面就一步一步來(lái)使用RTX51TINY來(lái)實(shí)現(xiàn)51的多任務(wù)的吧。

 一,庫(kù)文件的添加及KEIL的設(shè)置。
  
#include <rtx51tny.h>   //rtx51tny.h這個(gè)文件就是RTX51TINY的庫(kù)文件,只有一個(gè)文件,因?yàn)檫@個(gè)文件是keil里包含有的,不必去哪里找。            
   #include <reg51.h>
 然后就是打開工程的設(shè)置,如圖:
   
  在Target這個(gè)選項(xiàng)里,找到如圖中那個(gè),選擇RTX51 Tiny這個(gè)選項(xiàng),這樣,在編譯的時(shí)候,就不用提示頭文件不存在了。
這便是第一步在完成的。
 
二,對(duì)rtx51tny.h的解讀。
   
    從軟件的角度,也只是把這個(gè)頭文件添加進(jìn)來(lái),然后對(duì)庫(kù)函數(shù)做出調(diào)用。
 
 這個(gè)庫(kù)文件的函數(shù)就這幾個(gè),所以,實(shí)現(xiàn)多任務(wù)管理,只要恰當(dāng)?shù)氖褂眠@個(gè)函數(shù)就可以了。
  其中,常用的幾個(gè)函數(shù)是  os_create_task(),os_send_signal(),os_wait().。由于os_wait1和os_wait2的這兩個(gè)函數(shù)是差不多的, 
 。
三,以一個(gè)簡(jiǎn)單的程序分析:
   
#include <rtx51tny.h>               
#include <reg51.h>
void  job()  _task_  0  
{                  
  os_create_task (1);                
  os_create_task (2);              
  os_create_task (3); 
    while(1)
{  
    P1=~P1;
os_wait(K_TMO,50,0);
}   
}

void  num1() _task_ 1 
{
                     
   while(1)
{  
    P0=~P0;
     os_wait(K_TMO,100,0);
}                      
}

void num2 () _task_ 2  
{
  while (1)  
  {                     
    P2=~P2;                     
    os_wait1(K_SIG);
  }
}

void num4 () _task_ 3  
{
  while (1)  {                     
           
    P3=~P3;                     
  }
}

以上便是一個(gè)完整的程序。首先,這個(gè)程序有一個(gè)特點(diǎn),就是沒有main函數(shù)了。 下面,就對(duì)這個(gè)程序作出分析并對(duì)rtx51加深學(xué)習(xí)和理解。
void  job()  _task_  0  {}, 這個(gè),便是一個(gè)任務(wù),所謂任務(wù),就是披著嫁衣的函數(shù)。void,這個(gè),名義上可有可無(wú),但,有為好,一般不需要做什么返回。job()這個(gè),就是函數(shù)名了。這個(gè)job可以隨便一個(gè)名字,自己可以隨便起。 然后_task_是一個(gè)關(guān)鍵字,必須要有,表示你建的這個(gè)函數(shù)就是一個(gè)任務(wù)。  然后 0呢, 表示這個(gè)任務(wù)的優(yōu)先級(jí)是0。擁有最高優(yōu)先級(jí)。
   因?yàn)椋褂胷tx51這個(gè),并沒有main函數(shù),所以,程序是從任務(wù)0開始的,然后,做任務(wù)0開始執(zhí)行的后,程序該干嘛就干嘛了。那現(xiàn)在看一下任務(wù)0干了嘛。
  
os_create_task (1);   ,這個(gè),就是任務(wù)0做的事。就是創(chuàng)建了任務(wù)1。因?yàn)?/span> void  num1() _task_ 1 {}只是定義了任務(wù)1的函數(shù),或者只是定義了任務(wù)1該干什么的。但,程序沒有調(diào)用到它,它就還不能正常工作。所以os_create_task (1);的工作就是調(diào)用了任務(wù)1,讓任務(wù)1可以正常工作。然后,把任務(wù)1創(chuàng)建后,就和任務(wù)0無(wú)關(guān)了。同理,也可以os_delete_task(1);來(lái)刪除任務(wù)1,這樣,刪除了任務(wù)1后,任務(wù)1里的內(nèi)容就不再工作了。
  rtx51tiny這個(gè)可以定義16個(gè)任務(wù)。16個(gè)任務(wù),對(duì)于用51實(shí)現(xiàn)的系統(tǒng),基本就可以了。有一些初學(xué)者有點(diǎn)困惑的是,以為程序只是定義16個(gè)函數(shù),這里只是說(shuō)最大支持16個(gè)任務(wù),而你要定義各種函數(shù)呢,定義多少個(gè)都可以的。
   然后,現(xiàn)在就是每個(gè)任務(wù)的作用,聯(lián)系及區(qū)別了。
   以上程序定義了0,1,2,3共四個(gè)任務(wù)。 
任務(wù)0所做的是:
  while(1)
{   
     P1=~P1;
 os_wait(K_TMO,50,0);
}   
   就是在一定的時(shí)間間隔里,對(duì)P1的值取反。os_wait(K_TMO,50,0);這個(gè)函數(shù)就是等待時(shí)間溢出,具體參考o(jì)s_wait()這個(gè)函數(shù)。K_TMO表示是對(duì)時(shí)間溢出的方式做出等待,K_SIG,這個(gè)表示對(duì)信號(hào)作出等待。如果用到了K_SIG,就要用到os_send_signal 這個(gè)函數(shù),表示對(duì)某個(gè)任務(wù)發(fā)送信號(hào)。然后,那個(gè)函數(shù)接收到了另一個(gè)任務(wù)接收到的信號(hào),就跳出等待,作出下一步的指令。這個(gè)的50呢,表示的是表示50個(gè)時(shí) 間間隔。就像剛才在廚房里的時(shí)間間隔為10分鐘,那這里就等了50個(gè)分鐘。在rtx51默認(rèn)的時(shí)間間隔是0.01s,也就是10ms,100Hz.,那 50個(gè)時(shí)間間隔,就是間隔了0.5s,那任務(wù)0的功能就是每隔0.5來(lái)對(duì)P1的狀態(tài)取反。

   同理,分析任務(wù)1就不難了。 也有一些人疑惑了,每個(gè)任務(wù)里都有一個(gè)while()循環(huán),程序都進(jìn)入了死循環(huán),怎么再執(zhí)行其它的指令呢。
 所 以,在這里需要接受的概念就是,每一個(gè)任務(wù)被建立之后,就不再管其它任務(wù)了,就自己在做自己的事了。每個(gè)程序就相當(dāng)于一個(gè)main函數(shù)一樣了。或者這么 說(shuō),一個(gè)12Mhz的晶振,你定義了12個(gè)任務(wù),然后,這個(gè)CPU就被分成12個(gè)CPU,每一個(gè)CPU的時(shí)鐘頻率為1Mhz,然后,每個(gè)CPU就在做自己 的事,和其它CPU無(wú)關(guān),只是兩個(gè)CPU之間是可以通信管理了。這樣的解釋雖然不恰當(dāng),不過,還是很形象地讓不少同學(xué)接受了這個(gè)概念。

     以上便是一個(gè)簡(jiǎn)單的多任務(wù)管理了。它有什么優(yōu)點(diǎn),這個(gè), 就看你程序的用途了。舉個(gè)簡(jiǎn)單的說(shuō)法吧,比如你要用51單片機(jī)實(shí)現(xiàn)鍵盤的掃描,又要實(shí)現(xiàn)數(shù)碼管 的動(dòng)態(tài)掃描顯示,還要實(shí)現(xiàn)通信,管理,控制等信息。其中一點(diǎn),要做到鍵盤的掃描,就必須讓程序至少在每10ms內(nèi)或者更嚴(yán)格的時(shí)間里,對(duì)鍵盤作出掃描,那 么,這個(gè)掃描程序如果用中斷來(lái)實(shí)現(xiàn)的話,還是可以接受的,但如果不是用中斷,而是在非中斷程序里實(shí)現(xiàn)的話,但,你的程序還是要做其它事的,而且程序在做其 它的事的情況下,還要照顧的鍵盤的掃描。還有數(shù)碼管的動(dòng)態(tài)掃描,如果用定時(shí)中斷來(lái)說(shuō)才能保證程序不因其它指令的執(zhí)行而影響了數(shù)碼管顯示的延遲或不穩(wěn)定。但 要保證這些都要照顧到,程序?qū)懫饋?lái)就畢竟麻煩了。但如果采用了這種多任務(wù)的方式的話,就免去了這個(gè)麻煩了。比如,鍵盤掃描就定義成一個(gè)任務(wù),這樣,這個(gè)任 務(wù)的工作就是鍵盤的掃描,其它事也不做,這樣,就不受其它程序段的影響,而且這個(gè)任務(wù)也可以方便的移植到相同的系統(tǒng)中去。數(shù)碼管的顯示也定義一個(gè)任務(wù)來(lái)實(shí) 現(xiàn)。
    比如你還想添加一個(gè)超聲波的顯示上去,那么,你只要再定義多一個(gè)任務(wù)用來(lái)作超聲波測(cè)距的就可以了。對(duì)原有程序幾乎不需要作修改,而且對(duì)原來(lái)的程序結(jié)構(gòu)也不改變。

以上的程序只是一個(gè)簡(jiǎn)單的例子,而且很多人搜索的時(shí)候,也一般很容易搜索到這個(gè)類似的簡(jiǎn)單的例子。
下面獻(xiàn)上自己編寫的,根據(jù)超聲波測(cè)距控制小車的前進(jìn)后退的程序:
     
#include <rtx51tny.h>               
#include <reg51.h>

sbit left0=P1^0;                       
sbit left1=P1^1;                     
sbit right0=P1^2;                      
sbit right1=P1^3;
sbit echo=P3^3;
sbit trig=P3^5;
typedef unsigned char uchar;
typedef unsigned int uint;
long  numecho=0;
uint num;
job0 () _task_ 0  
  { 
               
  os_create_task (1);  
  os_create_task (2);              
  os_create_task (3);  
  os_create_task (4);
  os_create_task (5);  
  TMOD=0x91;
   while(1)
{  
    }   
 }

void back () _task_ 2  
{
    while(1)
{  
     
    os_wait1(K_SIG);
left0=1;
left1=0;
right0=0;
right1=1;
}
}                      
void go () _task_ 1 
{
    while (1)  
  {                     
      os_wait1(K_SIG);
left0=0;
left1=1;
right0=1;
right1=0;
    }
}


void Echo_test () _task_ 3  
{
 while (1) 
   {  
         trig=0;
 trig=1;
 TL1=0;
 TH1=0;
 os_wait(K_TMO,1,0);
 trig=0;
 TR1=1;
 os_wait(K_TMO,2,0);
 numecho=TH1*256+TL1;
 num=numecho*346/1000/2;
          }
}
 void panduan(void) _task_ 4
 {
    while(1)
{
 if(num>500)
 {
   os_send_signal(1);
 }
 if(num<500)
 {
   os_send_signal(2);
 }
 if(num<200)
 {
   os_send_signal(5);
 }
}   
   
 }


void stop() _task_ 5
{
   while (1)  
  {                     
        os_wait1(K_SIG);
left0=1;
left1=1;
right0=1;
right1=1;
   } 
}


在這個(gè)程序里,任務(wù)3就是作的是超聲波的測(cè)距,這個(gè)任務(wù)是不停在做,也就是超聲波在不斷的測(cè)距,把測(cè)到的距離存到num這個(gè)全局變量里,然后任務(wù)4就是根據(jù)距離作出判斷,根據(jù)不作的距離,讓小車前進(jìn),后退或停止。
   

  最后,對(duì)這個(gè)系統(tǒng)再作一些解釋。這個(gè)系統(tǒng)呢,肯定是用到了51單片機(jī)的資源的。首先,它需要做cpu作時(shí)間分割,那么就要用到定時(shí)器。這里就用了定時(shí)器0 來(lái)作定時(shí)用的。采用了工作方式1,并采用中斷方式。所以,在使用的時(shí)候,一定要注意,不能改變了TMOD里對(duì)定時(shí)器0的設(shè)置,也就是低四位的數(shù)值。也就是 說(shuō)TMOD的值為0x01的,如果需要定時(shí)器1的時(shí)候,需要注意的。還有中斷,已經(jīng)開戶了全局中斷和定時(shí)器0的中斷,所以,要用到中斷的時(shí)候,一定要注 意,不要在設(shè)置中斷的時(shí)候,把IE的值對(duì)應(yīng)的中斷值改變了,這是注意一點(diǎn)的。

 而 且,學(xué)會(huì)了51的簡(jiǎn)單的多任務(wù)實(shí)時(shí)系統(tǒng)的開發(fā),那么,再去學(xué)STM32的嵌入式操作系統(tǒng)就不難了。只不過,嵌入式操作系統(tǒng)要操作和管理調(diào)用的庫(kù)函數(shù)比較 多,需要修改的參數(shù)也比較多,而且,也要對(duì)內(nèi)存管理,時(shí)鐘,系統(tǒng)等作進(jìn)一步了解。這樣,從51向嵌入式的轉(zhuǎn)型就更容易了。
    寥寥數(shù)語(yǔ),不能把RTX51解釋清楚,更多的功能,還得靠讀者自己去發(fā)揮,出現(xiàn)的問題 也待大家去發(fā)現(xiàn)并解決了。

評(píng)分

參與人數(shù) 1黑幣 +8 收起 理由
承小諾 + 8 很給力!

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:75926 發(fā)表于 2015-4-5 22:30 | 只看該作者
看了你的文章,我所理解的系統(tǒng)就是:所有任務(wù)都已經(jīng)分配了固定時(shí)間,在固定時(shí)間只做固定的事情!因此要用到定時(shí)中斷,但這不就增加執(zhí)行每件任務(wù)的堆棧的時(shí)間么?
回復(fù)

使用道具 舉報(bào)

板凳
ID:70941 發(fā)表于 2015-4-5 22:42 | 只看該作者
xiaos 發(fā)表于 2015-4-5 22:30
看了你的文章,我所理解的系統(tǒng)就是:所有任務(wù)都已經(jīng)分配了固定時(shí)間,在固定時(shí)間只做固定的事情!因此要用到 ...

這個(gè),我一般都不太用專業(yè)的術(shù)語(yǔ)去寫的,太專業(yè)的術(shù)語(yǔ)哪里都有,習(xí)慣用自己的話去描述……
回復(fù)

使用道具 舉報(bào)

地板
ID:75926 發(fā)表于 2015-4-5 22:42 | 只看該作者
能理解,這是能是增強(qiáng)型才有的實(shí)時(shí)任務(wù)嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:70941 發(fā)表于 2015-4-5 22:43 | 只看該作者
xiaos 發(fā)表于 2015-4-5 22:42
能理解,這是能是增強(qiáng)型才有的實(shí)時(shí)任務(wù)嗎?

rtx51是普通型的也可以的……
回復(fù)

使用道具 舉報(bào)

6#
ID:74145 發(fā)表于 2016-6-4 17:06 | 只看該作者
有幫助
回復(fù)

使用道具 舉報(bào)

7#
ID:182843 發(fā)表于 2017-3-25 15:15 | 只看該作者
開始學(xué)些謝謝好文章
回復(fù)

使用道具 舉報(bào)

8#
ID:209652 發(fā)表于 2017-7-22 15:50 | 只看該作者
真是大牛,講了之后真是闊然開朗
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表