精华内容
下载资源
问答
  • STM32延时函数

    2020-06-02 14:03:47
    延时函数滴答定时器实现定时器 滴答定时器实现 虽然SysTick已经被配置为1ms中断一次的模式,但每个1ms之间SysTick的当前值寄存器是一直在计数的(每计一个数的时间是1/SytemCoreClock)我们便可以利用该机制实现微秒...

    滴答定时器实现

    虽然SysTick已经被配置为1ms中断一次的模式,但每个1ms之间SysTick的当前值寄存器是一直在计数的(每计一个数的时间是1/SytemCoreClock)我们便可以利用该机制实现微秒延时函数。
    可直接添加至delay.c使用

    //注释描述下一条语句
    void delay_us(uint32_t us)
    {
        __IO uint32_t currentTicks = SysTick->VAL;
      
      /* 每毫秒的滴答数 */
      const uint32_t tickPerMs = SysTick->LOAD + 1;
      
      /* 需计数的滴答数; /1000,就是把1ms分成1000份,因此us延时要在1ms内,超过1ms的延时就是用HAL库的HAL_Delay()延时*/   
      const uint32_t nbTicks = (us * tickPerMs) / 1000;
      
      /* 经过的滴答数 */
      uint32_t elapsedTicks = 0;
      __IO uint32_t oldTicks = currentTicks;
      do {
        currentTicks = SysTick->VAL;
        elapsedTicks += (oldTicks < currentTicks) ? tickPerMs + oldTicks - currentTicks : oldTicks - currentTicks;
        oldTicks = currentTicks;
      } while (nbTicks > elapsedTicks); //经过的滴答数大于等于需计数的滴答数就完成延时了
    }
    ————————————————
    版权声明:本文为CSDN博主「Apex-yuan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xiaoyuanwuhui/article/details/104667635
    

    定时器

    不可直接使用, 需配置定时器

    void Delay(__IO uint32_t nTime)
    {     
        /* 清零计数器 */  
        TIM2->CNT   = 0;  
        /* 使能计数器 */
        TIM_Cmd(TIM2, ENABLE);     
    
        for( ; nTime > 0 ; nTime--)
        {
         /* 等待一个延时单位的结束 */
         while(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) != SET);
         TIM_ClearFlag(TIM2, TIM_FLAG_Update);
        }
        /* 释放计数器 */
        TIM_Cmd(TIM2, DISABLE);
    }
    
    展开全文
  • STM32笔记】STM32 延时函数的实现 在MCU编程中,微秒延时和毫秒延时使用最为频繁,在RTOS中,毫秒延时可以由系统提供,可是微秒延时却需要开发人员编写。本文基于STM32F407ZG芯片实现几种微秒延时操作。 1、定时器...

    在MCU编程中,微秒延时和毫秒延时使用最为频繁,在RTOS中,毫秒延时可以由系统提供,可是微秒延时却需要开发人员编写。本文基于STM32F407ZG芯片实现几种微秒延时操作。

    1、定时器延时

    STM32F407里提供的定时器有:

    • 高级定时器:TIM1和TIM8,16位定时器
    • 通用定时器:TIM2到TIM5,TIM9到TIM14,16位定时器
    • 基本定时器:TIM6和TIM7,16位定时器

    时钟总线:在这里插入图片描述

    image-20210123135456834

    本文采用基本定时器TIM6来作为微秒延时的定时器。

    定时器6初始化:

    /**
     * @brief  TIM6初始化 
     * @note   84MHz时钟频率,时钟分频84,每个CNT计数1us,16位定时器,最大可计数65535us
     */
    void tim6Init(void)
    {
      TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);  /* 初始化时钟 */
    
    	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
    	
    	TIM_TimeBaseInitStructure.TIM_Period        = 65535;                  /* 最大计数 */ 	
    	TIM_TimeBaseInitStructure.TIM_Prescaler     = (84-1);                 /* 定时器分频,分频后频率为1MHz,最低1us定时 */ 
    	TIM_TimeBaseInitStructure.TIM_CounterMode   = TIM_CounterMode_Down;   /* 向下计数 */
    	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;           /* 时钟分频 */
    
    	TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStructure);                    /* 初始化 */
    	TIM_Cmd(TIM6,ENABLE);                                                 /* 使能定时器 */
    }
    

    关闭定时器:

    /**
     * @brief  关闭定时器 
     * @note   延时结束后关闭定时器
     */
    void tim6Stop(void)
    {
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,DISABLE);
      TIM_Cmd(TIM6,DISABLE); 
    }
    

    微秒延时:

    /**
     * @brief  微秒延时 
     * @param  uint32_t nUs  延时数
     */
    void delayUs(uint32_t nUs)
    {
      volatile uint32_t startCnt = 0;
    
      (nUs >= 65535) ? (nUs = 65536) : (nUs = nUs);     /* 16位定时器,最大计数延时65535us */
    
      tim6Init();   /* 初始化定时器 */
    
      startCnt = TIM6->CNT;
    
      while((TIM6->CNT-startCnt) < nUs);
    
      tim6Stop();
    }
    

    以上代码在单线程裸机系统中,在准确度上可以满足MCU的微秒延时使用;但是在多线程的RTOS中,会因为在多线程中同时调用微秒延时,导致线程A在while里等待延时时,定时器被线程B关闭,CPU无法释放。

    微秒延时(代码段保护):

    /**
     * @brief  微秒延时 
     * @param  uint32_t nUs  延时数
     */
    void delayUs(uint32_t nUs)
    {
      volatile uint32_t startCnt = 0;
    
      (nUs >= 65535) ? (nUs = 65535) : (nUs = nUs);     /* 16位定时器,最大计数延时65535us */
    
      rt_enter_critical();            /* 进入保护段,禁止系统调度 */
    
      tim6Init();   /* 初始化定时器 */
    
      startCnt = TIM6->CNT;
    
      while((TIM6->CNT-startCnt) < nUs);
    
      tim6Stop();
    
      rt_exit_critical();             /* 离开保护段 */
    }
    

    2、嘀嗒定时器(中断方式)

    STM32的cotex内核上提供了一个嘀嗒定时器(SysTick),嘀嗒定时器是一个24位的计时器,向下计数的方式,当计数倒数到0时,将从RELOAD寄存器里自动重装载值。只要CTRL寄存器的ENABLE位不被清除,则嘀嗒定时器用不停止。

    可以用嘀嗒定时器为系统提供微秒延时。

    嘀嗒定时器初始化:

    /**
     * @brief  嘀嗒定时器初始化 
     * @param  {type}
     * @retval none
     */
    void sysTickInit(void)
    {
      RCC_GetClocksFreq(&RCC_Clocks);     /* 获取系统时钟 */
      SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);   /* 配置嘀嗒为1ms */
      SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;         /* 关闭嘀嗒 */
    }
    

    延时实现:

    volatile uint32_t delayTimer;
    
    /**
     * @brief  嘀嗒中断服务函数 
     * @param  {type}
     * @retval none
     */
    void SysTick_Handler(void)
    {
      if(delayTimer)
      {
        delayTimer --;
      }
    }
    
    /**
     * @brief  延时函数 
     * @param  {type}
     * @retval none
     */
    void delay(uint32_t nTimer)
    {
      delayTimer = nTimer;
    
      SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;           /* 开启嘀嗒 */
    
      while(delayTimer);
    
      SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;         /* 关闭嘀嗒 */
    }
    

    3、嘀嗒定时器(查询)

    中断方式会频繁打断系统,可以使用查询嘀嗒计数器的方式完成延时。
    image-20210123152205616
    image-20210123152355015
    image-20210123152625792

    在此贴上一段RT-TRHEAD的嘀嗒初始化函数:

    /**
     * @brief  嘀嗒定时器初始化 
     * @note   使用RT-THREAD的嘀嗒初始化,嘀嗒超时事件1ms,嘀嗒时钟8分频
     */
    void SysTick_Configuration(void)
    {
      RCC_ClocksTypeDef  rcc_clocks;
      rt_uint32_t         cnts;
    
      RCC_GetClocksFreq(&rcc_clocks);
    
      cnts = (rt_uint32_t)rcc_clocks.HCLK_Frequency / 1000;
      cnts = cnts / 8;
    
      SysTick_Config(cnts);
      SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
    }
    
    /**
     * This is the timer interrupt service routine.
     *
     */
    void SysTick_Handler(void)
    {
        /* enter interrupt */
        rt_interrupt_enter();
    
        rt_tick_increase();			/* 系统时间片累加 */
    		
        /* leave interrupt */
        rt_interrupt_leave();	
    }
    

    时钟8分频,每1ms完成一次中断,每1ms完成一次系统时间片的累加计数。

    初始化后的嘀嗒重装载值(SysTick->RELOAD)为:
    168000000 / 1000 / 8 = 21000 168000000 / 1000 / 8 = 21000 168000000/1000/8=21000
    嘀嗒计数满21000个值,时间刚好是1ms,故每一次计数的时间为:
    ( 0.001 s / 21000 ) s (0.001 s / 21000) s (0.001s/21000)s
    嘀嗒定时器延时实现:

    /**
     * @brief  微秒延时 
     * @param  {type}
     * @retval none
     */
    void delayUs(uint32_t nUs)
    {
      uint32_t ticks;
    	uint32_t told,tnow,tcnt=0;
    	uint32_t reload=SysTick->LOAD;	
    
    	rt_enter_critical();
    	
    	ticks = nUs*(168 >> 3); 		//168 MHZ		
    	told  = SysTick->VAL;       
       			
    	while(1)
    	{
    		tnow = SysTick->VAL;	
    
    		if(tnow != told)
    		{	    
    			if(tnow < told)
    			{
    				tcnt += told - tnow;
    			}
    			else 
    			{
    				tcnt += reload - tnow + told;	
    			}		
    
    			told = tnow;
    
    			if(tcnt >= ticks)
    			{
    				break;
    			}				
    		}  
    	}
    
    	rt_exit_critical();
    }
    

    最低的延时时间为1us。

    1. 完成1us需要嘀嗒定时器VAL的计数值:

      前面计算的每一次计数时间为:(0.001 s / 21000) s,

      完成1us需要的计数为:
      t i c k s = 1 u s / ( 0.001 s / 21000 ) = 21 ticks = 1us / (0.001s / 21000) = 21 ticks=1us/(0.001s/21000)=21

    展开全文
  • STM32延时函数讲解

    2020-08-10 13:45:40
    Systick 主要的作用就是拿来计时,其原理和应用简述一下就是这样的:通过配置寄存器 SysTick->CTRL来设定Systick的计时频率并Enable使Systick开始计数,这里的 SysTick->CTRL&=0xfffffffb应该很好理解,把第2位设定...
  • STM32延时函数的四种方法

    万次阅读 多人点赞 2020-06-12 10:01:15
    本文基于STM32F207介绍4种不同方式实现的延时函数。 1、普通延时 这种延时方式应该是大家在51单片机时候,接触最早的延时函数。这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,在某些...

    目录

    1、普通延时

    2、定时器中断

    3、查询定时器

    4、汇编指令


    单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us()和毫秒级delay_ms()。本文基于STM32F207介绍4种不同方式实现的延时函数。

    1、普通延时

    这种延时方式应该是大家在51单片机时候,接触最早的延时函数。这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,在某些编译器下,代码会被优化,导致精度较低,用于一般的延时,对精度不敏感的应用场景中。

    //微秒级的延时
    void delay_us(uint32_t delay_us)
    {    
      volatile unsigned int num;
      volatile unsigned int t;
    
      
      for (num = 0; num < delay_us; num++)
      {
        t = 11;
        while (t != 0)
        {
          t--;
        }
      }
    }
    //毫秒级的延时
    void delay_ms(uint16_t delay_ms)
    {    
      volatile unsigned int num;
      for (num = 0; num < delay_ms; num++)
      {
        delay_us(1000);
      }
    }

    上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template

    2、定时器中断

    定时器具有很高的精度,我们可以配置定时器中断,比如配置1ms中断一次,然后间接判断进入中断的次数达到精确延时的目的。这种方式精度可以得到保证,但是系统一直在中断,不利于在其他中断中调用此延时函数,有些高精度的应用场景不适合,比如其他外设正在输出,不允许任何中断打断的情况。

    STM32任何定时器都可以实现,下面我们以SysTick 定时器为例介绍:

    初始化SysTick 定时器:

    /* 配置SysTick为1ms */
    RCC_GetClocksFreq(&RCC_Clocks);
    SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);

    中断服务函数:

    void SysTick_Handler(void)
    {
      TimingDelay_Decrement();
    }
    void TimingDelay_Decrement(void)
    {
      if (TimingDelay != 0x00)
      { 
        TimingDelay--;
      }
    }

    延时函数:

    void Delay(__IO uint32_t nTime)
    {
      TimingDelay = nTime;
      while(TimingDelay != 0);
    }

    上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template

    3、查询定时器

    为了解决定时器频繁中断的问题,我们可以使用定时器,但是不使能中断,使用查询的方式去延时,这样既能解决频繁中断问题,又能保证精度。

    STM32任何定时器都可以实现,下面我们以SysTick 定时器为例介绍。

    STM32的CM3内核的处理器,内部包含了一个SysTick定时器,SysTick是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。

    SYSTICK的时钟固定为HCLK时钟的1/8,在这里我们选用内部时钟源120M,所以SYSTICK的时钟为(120/8)M,即SYSTICK定时器以(120/8)M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器。

                                           ▼CTRL:控制和状态寄存器

                                           ▼LOAD:自动重装载除值寄存器

                                            ▼VAL:当前值寄存器

                                     ▼CALIB:校准值寄存器

    使用不到,不再介绍

    示例代码

    void delay_us(uint32_t nus)
    {
      uint32_t temp;
      SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000000/8*nus;
      SysTick->VAL=0X00;//清空计数器
      SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
      do
      {
        temp=SysTick->CTRL;//读取当前倒计数值
      }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
      SysTick->CTRL=0x00; //关闭计数器
      SysTick->VAL =0X00; //清空计数器
    }
    void delay_ms(uint16_t nms)
    {
      uint32_t temp;
      SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;
      SysTick->VAL=0X00;//清空计数器
      SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
      do
      {
        temp=SysTick->CTRL;//读取当前倒计数值
      }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
      SysTick->CTRL=0x00; //关闭计数器
      SysTick->VAL =0X00; //清空计数器
    }

    上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/04-Delay

    4、汇编指令

    如果系统硬件资源紧张,或者没有额外的定时器提供,又不想方法1的普通延时,可以使用汇编指令的方式进行延时,不会被编译优化且延时准确。

    STM32F207在IAR环境下

    /*!
     *  @brief 	软件延时 
     *  @param	ulCount:延时时钟数
     *  @return none
     *	@note 	ulCount每增加1,该函数增加3个时钟
     */
    void SysCtlDelay(unsigned long ulCount)
    {
        __asm("    subs    r0, #1\n"
              "    bne.n   SysCtlDelay\n"
              "    bx      lr");
    }

    这3个时钟指的是CPU时钟,也就是系统时钟。120MHZ,也就是说1s有120M的时钟,一个时钟也就是1/120 us,也就是周期是1/120 us。3个时钟,因为执行了3条指令。

    使用这种方式整理ms和us接口,在Keil和IAR环境下都测试通过。

    /*120Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/120us=1/40us*/
    /*
    SystemCoreClock=120000000
    
    us级延时,延时n微秒
    SysCtlDelay(n*(SystemCoreClock/3000000));
    
    ms级延时,延时n毫秒
    SysCtlDelay(n*(SystemCoreClock/3000));
    
    m级延时,延时n秒
    SysCtlDelay(n*(SystemCoreClock/3));
    */
    
    #if defined   (__CC_ARM) /*!< ARM Compiler */
    __asm void
    SysCtlDelay(unsigned long ulCount)
    {
        subs    r0, #1;
        bne     SysCtlDelay;
        bx      lr;
    }
    #elif defined ( __ICCARM__ ) /*!< IAR Compiler */
    void
    SysCtlDelay(unsigned long ulCount)
    {
        __asm("    subs    r0, #1\n"
           "    bne.n   SysCtlDelay\n"
           "    bx      lr");
    }
    
    #elif defined (__GNUC__) /*!< GNU Compiler */
    void __attribute__((naked))
    SysCtlDelay(unsigned long ulCount)
    {
        __asm("    subs    r0, #1\n"
           "    bne     SysCtlDelay\n"
           "    bx      lr");
    }
    
    #elif defined  (__TASKING__) /*!< TASKING Compiler */                           
    /*无*/
    #endif /* __CC_ARM */

    上述工程源码仓库:https://github.com/strongercjd/STM32F207VCT6/tree/master/03-ASM

     

    备注:

    理论上:汇编方式的延时也是不准确的,有可能被其他中断打断,最好使用us和ms级别的延时,采用for循环延时的函数也是如此。采用定时器延时理论上也可能不准确的,定时器延时是准确的,但是可能在判断语句的时候,比如if语句,判断延时是否到了的时候,就在判断的时候,被中断打断执行其他代码,返回时已经过了一小段时间。不过汇编方式和定时器方式,只是理论上不准确,在实际项目中,这两种方式的精度已经足够高了。

     

    点击查看本文所在的专辑,STM32F207教程

     

    关注公众号,第一时间收到文章更新。评论区不能及时看到,需要交流可以到公众号沟通

    展开全文
  • 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要...

    单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。

    1.普通延时法

    这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。

    //粗延时函数,微秒
    void delay_us(u16 time)
    {    
       u16 i=0;  
       while(time--)
       {
          i=10;  //自己定义
          while(i--) ;    
       }
    }
    //毫秒级的延时
    void delay_ms(u16 time)
    {    
       u16 i=0;  
       while(time--)
       {
          i=12000;  //自己定义
          while(i--) ;    
       }
    }
    

    2.SysTick 定时器延时

    CM3 内核的处理器,内部包含了一个SysTick 定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。SysTick 在STM32的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。

    这里面也有两种方式实现:

    a.中断方式 如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。

    volatile unsigned long time_delay; // 延时时间,注意定义为全局变量
    //延时n_ms
    void delay_ms(volatile unsigned long nms)
    {
        //SYSTICK分频--1ms的系统时钟中断
        if (SysTick_Config(SystemFrequency/1000))
        {
       
            while (1);
        }
        time_delay=nms;//读取定时时间
        while(time_delay);
        SysTick->CTRL=0x00; //关闭计数器
        SysTick->VAL =0X00; //清空计数器
    }
    //延时nus
    void delay_us(volatile unsigned long nus)
    {
     //SYSTICK分频--1us的系统时钟中断
        if (SysTick_Config(SystemFrequency/1000000))
        {
       
            while (1);
        }
        time_delay=nus;//读取定时时间
        while(time_delay);
        SysTick->CTRL=0x00; //关闭计数器
        SysTick->VAL =0X00; //清空计数器
    }
     
        //在中断中将time_delay递减。实现延时
     
    void SysTick_Handler(void)
    {
        if(time_delay)
            time_delay--;
    }
    

    b.非中断方式

    主要仿照原子的《STM32不完全手册》。SYSTICK 的时钟固定为HCLK 时钟的1/8,在这里我们选用内部时钟源72M,所以SYSTICK的时钟为9M,即SYSTICK定时器以9M的频率递减。SysTick 主要包含CTRL、LOAD、VAL、CALIB 等4 个寄存器,

    SysTick->CTRL

    位段名称类型复位值描述
    16COUNTFLAGR0如果在上次读本寄存器后systick已为0,则该位为1,若 读该位自动清零
    2CLKSOURCERW00:外部时钟源 1:内部时钟
    1TICKINTRW00:减到0无动作;1:减到0产生systick异常请求
    0ENABLERW0systick定时器使能位

    SysTick-> LOAD

    位段名称类型复位值描述
    23:0RELOADRW0减到0时被重新装载的值

    SysTick-> VAL

    位段名称类型复位值描述
    23:0CURRENTRW0读取时返回当前倒计数的值,写则清零,同时还会清除在systick控制及状态寄存器中的COUNTFLAG标志

    SysTick-> CALIB 不常用,在这里我们也用不到,故不介绍了。

    程序如下,相当于查询法。

    //仿原子延时,不进入systic中断
    void delay_us(u32 nus)
    {
     u32 temp;
     SysTick->LOAD = 9*nus;
     SysTick->VAL=0X00;//清空计数器
     SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
     do
     {
      temp=SysTick->CTRL;//读取当前倒计数值
     }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
         SysTick->CTRL=0x00; //关闭计数器
        SysTick->VAL =0X00; //清空计数器
    }
    void delay_ms(u16 nms)
    {
     u32 temp;
     SysTick->LOAD = 9000*nms;
     SysTick->VAL=0X00;//清空计数器
     SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
     do
     {
      temp=SysTick->CTRL;//读取当前倒计数值
     }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
        SysTick->CTRL=0x00; //关闭计数器
        SysTick->VAL =0X00; //清空计数器
    }
    

    三种方式各有利弊,第一种方式容易理解,但不太精准。第二种方式采用库函数,编写简单,由于中断的存在,不利于在其他中断中调用此延时函数。第三种方式直接操作寄存器,看起来比较繁琐,其实也不难,同时克服了以上两种方式的缺点,个人感觉比较好用。

    展开全文
  • stm32延时函数的三种写法

    千次阅读 2019-08-04 12:38:54
    我常用的延时函数有3种,一种是空循环,一种是使用systick中断,还有一种是正点原子的延时。 第一种就不做举例,因为平时不常用。但是一些模块给的参考代码的延时函数都会采用这样的方法,直接用就好了,不做赘述。 ...
  • STM32 延时函数高级用法分析

    千次阅读 2017-03-01 20:44:42
    一、使用场景第一种情况,在使用普通 STM32 延迟函数,类似于 HAL_Delay(time),由于该函数是使用循环去判断及延时的,所以在执行该函数时整个程序会在此处等待定时器的中断服务函数修改参量使得循环判决条件不成立...
  • STM32延时函数的三种方法——最好掌握第三种

    万次阅读 多人点赞 2018-08-05 11:04:58
    单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是...
  • STM32延时函数及流水灯简单实现

    千次阅读 2019-09-15 09:32:32
    一、C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。 方法一:使用for循环来延时 void delay...
  • stm32 延时函数

    千次阅读 2018-05-24 13:01:30
    //延时 n us//n us 为要延时的us数void delay_us(u32 nus){ u32 temp; SysTick-&gt;LOAD = 9*nus; SysTick-&gt;VAL = 0X00;//清空计数器 SysTick-&gt;CTRL =0X01;//使能,减到零是无动作,采用外部时钟 ...
  • STM32精确延时函数

    2014-03-06 12:26:59
    基于STM32滴答定时器的精确延时函数,分享给大家
  • STM32延时函数的三种方法:普通延时、SysTick 定时器延时(1.中断方式;2.非中断方式)   单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ms( )。 1.普通延时法 (1)...
  • STM32F0延时函数,用于ms及us延时
  • 使用汇编语言实现微秒精准延时及复位功能,移植方便 asm.c #include "asm.h" __asm void SysCtlDelay(u32 ulCount) { subs r0, #1; bne SysCtlDelay; bx lr; } __asm void SystemReset(...
  • STM32 延时函数解析

    万次阅读 2017-02-28 15:29:23
    一、函数原型STM32官方提供的函数库中,可以找到类似于 HAL_Delay() 这样的函数。这个函数的就是通过使用定时器,达到一个较为精确的时间延迟,提供给用户调用。这个函数一般包含在类似于 stm32f4xx_hal.c 这样的...
  • stm32软件延时定时器

    2018-09-20 22:46:56
    stm32软件延时定时器
  • STM32F103延时函数

    2016-02-17 17:09:54
    利用FOR循环,通过示波器观察,针对STM32F103进行的us,ms,s的延时,精度稍有误差,不影响使用
  • 基于stm32f103rc编写的精准延迟函数,delay(),主要有微秒级延迟,毫秒级延迟
  • STM32 延时函数封装

    2014-12-30 16:54:33
    延时模块函数 说明:只需在工程中加入delay.c和delay.h 文件,即可用 Delayms(__IO uint32_t nTime); Delayus(__IO uint32_t nTime) -----------------------------------*/ #ifndef
  • 第一:自己创建的工程文件根目录下的命名带有中文字样或...解决办法:(一)在自己工程下重新建一个用来存放延时函数的版级支持包,自己再板级支持包里面写一遍延时函数(二)将自己工程的根目录命名改为全英文 ...
  • 上代码 首先头文件timer.h #ifndef __TIMER_H_ ...#include "stm32f10x.h" void TIM2_init(u16 arr,u16 psc); __weak void Timer2_ISR(void); u32 F420_TICK(void); _Bool F420_CHECK_TIMEOUT(u32 ...
  • HAL 库有提供延时函数,只不过它只能实现简单的毫秒级别延时,没有实现 us 级别延时。 下面我们列出HAL 库实现延时相关的函数。首先是功能配置函数: //调用 HAL_SYSTICK_Config 函数配置每隔 1ms 中断一次 __weak ...
  • STM32基于HAL库实现的Delay延时函数(兼容操作系统和裸机),一贯的精简高效,无论是否用了操作系统,都可以实现高精度的延时功能。
  • STM32中精确延时函数的实现

    千次阅读 2020-05-12 20:39:59
    在与传感器或者模块的总线进行通信的时候,常常需要使用到精确延时,一般我们会封装几个常用延时函数,下面我们以STM32F103芯片为例,详细介绍一下STM32下一种精确延时函数的实现: 时钟树 下图中紫色的toCortex...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,457
精华内容 5,782
关键字:

stm32延时函数