打印

GD32F450+TIM定时器

[复制链接]
809|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kepe|  楼主 | 2024-3-31 12:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
GD32Fxx+TIM定时器(1)
定时器基本功能使用
时钟初始化
定时器初始化
时钟初始化:此处使用TIMER1
rcu_periph_clock_enable(RCU_TIMER1);
1
定时器初始化
定时器初始化需要配置计数周期,计数方式等等。通常我们只需要初始化一个结构体这些就完成了,如下:

   timer_parameter_struct timer_init_struct;//定义结构体
  timer_init_struct.alignedmode = TIMER_COUNTER_EDGE;
  timer_init_struct.clockdivision = TIMER_CKDIV_DIV1;
  timer_init_struct.counterdirection = TIMER_COUNTER_UP;
  timer_init_struct.period = 999;
  timer_init_struct.prescaler = 107;
  timer_init_struct.repetitioncounter = 0;
  timer_init(TIMER1,&timer_init_struct);
  timer_enable(TIMER1);
  • 定义的结构体类型每个型号的单片机不一样,可以去移植的官方库文件里面去找,类似于下图gd32f10x_timer.c里面。



使用特权

评论回复
沙发
kepe|  楼主 | 2024-3-31 12:19 | 只看该作者
点进去可以查看结构体的定义

typedef struct
{
    uint16_t prescaler;                         /*!< prescaler value */
    uint16_t alignedmode;                       /*!< aligned mode */
    uint16_t counterdirection;                  /*!< counter direction */
    uint32_t period;                            /*!< period value */
    uint16_t clockdivision;                     /*!< clock division value */
    uint8_t  repetitioncounter;                 /*!< the counter repetition value */
}timer_parameter_struct;

使用特权

评论回复
板凳
kepe|  楼主 | 2024-3-31 12:20 | 只看该作者
prescaler
定时器预分频系数,分频后的时钟驱动计数器计数,就是定时器的计数频率。

通过官方手册可知,预分频寄存器的范围是0-65535,实际的预分频值= 预分频寄存器值+1。所以我们想使分频系数为x的话,prescaler = x-1;

使用特权

评论回复
地板
kepe|  楼主 | 2024-3-31 12:20 | 只看该作者
我们要知道定时器的频率从哪来的。通过查看用户手册。

使用特权

评论回复
5
kepe|  楼主 | 2024-3-31 12:20 | 只看该作者
通过时钟树可以看到TIMER1的时钟是通过APB1得到的,APB1的时钟是通过AHB得到的,AHB的时钟是通过外部晶振或者内部时钟得到的。通过system_gd32f10x.c可以知道我们用的是外部还是内部时钟。

使用特权

评论回复
6
kepe|  楼主 | 2024-3-31 12:20 | 只看该作者
此处用的外部时钟,时钟频率为108Mhz。往下找到defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)处可以看到具体的时钟配置。

使用特权

评论回复
7
kepe|  楼主 | 2024-3-31 12:21 | 只看该作者
通过上图可以知道AHB的频率为108Mhz,APB2为108Mhz,APB1为54Mhz。又通过时钟树知道

使用特权

评论回复
8
kepe|  楼主 | 2024-3-31 12:21 | 只看该作者
如果APB1的分频为1,TIMERx的频率=APB1,不然TIMERx的频率=APB1x2,具体还要看对应芯片的手册。所以TIMER1的时钟频率为108Mhz。1HZ = 1s。prescaler = 107,定时器就会1us记一次数了。

alignedmode
定时器计数方式
向上计数:

在这种模式,计数器的计数方向是向上计数。计数器从0开始向上连续计数到自动加载值,一旦计数器计数到自动加载值,会重新从0开始向上计数并产生上溢事件。

向下计数:

在这种模式,计数器的计数方向是向下计数。计数器从自动加载值向下连续计数到0。一旦计数器计数到0,计数器会重新从自动加载值开始计数并产生下溢事件。

中央对齐计数:

在中央对齐计数模式下,计数器交替的从0开始向上计数到自动加载值,产生上溢事件。然后再向下计数到0,产生下溢事件。可以通过软件选择。

使用特权

评论回复
9
kepe|  楼主 | 2024-3-31 12:21 | 只看该作者
可选参数:

TIMER_COUNTER_EDGE//边沿计数
TIMER_COUNTER_CENTER_DOWN//中央对齐模式,只产生下溢事件
TIMER_COUNTER_CENTER_UP//中央对齐模式,只产生上溢事件
TIMER_COUNTER_CENTER_BOTH//中央对齐模式,上溢事件、下溢事件都选择

这里选择TIMER_COUNTER_EDGE这种模式,也就是向上,向下两种模式。

counterdirection
计数器计数方向,alignedmode选择TIMER_COUNTER_EDGE模式,这个参数才有用,不然这个参数是只读的。

可选参数:

TIMER_COUNTER_UP//向上计数模式
TIMER_COUNTER_DOWN//向下计数模式

这里我选择计时器向上计数TIMER_COUNTER_UP

period
计数器自动加载值。范围:0-65535。我想1ms产生一个事件,所以period = 999,为什么不是1000,因为计数器是从0开始的。

使用特权

评论回复
10
kepe|  楼主 | 2024-3-31 12:22 | 只看该作者
clockdivision
时钟分频。


通过手册可知我们一般用不上它。

可选参数:

TIMER_CKDIV_DIV1
TIMER_CKDIV_DIV2
TIMER_CKDIV_DIV4

选择TIMER_CKDIV_DIV1

使用特权

评论回复
11
kepe|  楼主 | 2024-3-31 12:22 | 只看该作者
repetitioncounter
重复寄存器,重复计数器是用来在N+1个计数周期之后产生更新事件,更新定时器的寄存器,N为这个参数的值,这个功能一般只有高级定时器才有,这里repetitioncounter = 0。

然后使能定时器timer_enable(TIMER1),初始化就完成了。

总结
定时器有很多用法,上面只是最基础的配置,如果有误,请大家多多指正,互相交流学习。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

101

帖子

0

粉丝