日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

  • 回復(fù)
  • 收藏
  • 點(diǎn)贊
  • 分享
  • 發(fā)新帖

STM32之多任務(wù)裸機(jī)

       在嵌入式開發(fā)中,特別是工業(yè)控制中,外設(shè)比較多,比如串口通訊這塊,有GPS模塊,wifi模塊,RS485通訊,232通訊。還有十幾路的輸入采樣,8路輸出控制,按鍵事件,串口屏數(shù)據(jù)實(shí)時(shí)顯示事件等多種事件。大部分都會(huì)采用實(shí)時(shí)操作系統(tǒng),但是實(shí)時(shí)操作系統(tǒng)對(duì)RAM和ROM都有要求的,所以我們看看在單片機(jī)裸奔時(shí)如何高效的實(shí)現(xiàn)多任務(wù)處理。

        其實(shí)作為嵌入式工程師來說,大家大部分時(shí)間都一直忙碌于公司的項(xiàng)目,沒有時(shí)間做自己的東西,其實(shí)有空時(shí)多回頭看看自己多年來做的項(xiàng)目,可以把以前的積累沉淀一下。怎么做才能使整個(gè)單片機(jī)系統(tǒng)的框架更加簡(jiǎn)潔方便可靠。

總結(jié)出單片機(jī)大致應(yīng)用程序的架構(gòu)有三種:

1. 簡(jiǎn)單的前后臺(tái)順序執(zhí)行程序,這類寫法是大多數(shù)人使用的方法,不需用思考程序的具體架構(gòu),直接通過執(zhí)行順序編寫應(yīng)用程序即可。

2. 時(shí)間片輪詢法,此方法是介于順序執(zhí)行與操作系統(tǒng)之間的一種方法。

3. 操作系統(tǒng),此法應(yīng)該是應(yīng)用程序編寫的最高境界。

       如果你能轉(zhuǎn)換一下思路,不再把業(yè)務(wù)邏輯中各個(gè)模塊的關(guān)系看成基于因果(順序),而是基于時(shí)間,模塊間如果需要確定次序可以采用標(biāo)志位進(jìn)行同步。那么恭喜你,你已經(jīng)有了采用實(shí)時(shí)系統(tǒng)的思想,可以嘗試使用RT-thread等操作系統(tǒng)來完成你的項(xiàng)目了。但是,使用操作系統(tǒng)有幾個(gè)問題,第一是當(dāng)單片機(jī)資源有限的時(shí)候,使用操作系統(tǒng)恐怕不太合適;第二是學(xué)習(xí)操作系統(tǒng)本身有一定的難度,至少你需要花費(fèi)一定的時(shí)間;第三如果你的項(xiàng)目復(fù)雜度沒有那么高,使用操作系統(tǒng)有點(diǎn)大材小用。
全部回復(fù)(7)
正序查看
倒序查看
2021-04-13 15:27

主要分享時(shí)間片輪詢法

看看時(shí)間輪詢?nèi)绾螌?shí)現(xiàn)單片機(jī)邏輯程序的高效執(zhí)行基于定時(shí)器觸發(fā),調(diào)度效率高,最大化減少無效的代碼運(yùn)行時(shí)間將定時(shí)器與狀態(tài)機(jī)和偽線程語法融合到一個(gè)框架,任務(wù)函數(shù)可以有兩種寫法。具體看下怎么寫

#ifndef huihui
        #define huihui
        #define MAXTASKS 6   //事件任務(wù)的數(shù)量,根據(jù)需要而定
        extern  volatile unsigned char timers[MAXTASKS];
        #define _SS static unsigned char _lc=0; switch(_lc){default: 
        #define _EE ;}; _lc=0; return 255;
        #define WaitX(tickets)  do {_lc=(__LINE__+((__LINE__%256)==0))%256; return tickets ;} while(0); case (__LINE__+((__LINE__%256)==0))%256: 

        #define RunTask(TaskName,TaskID) do { if (timers[TaskID]==0) timers[TaskID]=TaskName(); }  while(0); 
        #define RunTaskA(TaskName,TaskID) { if (timers[TaskID]==0) {timers[TaskID]=TaskName(); continue;} }   //前面的任務(wù)優(yōu)先保證執(zhí)行

        #define CallSub(SubTaskName) do {unsigned char currdt; _lc=(__LINE__+((__LINE__%256)==0))%256; return 0; case (__LINE__+((__LINE__%256)==0))%256:  currdt=SubTaskName(); if(currdt!=255) return currdt;} while(0);
        #define InitTasks() {unsigned char i; for(i=MAXTASKS;i>0 ;i--) timers[i-1]=0; }
        #define UpdateTimers() {unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}

        #define SEM unsigned int 
        //初始化信號(hào)量
        #define InitSem(sem) sem=0;
        //等待信號(hào)量
        #define WaitSem(sem) do{ sem=1; WaitX(0); if (sem>0) return 1;} while(0);
        //等待信號(hào)量或定時(shí)器溢出, 定時(shí)器tickets 最大為0xFFFE
        #define WaitSemX(sem,tickets)  do { sem=tickets+1; WaitX(0); if(sem>1){ sem--;  return 1;} } while(0);
        //發(fā)送信號(hào)量
        #define SendSem(sem)  do {sem=0;} while(0);
