consoleyou 发表于 2024-5-27 09:27:29

要怎么样才能实现“非阻塞延时”?

新手在学习单片机的时候,学习的延时函数都是“阻塞延时”,
MCU为了延时不停在做无用功,占用了算力、资源。
要怎么样才能做到“非阻塞延时”呢?

_奶咖君_ 发表于 2024-5-27 09:29:14

定时器,。

_奶咖君_ 发表于 2024-5-27 09:30:54

不需要特别精准的话,自己估算一下while循环一圈的时间 用一种软定时,

Lkck8210 发表于 2024-5-27 09:58:08

以下是一个流水灯的两种写法
void main()
{
        uchar i;
        while(1)
        {
                for(i=0;i<8;i++)
                {
                        P2 = ~(0x01<<i);
                        delay(200);
                }
        }
}

void main()
{
        uchar i = 0;
        uint DelayCnt = 2000;
        while(1)
        {
                DelayCnt++;
                if(DelayCnt>=2000)
                {
                        DelayCnt = 0;
                        P2 = ~(0x01<<i);
                        i++;
                        if(i>=8)i=0;
                }
        }
}

_奶咖君_ 发表于 2024-5-27 10:08:23

Lkck8210 发表于 2024-5-27 09:58
以下是一个流水灯的两种写法

对对 软定时就是下面那种写法

zhange 发表于 2024-5-27 10:08:51

新手就用阻塞延时就行慢慢学习你就会其他的{:4_188:}

soma 发表于 2024-5-27 10:18:02

软件延时还是有一定必要要使用的

jwd 发表于 2024-5-27 10:36:16

定时器设置标志位,比如你需要1ms定时,就配置1ms的定时器,中断后置标志位,主程序用这个标志位让变量A+1,清零标志位,你需要定时多长时间,就让A加到多少数

xxxevery 发表于 2024-5-27 11:45:55

不要直接使用毫秒级的延时函数,使用毫秒级延时的函数放到定时中断里去执行,但是微秒级的延时函数也还是不可避免阻塞,该用还是得用,不用太纠结,看实际情况再定呗

未元星系 发表于 2024-5-27 11:53:18

我最近也在学,可以用定时器进行延时,这是我做的用定时器和中断让LED闪烁的方案,while循环里添别的程序不干扰
void Timer0_Init(void)//定时1ms
{
      AUXR |= 0x80;//设置定时器为1T模式,即不分频
      TMOD &= 0xF0;//保留高四位(定时器1),低四位全为0:设置定时器/计数器0为定时器、GATE置0、16位自动重装模式
      TL0 = 0x3F;         //初始值65535 - 24000 = 41535 = 1010 0010 0011 1111,即高8位为0xA2,低8位为0x3F
      TH0 = 0xA2;         //
      TF0 = 0;                  //清零TF0中断标志位
      TR0 = 1;                  //定时器开始计时
      ET0 = 1;       //开启定时器0中断
}

void main()
{
      P2M0 = 0x00; P2M1 = 0x00;   //P2口设为准双向口模式
      Timer0_Init();                  //初始化定时器0
      EA = 1;                                  //打开总中断
      P2 = 0x00;                  //P2口8个LED灯全亮
      while(1){}                  //死循环
}

static unsigned int Timer1_num = 0;         //初始化定时变量
void Timer0_interrupt(void) interrupt 1   //定时器0中断
{
      Timer1_num ++;                            //当定时器完成一次定时,即1ms,Timer1_num加一
      if(Timer1_num == 500)                     //延时500ms
      {
                Timer1_num = 0;                         //清零定时变量
                P2 = ~(P2);                           //反转P2口
      }
}
页: [1] 2 3
查看完整版本: 要怎么样才能实现“非阻塞延时”?