STM32用定时器4的微妙和毫秒的延时函数

void udelay(int us)

{

    extern TIM_HandleTypeDef        htim4;
    TIM_HandleTypeDef *hHalTim = &htim4;

    uint32_t ticks;
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = __HAL_TIM_GET_AUTORELOAD(hHalTim);

    ticks = us * reload / (1000);  /* 假设reload对应1ms */
    told = __HAL_TIM_GET_COUNTER(hHalTim);
    while (1)
    {
        tnow = __HAL_TIM_GET_COUNTER(hHalTim);
        if (tnow != told)
        {
            if (tnow > told)
            {
                tcnt += tnow - told;
            }
            else
            {
                tcnt += reload - told + tnow;
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }

}



void mdelay(int ms)
{
    for (int i = 0; i < ms; i++)
        udelay(1000);
}

/**********************************************************************
 * 函数名称: system_get_ns
 * 功能描述: 获得系统时间(单位ns)
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 系统时间(单位ns)
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2023/08/03	     V1.0	  韦东山	      创建
 ***********************************************************************/
uint64_t system_get_ns(void)
{
    //extern uint32_t HAL_GetTick(void);
    extern TIM_HandleTypeDef        htim4;
    TIM_HandleTypeDef *hHalTim = &htim4;
    
    uint64_t ns = HAL_GetTick();
    uint64_t cnt;
    uint64_t reload;

    cnt = __HAL_TIM_GET_COUNTER(hHalTim);
    reload = __HAL_TIM_GET_AUTORELOAD(hHalTim);

    ns *= 1000000;
    ns += cnt * 1000000 / reload;
    return ns;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
定时器中断中使用延时函数是不可取的,因为延时函数会阻塞CPU,导致其他任务无法执行。在定时器中断中,应该使用定时器计数器来实现延时。具体实现方法如下: 1. 在定时器初始化中,设置定时器的自动重载值和时钟分频系数,以及使能定时器中断。 2. 在定时器中断处理函数中,使用定时器计数器的值来实现延时。例如,如果定时器的时钟频率为1MHz,定时器计数器的自动重载值为1000,那么定时器中断周期为1ms。在定时器中断处理函数中,每进入一次中断,就将一个计数器加1。当计数器达到所需的延时时间时,执行需要延时的操作。 以下是一个简单的示例代码: ```c volatile uint32_t timer_count = 0; // 定时器计数器 void TIM_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); timer_count++; // 每进入一次中断,计数器加1 } } void delay_ms(uint32_t ms) { timer_count = 0; // 重置计数器 TIM_Cmd(TIM2, ENABLE); // 启动定时器 while (timer_count < ms); // 等待计数器达到所需的延时时间 TIM_Cmd(TIM2, DISABLE); // 停止定时器 } int main(void) { // 初始化定时器 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 自动重载值为1000 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 时钟分频系数为72 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_EnableIRQ(TIM2_IRQn); while (1) { delay_ms(1000); // 延时1秒 // 执行需要延时的操作 } } ``` 需要注意的是,在使用定时器计数器实现延时时,计数器的精度会受到定时器时钟的影响,因此在进行延时操作时需要仔细计算定时器的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值