#endif//終止

0
回復(fù)
2021-04-13 15:33
@lihui710884923
主要分享時(shí)間片輪詢法看看時(shí)間輪詢?nèi)绾螌?shí)現(xiàn)單片機(jī)邏輯程序的高效執(zhí)行基于定時(shí)器觸發(fā),調(diào)度效率高,最大化減少無效的代碼運(yùn)行時(shí)間將定時(shí)器與狀態(tài)機(jī)和偽線程語法融合到一個(gè)框架,任務(wù)函數(shù)可以有兩種寫法。具體看下怎么寫#ifndefhuihui      #definehuihui      #defineMAXTASKS6  //事件任務(wù)的數(shù)量,根據(jù)需要而定      extern  volatileunsignedchartimers[MAXTASKS];      #define_SSstaticunsignedchar_lc=0;switch(_lc){default:      #define_EE;};_lc=0;return255;      #defineWaitX(tickets)  do{_lc=(__LINE__+((__LINE__%256)==0))%256;returntickets;}while(0);case(__LINE__+((__LINE__%256)==0))%256:      #defineRunTask(TaskName,TaskID)do{if(timers[TaskID]==0)timers[TaskID]=TaskName();}  while(0);      #defineRunTaskA(TaskName,TaskID){if(timers[TaskID]==0){timers[TaskID]=TaskName();continue;}}  //前面的任務(wù)優(yōu)先保證執(zhí)行      #defineCallSub(SubTaskName)do{unsignedcharcurrdt;_lc=(__LINE__+((__LINE__%256)==0))%256;return0;case(__LINE__+((__LINE__%256)==0))%256:  currdt=SubTaskName();if(currdt!=255)returncurrdt;}while(0);      #defineInitTasks(){unsignedchari;for(i=MAXTASKS;i>0;i--)timers[i-1]=0;}      #defineUpdateTimers(){unsignedchari;for(i=MAXTASKS;i>0;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255))timers[i-1]--;}}      #defineSEMunsignedint      //初始化信號(hào)量      #defineInitSem(sem)sem=0;      //等待信號(hào)量      #defineWaitSem(sem)do{sem=1;WaitX(0);if(sem>0)return1;}while(0);      //等待信號(hào)量或定時(shí)器溢出,定時(shí)器tickets最大為0xFFFE      #defineWaitSemX(sem,tickets)  do{sem=tickets+1;WaitX(0);if(sem>1){sem--;  return1;}}while(0);      //發(fā)送信號(hào)量      #defineSendSem(sem)  do{sem=0;}while(0);#endif//終止

我們這次是5個(gè)事件

1.電壓采集

2.處理串口屏的數(shù)據(jù)1

3.處理串口屏的數(shù)據(jù)2

4.向上位機(jī)發(fā)送數(shù)據(jù)

5.AD采集數(shù)據(jù)上傳串口屏

unsigned char task0(){
_SS
  while(1)
  {
         
   WaitX(100);
          FXJ_DYCJ(); /*電壓采集*/
  }
_EE
}

unsigned char  task1(){
_SS
  while(1){
   
   WaitX(10);
         Usart2_PeiFangDeal();
  }
_EE
}

unsigned char  task2(){
_SS
  while(1){
   WaitX(100); 
   Usart1_ReceiveDeal();          
  }
_EE
}

unsigned char  task3(){
_SS
  while(1){
   WaitX(100); 
   
   USART2_Send();/*向上位機(jī)發(fā)送數(shù)據(jù)*/ 
  }
_EE
}
unsigned char  task4(){
_SS
  while(1){
   WaitX(200); 
    USART1_SendADC();/*向屏上發(fā)送采集的電壓信號(hào)*/
  }
_EE
}
定時(shí)這塊都是采用滴答定時(shí)器中斷,1ms為時(shí)標(biāo)void SysTick_Handler(void)
{
     UpdateTimers();
}
每1ms對(duì)定時(shí)時(shí)間執(zhí)行減一操作
{unsigned char i; for(i=MAXTASKS;i>0 ;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255)) timers[i-1]--;}}
主函數(shù)只需要調(diào)用事件就可以,可以設(shè)置任務(wù)函數(shù)的優(yōu)先級(jí)執(zhí)行
int main(void)
{
                BSP_Init();
            InitTasks(); //初始化任務(wù),給TIME清零
                
                while(1)
                {
                   RunTask(task0,0);
           RunTaskA(task1,1);              
           RunTaskA(task2,2); 
           RunTaskA(task3,3); 
           RunTaskA(task4,4);                         
                }
                        
 }

