STM8S自学笔记-005 延时函数的3种方式
STM8S自学笔记-005 精准延时
- 精准延时
- 延时功能的底层驱动
- 延时功能的应用层
【修订记录】
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_TIM2CLK_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_TIM4CLK_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_TIM2TIM2_Cmd(NewState);
#elif DELAY_METHOD == DELAY_TIM4TIM4_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_SOFTwhile (us--){DELAY_APL_Delay1us();}#elif DELAY_METHOD == DELAY_TIM2uint16_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_TIM4uint8_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_SOFTuint16_t i; /* Type = u16 (Must) */while (ms--){for (i = 900;i > 0; i--){DELAY_APL_Delay1us();}}#elif DELAY_METHOD == DELAY_TIM2while (ms--){DELAY_APL_Delayus(1000);}#elif DELAY_METHOD == DELAY_TIM4while (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--);
}/******************************************************************************/