阻塞式编程和非阻塞式编程区别

   日期:2020-10-08     浏览:100    评论:0    
核心提示:很多单片机的初学者容易掉入阻塞式编程的陷阱.因为阻塞式编程符合我们对现实世界的理解,一个人在一段时间内,只能做一件事情.例如要是实现1Hz的闪灯程序,那么先让单片机端口拉高500ms,然后再拉低500ms,然后循环.因为等待时间太长了,没有打开看门狗.下面是阻塞式编程的例子:#include "extern.h"BIT LED : PA.3; BIT LED1 : PA...

       很多单片机的初学者容易掉入阻塞式编程的陷阱.因为阻塞式编程符合我们对现实世界的理解,一个人在一段时间内,只能做一件事情.例如要是实现1Hz的闪灯程序,那么先让单片机端口拉高500ms,然后再拉低500ms,然后循环.因为等待时间太长了,没有打开看门狗.

下面是阻塞式编程的例子:
#include    "extern.h"


BIT     LED            :        PA.3;  

BIT     LED1           :        PA.4;  



void    FPPA0 (void)
{
    
    .ADJUST_IC    SYSCLK=IHRC/2    
   
    $ LED  out ,low;

   $ LED1  out ,low;

   
    while (1)
    {
        
        LED=1;
      
       .delay 8000*500;
         
        LED=0;
       
       .delay 8000*500;
    }
}

OK 完美运行.

但是,当要你再加上一个指示灯,要2Hz闪烁,也就是250ms关,250ms开,然后循环,那要怎么办了.

OK继续,刚刚辛辛苦苦写好的程序得重新写了.


void    FPPA0 (void)
{
    
    .ADJUST_IC    SYSCLK=IHRC/2    
   
    $ LED  out ,low;

   $ LED1  out ,low;


    while (1)
    {
        
        LED=1;

       LED1=1;
      
       .delay 8000*250;

     LED=1;

     LED1=0;

     
       .delay 8000*250;
        LED=0;

       LED1=1;

     
       .delay 8000*250;

     LED=0;

     LED1=0;

     
       .delay 8000*250;
    }
}

OK,完美运行,要加上按键呢?怎么办,感觉越来越麻烦了.

 

        其实,单片机干起事情来比我们想象得要快得多.例如8M的主频,1T的单片机,在1S钟之内就可以执行8,000,000条指令.在很多时候,我们几乎可以忽略单片机在执行两条指令的时间差,也就是说虽然单片机程序是顺序执行的,在人看来效果和并行执行没有任何差别.不能让单片机在等待.LED开/关其实就是一条指令的事.做好定时就OK了,那定时怎么做呢?用定时中断,配置定时器每100us产生一次中断,那么计数10次就是1ms.在while循环里查询这个1ms标记并进行计数就可以进行定时了.

下面来个非阻塞式程序的案例.

#include "extern.h"

#define  HIGH 1

#define  LOW    0

#define DISABLE 0

#define ENABLE 1

 

#define EMPTY 0

#define FULL 1

 

#define ON 1

#define OFF 0

BIT     LED        :        PA.3;

BIT     LED1     :     PA.4;

 

word   usLedTmrCnt;

word   usLedTmrCnt1;

 

bit     FLAG_NMS;

byte count;

word T16COUNTER;

void    TIME16_Init(void)

{

T16COUNTER =488;

FLAG_NMS =0;

 

$ INTEN T16;

INTRQ = 0;

  

    T16M.5 =0;               

STT16 T16COUNTER;

$ T16M IHRC,/1,BIT11;     

}

void FPPA0 (void)

{

    .ADJUST_IC SYSCLK=IHRC/2, IHRC=16MHz, VDD=3.5V,init_ram;

$ CLKMD IHRC/2,En_IHRC,En_ILRC,En_WatchDog;

    $  LED     OUT,LOW;

 $  LED1    OUT,LOW;

    TIME16_Init();

 engint;

 

while (1)

{

         wdreset;

     

         if ( FLAG_NMS )

         {       

                 usLedTmrCnt++;

                   if(usLedTmrCnt>499)

                   {

                            usLedTmrCnt=0;

                           

                             if(LED)

                             {

                                       LED=0;

                              }

                            else

                           {

                                          LED=1;

                             }

                    }

#if 1

                                usLedTmrCnt1++;

                              if(usLedTmrCnt1>249)

                                {

                                                    usLedTmrCnt1=0;

                                                       

                                                             if(LED1)

                                                            {

                                                                          LED1=0;

                                                             }

                                                            else

                                                            {

                                                                                LED1=1;

                                                             }

                                 }

#endif

                     

                          FLAG_NMS=0;

                  }

         }

}

 

void Interrupt ( void )

{

pushaf;

if ( Intrq.T16 )  

{

Intrq.T16 = 0;

STT16 T16COUNTER;

if ( count>0 )

{

count--;

}

else

{

count   =   9;

FLAG_NMS=   1;  

     }

}

popaf;

}

           给LED 和LED1各分配一个计数器,可以设置1-65535ms的翻转时间.LED亮/灭只需要一条指令.其他的时候就查询一下1ms标记,有就计数,当计数值溢出的时候就把LED进行翻转.就这么简单.各自独立,没有长时间的等待,看门狗也打开了.在端口和内存允许的情况下还可以添加N个.在这个框架下,还可以扩展按键,显示.....

    这里并不是说阻塞式的程序不好,而是有一定的局限性.在写简单的应用中也很好用.很直观.

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服