GD32F303 Timer1定时器中断
主要特性
◼ 总通道数:4;
◼ 计数器宽度:16位;
◼ 时钟源可选:内部时钟,内部触发,外部输入,外部触发;
◼ 多种计数模式:向上计数,向下计数和中央计数;
◼ 正交编码器接口:被用来追踪运动和分辨旋转方向和位置;
◼ 霍尔传感器接口:用来做三相电机控制;
◼ 可编程的预分频器:16位,运行时可以被改变;
◼ 每个通道可配置:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式;
◼ 自动重装载功能;
◼ 中断输出和DMA请求:更新事件,触发事件,比较/捕获事件;
◼ 多个定时器的菊链使得一个定时器可以同时启动多个定时器;
◼ 定时器的同步允许被选择的定时器在同一个时钟周期开始计数;
◼ 定时器主-从管理。
结构图
通用定时器TIMER1时钟
如上图,timer1的时钟挂在APB1上,频率最大为60MHz。这里使用的就是60MHz。
时钟使能,令寄存器RCU_APB1EN 第 0 bit为1即可。
timer1的配置寄存器
主要使用上面框起来的寄存器即可
代码讲解
- timer.c
#include "timer.h"
void Timer1_init(uint16_t prescale, uint16_t period)
{
RCU_APB1EN |=(1<<0);//TIMER1时钟使能
TIMER_CTL0(TIMER1) = 0;//清除控制寄存器0配置
TIMER_CTL0(TIMER1) |=(0<<8);//通过软件配置CKDIV,规定定时器时钟(CK_TIMER) 与死区时间和数字滤波器采样时钟(DTS)之间的分频系数。:
//00:fDTS=fCK_TIMER;
//01:fDTS= fCK_TIMER /2;
//10:fDTS= fCK_TIMER /4;
//11:保留
TIMER_CTL0(TIMER1) |=(1<<7);//1:使能TIMERx_CAR寄存器的影子寄存器(自动重载影子使能)
TIMER_CTL0(TIMER1) |=(0<<5);//计数器对齐模式选择:00:无中央对齐计数模式(边沿对齐模式)。 DIR位指定了计数方向。其他值为中央对齐模式
TIMER_CTL0(TIMER1) |=(0<<4);//0:向上计数;1:向下计数
TIMER_CTL0(TIMER1) |=(1<<2);//选择更新事件源。1:下列事件会产生更新中断或DMA请求:计数器溢出/下溢
TIMER_CTL0(TIMER1) |=(0<<1);//该位用来使能或禁能更新事件的产生。0:更新事件使能.1:更新事件禁能.
TIMER_CTL1(TIMER1)=0;//清除控制寄存器1配置
TIMER_SMCFG(TIMER1) =0;//清除从模式配置寄存器配置
TIMER_SWEVG(TIMER1) =0;//软件事件产生寄存器清零
//时基配置
TIMER_CNT(TIMER1)=0;//计数器寄存器清零
TIMER_PSC(TIMER1) =prescale;//TIM_CLK=120MHz/(prescale+1)。计数器时钟等于TIMER_CK时钟除以(PSC+1),每次当更新事件产生时,PSC 的值被装入到对应的影子寄存器。
TIMER_CAR(TIMER1) =period;//计数器自动重载值
TIMER_DMAINTEN(TIMER1) =0;//清除DMA和中断使能寄存器
TIMER_INTF(TIMER1) =0;//中断标志位清零 【TIMER_INTF(TIMER0)&(1<<0) 为UPIF更新中断标志位:1:发生更新中断;0:无更新中断发生。】
TIMER_SWEVG(TIMER1) |=(1<<0);//更新事件产生:1:产生更新事件。此位由软件置1,被硬件自动清0。当此位被置1,如果选择了中央对齐或向上计数模式,计数器被清0。否则(向下计数模式)计数器将载入自动重载值,预分频计数器将同时被清除。
//配置NVIC,中断线28。具体配置请参考cortex-m4编程手册
NVIC->IP[28] =240;//优先级设置为240,最大为255
//28/32=1; 28%32=28.
NVIC->ISER[0]|=(1<<28);//使能28号的中断线
TIMER_DMAINTEN(TIMER1) |=(1<<0);//0:禁止更新中断;1:使能更新中断
TIMER_CTL0(TIMER1) |=(1<<0);//计数器使能:0:计数器禁能;1:计数器使能
}
uint8_t tog=0;
void TIMER1_IRQHandler(void)
{
if(TIMER_INTF(TIMER1)&(1<<0))//判断定时器更新标志位
{
TIMER_INTF(TIMER1) &=~(1<<0);//清更新标志位
//实现LED灯电平翻转
if(tog)
GPIO_BC(GPIOB)=GPIO_PIN_1;
else
GPIO_BOP(GPIOB)=GPIO_PIN_1;
tog=~tog;
}
}
- main.c
#include "gd32f30x.h"
#include <stdio.h>
#include "timer.h"
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
GPIO_BC(GPIOB)=GPIO_PIN_1;
Timer1_init(6000-1,15000-1);//1.5s
while (1);
}
实验现象
LED以1.5秒的间隔闪烁。