0
回復(fù)
iszjt
LV.5
4
2021-07-14 09:55

感謝樓主分享?。?!

請(qǐng)問STM32F103可以下載程序但連燈都點(diǎn)不了是為什么?

0
回復(fù)
魯珀特
LV.4
5
2021-07-19 22:38

個(gè)人感覺基于STM32的操作系統(tǒng)用起來不是那么方便,還是時(shí)間片輪詢的方式更能接近底層。

1
回復(fù)
airwill
LV.2
6
2021-07-27 14:30

STM32之多任務(wù)裸機(jī),  本文內(nèi)容和題目好像切合度不高。

怎么做才能使整個(gè)單片機(jī)系統(tǒng)的框架更加簡(jiǎn)潔方便可靠。這一點(diǎn)值得贊賞,做完一個(gè)項(xiàng)目回頭想一想,怎樣才能更好,是學(xué)習(xí)進(jìn)步的好方法。

多任務(wù)和裸機(jī)是個(gè)矛盾的說法。因?yàn)槿蝿?wù)一詞已經(jīng)再 OS 里嚴(yán)格定義。那就不妨理解成需要處理的多個(gè)事務(wù)吧

0
回復(fù)
2021-07-30 15:53
@airwill
STM32之多任務(wù)裸機(jī), 本文內(nèi)容和題目好像切合度不高。怎么做才能使整個(gè)單片機(jī)系統(tǒng)的框架更加簡(jiǎn)潔方便可靠。這一點(diǎn)值得贊賞,做完一個(gè)項(xiàng)目回頭想一想,怎樣才能更好,是學(xué)習(xí)進(jìn)步的好方法。多任務(wù)和裸機(jī)是個(gè)矛盾的說法。因?yàn)槿蝿?wù)一詞已經(jīng)再OS里嚴(yán)格定義。那就不妨理解成需要處理的多個(gè)事務(wù)吧

看自己理解了,沒啥,就是多個(gè)事件,裸機(jī)跑

0
回復(fù)
2021-08-05 18:49
@lihui710884923
主要分享時(shí)間片輪詢法看看時(shí)間輪詢?nèi)绾螌?shí)現(xiàn)單片機(jī)邏輯程序的高效執(zhí)行基于定時(shí)器觸發(fā),調(diào)度效率高,最大化減少無效的代碼運(yùn)行時(shí)間將定時(shí)器與狀態(tài)機(jī)和偽線程語法融合到一個(gè)框架,任務(wù)函數(shù)可以有兩種寫法。具體看下怎么寫#ifndefhuihui      #definehuihui      #defineMAXTASKS6  //事件任務(wù)的數(shù)量,根據(jù)需要而定      extern  volatileunsignedchartimers[MAXTASKS];      #define_SSstaticunsignedchar_lc=0;switch(_lc){default:      #define_EE;};_lc=0;return255;      #defineWaitX(tickets)  do{_lc=(__LINE__+((__LINE__%256)==0))%256;returntickets;}while(0);case(__LINE__+((__LINE__%256)==0))%256:      #defineRunTask(TaskName,TaskID)do{if(timers[TaskID]==0)timers[TaskID]=TaskName();}  while(0);      #defineRunTaskA(TaskName,TaskID){if(timers[TaskID]==0){timers[TaskID]=TaskName();continue;}}  //前面的任務(wù)優(yōu)先保證執(zhí)行      #defineCallSub(SubTaskName)do{unsignedcharcurrdt;_lc=(__LINE__+((__LINE__%256)==0))%256;return0;case(__LINE__+((__LINE__%256)==0))%256:  currdt=SubTaskName();if(currdt!=255)returncurrdt;}while(0);      #defineInitTasks(){unsignedchari;for(i=MAXTASKS;i>0;i--)timers[i-1]=0;}      #defineUpdateTimers(){unsignedchari;for(i=MAXTASKS;i>0;i--){if((timers[i-1]!=0)&&(timers[i-1]!=255))timers[i-1]--;}}      #defineSEMunsignedint      //初始化信號(hào)量      #defineInitSem(sem)sem=0;      //等待信號(hào)量      #defineWaitSem(sem)do{sem=1;WaitX(0);if(sem>0)return1;}while(0);      //等待信號(hào)量或定時(shí)器溢出,定時(shí)器tickets最大為0xFFFE      #defineWaitSemX(sem,tickets)  do{sem=tickets+1;WaitX(0);if(sem>1){sem--;  return1;}}while(0);      //發(fā)送信號(hào)量      #defineSendSem(sem)  do{sem=0;}while(0);#endif//終止

樓主寫代碼還是換行好看,好分析,避免出錯(cuò)不易查找。

0
回復(fù)
發(fā)