GD32单片机设置us级延时

发布时间 2023-04-05 16:24:14作者: LX2020

us延时会在很多外设驱动的时候用到,但是GD32提供的资料里面没有看到,只有一个ms延时的函数,不过GD32用的和stm32是一样的内核,因此也可以套用stm32嘀嗒定时器的版本,就是直接用stm32的思路来实现,这里直接贴代码:

说明一下实验平台:

  • GD32F470ZG
  • 立创梁山派开发板

代码如下:

#include "delay.h"

// #define USE_BLOCK
#ifdef USE_BLOCK


/* 和正点原子一样的延时方式,cpu死等,适用于时间比较短的方式 */
void delay_ms(uint32_t ms)
{
    SysTick->LOAD = SystemCoreClock / 1000 - 1; // 设置SysTick定时器为1毫秒
    SysTick->VAL = 0; // 设置初值为0
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 使能计数器

    for (uint16_t i = 0; i < ms; i++) {
        while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {
            // 循环等待计数到达目标值
        }
    }

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
    SysTick->VAL = 0; // 时间到了溢出后要记得清空
}

void delay_us(uint32_t us)
{
    SysTick->LOAD = SystemCoreClock / 1000000 - 1; // 设置SysTick定时器为1毫秒
    SysTick->VAL = 0; // 设置初值为0
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 使能计数器

    for (uint16_t i = 0; i < us; i++) {
        while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {
            // 循环等待计数到达目标值
        }
    }

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭计数器
    SysTick->VAL = 0; // 时间到了溢出后要记得清空
}

#else

/* 下面的方式是systick中断实现的,从逻辑分析仪看到的数据,效果更好一点 */
void delay_us(uint32_t us)
{
    uint32_t start_tick = SysTick->VAL;
    uint32_t us_tick = us * (SystemCoreClock / 1000000);
    while ((start_tick - SysTick->VAL) < us_tick) {
        // 等待
    }
}

void delay_ms(uint32_t ms)
{
    for (uint32_t i = 0; i < ms; i++) {
        delay_us(1000);
    }
}

#endif // DEBUG

上面提供了两种方式来实现,区别是第一种是忙等的方式,第二种是中断的方式,可以根据自己的需求适当选择。