欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > 零基础国产GD32单片机编程入门(四)定时器详解及实战含源码

零基础国产GD32单片机编程入门(四)定时器详解及实战含源码

2024/10/24 18:20:54 来源:https://blog.csdn.net/zy2232652/article/details/141596156  浏览:    关键词:零基础国产GD32单片机编程入门(四)定时器详解及实战含源码

文章目录

    • 一.概要
    • 二.通用定时器内部结构
      • 1.时基单元
      • 2.时钟源
      • 3.输入捕获
      • 4.输出比较
    • 三.通用定时器内部特色
    • 四.TIME定时器1ms中断例程
    • 五.工程源代码下载
    • 六.小结

一.概要

定时器的简介
定时器就是计数器,应用在我们生活的方方面面,比如有闹钟、计时器等。在GD32F103C8T6定时器分为2类,即高级控制定时器(TIM0)、通用定时器(TIM1,TIM2,TIM3),要学会定时器要懂得分频设置、计数器设置。

1、高级定时器(TIM0)
高级定时器(TIM0)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器(TIM0)和通用定时器(TIM1,TIM2,TIM3)是完全独立的,它们不共享任何资源。

2、通用定时器(TIM1,TIM2,TIM3)
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。

高级定时器除了具备通用定时器的所有功能外,还支持更高级的功能,如定时器级联,还有面向更复杂的应用,如BLDC电机控制、高精度测量等。

我们以通用定时器为例,通用定时器能应付我们大部分使用场景,后面对定时器的内部构造,配置使用,实际使用进行一一讲解

二.通用定时器内部结构

定时器计时原理:
首先,设置预分频器的值,以确定输入到计数器的时钟频率。然后,设置自动装载寄存器的值,这个值决定了延时的长度。最后,启动定时器,开始计数。当计数器的值达到自动装载寄存器的值时,将触发一个中断,完成延时任务。通过调整预分频器和自动装载寄存器的值,可以实现不同长度的延时,从而满足不同的应用需求‌。
计数器、自动装载寄存器和预分频器寄存器这三个组成了时基单元。

通用定时器由4部分组成:①时基单元 ②时钟源 ③输入捕获 ④输出比较。

在这里插入图片描述

1.时基单元

可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。

在这里插入图片描述

时基单元包含:
● 计数器寄存器(TIMERx_CNT) :向上计数、向下计数或者中心对齐向计数,最常用是向上对齐。
● 预分频器寄存器 (TIMERx_PSC) :可将时钟频率按1到65536之间的任意值进行分频,可在运行时改变其设置值。
● 自动装载寄存器 (TIMERx_CAR) :
在向上计数模式中,计数器从0计数到自动装载寄存器值(TIMERx_CAR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。

ARSE=0,当TIMERx_CAR值被修改时,同时马上更新影子寄存器的值;ARSE=1,当TIMERx_CAR值被修改时,必须在下一次更新事件UPE发生后才能更新影子寄存器的值,当计数器产生溢出条件时,产生更新事件。

自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在
TIMERx_CTL0寄存器中的自动装载预装载使能位(ARSE)的设置,预装载寄存器的内容被立即或在每次的更新事件UPE时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件),产生更新事件。

在这里插入图片描述

上图中圈出来带了阴影的寄存器表示该寄存器存在影子寄存器,这些有影子寄存的寄存器在物理上对应了两个寄存器,一个是开放出来给程序员可以写入和读出的预装载寄存器(preloadregister),比如CAR,PSC,捕获/比较等寄存器;另一个并没有开放出来,即程序员看不见的、但在操作中真正起作用的影子寄存器(shadowregister)。

设计影子寄存器的好处:
每次发生更新事件(UPE)时,所有真正起作用的影子寄存器可以同时被更新为预装载寄存器 (preloadregister)里面的值,这样可以保证多个通道的操作能够准确同步;如果没有影子寄存器,预装载寄存器和影子寄存器 是直通的,当软件更新了预装载寄存器,也就立即更新了影子寄存器,由于软件不能同时更新多个影子寄存器,这就会导致多个通道的时序不能同步。

ARSE=0,当TIMERx_CAR值被修改时,同时马上更新影子寄存器的值;
ARSE=1,当TIMERx_CAR值被修改时,必须在下一次事件UPE发生后才能更新影子寄存器的值

2.时钟源

根据模式不同,选择的时钟源也不同:
如果定时器是选择主模式:
① 时钟源可以选择内部时钟 (TIMER_CK),计数器预分频器时钟源由内部时钟TIMER_CK驱动。

