STM8S自学笔记-005 延时函数的3种方式


【修订记录】
1、20210807,第一版
2、20210813,错字修订
3、20230206,增加定时器硬件延时
4、20230207,硬件延时方式增加

精准延时

软件延时不必多说,CSDN上已经有很多开发者贡献了代码,我也是抄他们的。
硬件延时也是抄的,我的工作是把两者结合在了一起,用延时方式宏定义做了编译区分,并进行了模块化设计。

延时功能的底层驱动

延时方法的配置宏DELAY_METHOD ,位于delay_hal.h中。
目前有3种:软件延时,TIM2延时,TIM4延时。

/**
  ******************************************************************************
  * @file    delay_hal.c 
  * @author  
  * @version V1.0.0
  * @date    DD-MM-YYYY
  * @brief   
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "delay_hal.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Variables -----------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Functions -----------------------------------------------------------------*/
/**
  * @brief  Timer Init for Delay
  * @param  None
  * @retval None
  */
void DELAY_HAL_TimerInit(void)
{
#if     DELAY_METHOD == DELAY_TIM2
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);       /*  */
    TIM2_DeInit();
    TIM2_TimeBaseInit(TIM2_PRESCALER_1, 65535);     /* time_cnt_MAX = (65535 * DIV / 16)(us) */
    TIM2_Cmd(DISABLE);
    
#elif   DELAY_METHOD == DELAY_TIM4
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE);       /*  */
    TIM4_DeInit();
    TIM4_TimeBaseInit(TIM4_PRESCALER_64, 255);      /* time_cnt_MAX = (255 * DIV / 16)(us) */
    TIM4_Cmd(DISABLE);
#endif
}

/**
  * @brief  
  * @param  None
  * @retval None
  */
void DELAY_HAL_TimerCmd(FunctionalState NewState)
{
#if     DELAY_METHOD == DELAY_TIM2
    TIM2_Cmd(NewState);
#elif   DELAY_METHOD == DELAY_TIM4
    TIM4_Cmd(NewState);
#endif
}



/******************************************************************************/

延时功能的应用层

在硬件延时的微秒级函数中,可考虑增加变量value的溢出防止对策。

/**
  ******************************************************************************
  * @file    delay_apl.c 
  * @author  
  * @version V1.0.0
  * @date    DD-MM-YYYY
  * @brief   
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "delay_apl.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Variables -----------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void DELAY_APL_Delay1us(void);

/* Functions -----------------------------------------------------------------*/
/**
  * @brief  Delay 1 us
  * @param  None
  * @retval None
  */
#pragma optimize = none
static void DELAY_APL_Delay1us(void)
{
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
}

/**
  * @brief  Delay 1 us @ SYSCLK = 16MHz
  * @param  us: the time to wait
  * @retval None
  */
#pragma optimize = none
void DELAY_APL_Delayus(uint32_t us)
{
#if     DELAY_METHOD == DELAY_SOFT
    while (us--)
    {
        DELAY_APL_Delay1us();
    }
    
#elif   DELAY_METHOD == DELAY_TIM2
    uint16_t value = us * 16 / 1;           /* DIV_1 */
    
    TIM2_SetCounter(0);                     /* Clear Counter REG */
    TIM2_Cmd(ENABLE);                       /* Start Countor */
    while (TIM2_GetCounter() < value);      /* Wait */
    TIM2_Cmd(DISABLE);                      /* Stop Countor */
    
#elif   DELAY_METHOD == DELAY_TIM4
    uint8_t value = us * 16 / 64;           /* DIV_64 */
    
    TIM4_SetCounter(0);                     /* Clear Counter REG */
    TIM4_Cmd(ENABLE);                       /* Start Countor */
    while (TIM4_GetCounter() < value);      /* Wait */
    TIM4_Cmd(DISABLE);                      /* Stop Countor */
#endif
}

/**
  * @brief  Delay 1 ms
  * @param  ms: the time to wait
  * @retval None
  */
#pragma optimize = none
void DELAY_APL_Delayms(uint32_t ms)
{
#if     DELAY_METHOD == DELAY_SOFT
    uint16_t i;                             /* Type = u16 (Must) */
    
    while (ms--)
    {
        for (i = 900;i > 0; i--)
        {
            DELAY_APL_Delay1us();
        }
    }
    
#elif   DELAY_METHOD == DELAY_TIM2
    while (ms--)
    {
        DELAY_APL_Delayus(1000);
    }
    
#elif   DELAY_METHOD == DELAY_TIM4
    while (ms--)
    {
        DELAY_APL_Delayus(1000);
    }
#endif    
}

/**
  * @brief  DELAY_APL_Delay
  * @param  n: the time to wait
  * @retval None
  */
#pragma optimize = none
void DELAY_APL_Delay(uint32_t n)
{
    uint32_t m = n;
    while (m--);
}



/******************************************************************************/
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值