使用systick实现us延时,可以参考原子哥的教程。
定时器的方式实现us延时,可以在freertos中使用。
选择定时器
这里使用GD32H7的基本定时器Timer51。如果其他的定时器也可以的,只使用延时,有点浪费资源。
创建.c .h
.h内容
#include "gd32h7xx.h"
#define TIMEDELAY_TIMER TIMER51
#define TIMEDELAY_TIMER_IRQ TIMER51_IRQn
#define TIMEDELAY_TIMER_RCU RCU_TIMER51
void timer51_delay_config(void);
void timer51_delay_us(uint32_t us);
.c内容
配置部分比较简单
void timer51_delay_config(void)
{
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
/* -----------------------------------------------------------------------
TIMER configuration:
TIMERCLK = 300MHz/300 =1MHZ= 1us
----------------------------------------------------------------------- */
rcu_periph_clock_enable(TIMEDELAY_TIMER_RCU);
timer_deinit(TIMEDELAY_TIMER);
/* TIMER configuration */
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 300;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = (uint64_t)(0XFFFFFFFF);
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMEDELAY_TIMER, &timer_initpara);
timer_disable(TIMEDELAY_TIMER);
}
这里需要注意clockdivision 这个参数,手册上关于这个参数是保留的,也就是说配置无效,定时器的时钟频率取决于AHB 和APB的总线时钟。
period参数的设置只需要大于用到的最大值就行。
关键函数如下
void timer51_delay_us(uint32_t us)
{
1 timer_counter_value_config(TIMEDELAY_TIMER, 0);
2 timer_autoreload_value_config(TIMEDELAY_TIMER, us);
3 timer_enable(TIMEDELAY_TIMER);
4 while (timer_counter_read(TIMEDELAY_TIMER) < us);
5 timer_disable(TIMEDELAY_TIMER);
}
需要注意的是第一行,每次需要重新设置cnt的值;如果不设置,则会加载上次reload的值,直到计数到上面配置的period值,才会重新设置为0;
测试