如果定时器是选择从模式:
①时钟源可以选择外部输入脚 (TIMERx_ETI):计数器预分频器可以在外部引脚ETI的每个上升沿或下降沿计数。
②时钟源可以选择TIMERx_CIx通过数字滤波器采样后的信号:计数器预分频器可以在TIMERx_CI0/ TIMERx_CI1引脚的每个上升沿或下降沿计数。
③时钟源可以选择ITI0/1/2/3:计数器预分频器也可以在内部触发信号ITI0/1/2/3的上升沿计数。
在这里插入图片描述

我们通常使用内部时钟 (TIMER_CK)作为时钟源

3.输入捕获

捕获模式允许通道测量一个波形时序,频率,周期,占空比等。输入级包括一个数字滤波器,一个通道极性选择,边沿检测和一个通道预分频器。如果在输入引脚上出现被选择的边沿,TIMERx_CHxCV寄存器会捕获计数器当前的值。

在这里插入图片描述

4.输出比较

在输出比较模式,TIMERx可以产生时控脉冲,其位置,极性,持续时间和频率都是可编程的。当一个输出通道的CxCV寄存器与计数器的值匹配时,根据CHxCOMCTL的配置,这个通道的输出可以被置高电平,被置低电平或者反转。

如下图所示,比如配置自动装载CAR=63, 输出通道CxCV=3,输出比较的时序图

在这里插入图片描述

三.通用定时器内部特色

在这里插入图片描述

四.TIME定时器1ms中断例程

1.硬件准备
STLINK接GD32F103C8T6开发板,STLINK接电脑USB口。

在这里插入图片描述
2.实验原理
通过配置定时器1每1mS进入中断一次,每进入中断服务程序一次,增加一次计数,计数
到达500,控制PB4引脚输出高或低电平,从而实现1S钟周期闪烁。

3.主要代码

//定时器配置
void timer_config(void)
{/* -----------------------------------------------------------------------系统主频108MHZ,timer_initpara.prescaler为107,timer_initpara.period为999,频率就为1KHZ----------------------------------------------------------------------- */timer_parameter_struct timer_initpara;rcu_periph_clock_enable(RCU_TIMER1);timer_deinit(TIMER1);/* TIMER1 configuration */timer_initpara.prescaler         = 107;//108M主频,分频后就是1M频率timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;timer_initpara.counterdirection  = TIMER_COUNTER_UP;timer_initpara.period            = 999;//1M频率,计数1000次,就是1mstimer_initpara.clockdivision     = TIMER_CKDIV_DIV1;timer_initpara.repetitioncounter = 0;timer_init(TIMER1,&timer_initpara);nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);nvic_irq_enable(TIMER1_IRQn, 0, 1);timer_interrupt_enable(TIMER1, TIMER_INT_UP);/* auto-reload preload enable */timer_auto_reload_shadow_enable(TIMER1);/* auto-reload preload enable */timer_enable(TIMER1);
}int main(void)
{rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);//AHB主频是1分频systick_config();//系统主频108MHZ,采用外部晶振,由两个宏决定(__SYSTEM_CLOCK_108M_PLL_HXTAL与HXTAL_VALUE)rcu_periph_clock_enable(RCU_AF);//管脚复用时钟alternate function clock使能delay_1ms(1000);//等待1秒gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);//PB4管脚默认是NJTRST,要当GPIO,需要重映射rcu_periph_clock_enable(RCU_GPIOB);//GPIOB时钟使能gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);//PB4配置成输出timer_config();//定时器初始化配置,1ms进入一次中断,TIMER1_IRQHandler()函数中实现LED闪烁while(1){}
}uint32_t Timcounter;
uint8_t  LedFlag;
//定时器溢出中断服务程序,配置的定时器溢出时间是1ms,所以1ms调用一次
void TIMER1_IRQHandler(void)
{timer_flag_clear(TIMER1,TIMER_FLAG_UP);Timcounter++;if(Timcounter>=500){Timcounter=0;LedFlag^=0x01;}if(LedFlag)//计数到500ms,翻转输出{gpio_bit_set(GPIOB,GPIO_PIN_4);//PB4输出高电平}else{gpio_bit_reset(GPIOB,GPIO_PIN_4);//PB4输出低电平}
}

五.工程源代码下载

通过百度网盘分享的文件:6.定时器1ms.zip
链接:https://pan.baidu.com/s/1NlLrGcL9Afk2hNkPXCmoQw
提取码:mmib

如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行
CSDN代码

六.小结

通过定时器周期性地产生中断信号,可以实现系统定时和时间戳等功能。例如,在智能家居系统中,可以使用定时器控制各种设备的开关,在工业控制系统中,定时器可以用于检测传感器数据并执行相应的动作,定时器还可以配合PWM模块实现对电机等设备的精确控制。通过定时器产生固定频率的方波信号,然后使用PWM模块将其转化为可调节占空比的脉冲信号,从而实现对电机速度和输出功率的控制。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com