【修订记录】
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--);
}
/******************************************************************************/