149 lines
4.3 KiB
C
149 lines
4.3 KiB
C
/*
|
||
* @Author:
|
||
* @Date: 2023-04-11 18:31:07
|
||
* @LastEditors: xxx
|
||
* @LastEditTime: 2023-08-25 11:27:12
|
||
* @Description:
|
||
* email:
|
||
* Copyright (c) 2023 by xxx, All Rights Reserved.
|
||
*/
|
||
|
||
#include "delay.h"
|
||
|
||
// static uint16_t g_fac_ms = 0; // ms延时倍乘数,在os下,代表每个节拍的ms数
|
||
static uint32_t g_fac_us = 0; /* us延时倍乘数 */
|
||
|
||
void SysTick_Init(void)
|
||
{
|
||
NVIC_SetPriority(SysTick_IRQn, 3);
|
||
LL_SYSTICK_EnableIT();
|
||
}
|
||
/**
|
||
* @brief 初始化延迟函数
|
||
* @param sysclk: 系统时钟频率, 即CPU频率(rcc_c_ck)
|
||
* @retval 无
|
||
*/
|
||
void delay_init(uint16_t sysclk)
|
||
{
|
||
#if SYS_SUPPORT_OS /* 如果需要支持OS */
|
||
uint32_t reload;
|
||
#endif
|
||
// SysTick_Init();
|
||
// LL_SetSystemCoreClock(LL_SYSTICK_CLKSOURCE_HCLK); /* SYSTICK使用内核时钟源,同CPU同频率 */
|
||
g_fac_us = sysclk; /* 不论是否使用OS,g_fac_us都需要使用 */
|
||
// Remove the redundant assignment statement
|
||
#if SYS_SUPPORT_OS /* 如果需要支持OS. */
|
||
reload = sysclk; /* 每秒钟的计数次数 单位为M */
|
||
reload *= 1000000 / configTICK_RATE_HZ; /* 根据delay_ostickspersec设定溢出时间,reload为24位
|
||
* 寄存器,最大值:16777216,在168M下,约合0.099s左右
|
||
*/
|
||
g_fac_ms = 1000 / configTICK_RATE_HZ; // 代表OS可以延时的最少单位
|
||
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; /* 开启SYSTICK中断 */
|
||
SysTick->LOAD = reload; /* 每1/delay_ostickspersec秒中断一次 */
|
||
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* 开启SYSTICK */
|
||
#endif
|
||
}
|
||
|
||
/**
|
||
* @brief 延时nus
|
||
* @param nus: 要延时的us数.
|
||
* @note 注意: nus的值,不要大于34952us(最大值即2^24 / g_fac_us @g_fac_us = 168)
|
||
* @retval 无
|
||
*/
|
||
void delay_us(uint32_t nus)
|
||
{
|
||
uint32_t ticks;
|
||
uint32_t told, tnow, tcnt = 0;
|
||
uint32_t reload = SysTick->LOAD; /* LOAD的值 */
|
||
ticks = nus * g_fac_us; /* 需要的节拍数 */
|
||
told = SysTick->VAL; /* 刚进入时的计数器值 */
|
||
while (1)
|
||
{
|
||
tnow = SysTick->VAL;
|
||
if (tnow != told)
|
||
{
|
||
if (tnow < told)
|
||
{
|
||
tcnt += told - tnow; /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */
|
||
}
|
||
else
|
||
{
|
||
tcnt += reload - tnow + told;
|
||
}
|
||
told = tnow;
|
||
if (tcnt >= ticks)
|
||
{
|
||
// __NOP();
|
||
break; /* 时间超过/等于要延迟的时间,则退出 */
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 对指定的硬件定时器进行微秒级延时
|
||
*
|
||
* 使用指定的硬件定时器进行延时操作,延时时间为微秒级。
|
||
*
|
||
* @param timer_us 指向硬件定时器的指针
|
||
* @param us 需要延时的微秒数
|
||
*/
|
||
void delay_hardware_us(TIM_TypeDef *timer_us, uint32_t us)
|
||
{
|
||
RESET_TIM_COUNT(timer_us);
|
||
while (LL_TIM_GetCounter(timer_us) < us)
|
||
; // 等待计数器达到指定值
|
||
}
|
||
|
||
/**
|
||
* @brief 延迟指定微秒数的硬件延迟函数
|
||
*
|
||
* 使用指定的定时器实现微秒级的硬件延迟。
|
||
*
|
||
* @param timer_us 指向定时器的指针,用于实现延迟功能
|
||
* @param us 需要延迟的微秒数
|
||
*/
|
||
void delay_hardware_ms(TIM_TypeDef *timer_us, uint32_t ms)
|
||
{
|
||
while (ms--)
|
||
{
|
||
delay_hardware_us(timer_us, 1000); // 每毫秒延时1000微秒
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 延时nms
|
||
* @param nms: 要延时的ms数 (0< nms <= 65535)
|
||
* @retval 无
|
||
*/
|
||
void delay_ms(uint16_t nms)
|
||
{
|
||
uint32_t repeat = nms / 30; /* 这里用30,是考虑到可能有超频应用 */
|
||
uint32_t remain = nms % 30;
|
||
|
||
while (repeat)
|
||
{
|
||
delay_us(30 * 1000); /* 利用delay_us 实现 1000ms 延时 */
|
||
repeat--;
|
||
}
|
||
|
||
if (remain)
|
||
{
|
||
delay_us(remain * 1000); /* 利用delay_us, 把尾数延时(remain ms)给做了 */
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 延时函数,用于模拟硬件延时。
|
||
* @param {uint32_t} ticks
|
||
* @return {*}
|
||
* @note: 请注意,这个函数仅用于模拟硬件延时,实际应用中可能需要使用其他延时函数,如HAL_Delay或rt_delay。
|
||
*/
|
||
void delay_tick(uint32_t ticks)
|
||
{
|
||
while (ticks--)
|
||
{
|
||
__NOP();
|
||
}
|
||
}
|