本测试程序,配置GD32F103VE定时器0每500ms中断一次,中断时,开关LED灯。
只讲定时器,多了,有点乱。有的人喜欢汇总,Timer的功能太多,放在一起,会搞混,不好移植。即使放一起,也只能使用其中之一的功能。不必贪婪。测试程序如下:
#include "Timer0.h"
#include "LED.h"
void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc);
//函数功能:通用定时器0中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//Timer_Interrupt_Initializtion(TIMER0,50000,1080);//当arr=50000,psc=1080时,则为500ms,误差为10us;
void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc)
{
timer_parameter_struct TimerParameterStruct;
switch(timer_periph)
{
case TIMER0:
rcu_periph_clock_enable(RCU_TIMER0); //使能TIMER0的APB2外设时钟
nvic_irq_enable(TIMER0_UP_IRQn, 2U, 0U); //设置TIMER0_UP_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER1:
rcu_periph_clock_enable(RCU_TIMER1);
nvic_irq_enable(TIMER1_IRQn, 2U, 0U); //设置TIMER1_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER2:
rcu_periph_clock_enable(RCU_TIMER2);
nvic_irq_enable(TIMER2_IRQn, 2U, 0U); //设置TIMER2_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER3:
rcu_periph_clock_enable(RCU_TIMER3);
nvic_irq_enable(TIMER3_IRQn, 2U, 0U); //设置TIMER3_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER4:
rcu_periph_clock_enable(RCU_TIMER4);
nvic_irq_enable(TIMER4_IRQn, 2U, 0U); //设置TIMER4_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER5:
rcu_periph_clock_enable(RCU_TIMER5);
nvic_irq_enable(TIMER5_IRQn, 2U, 0U); //设置TIMER5_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
case TIMER6:
rcu_periph_clock_enable(RCU_TIMER6);
nvic_irq_enable(TIMER6_IRQn, 2U, 0U); //设置TIMER6_IRQn的中断优先级,抢占优先级为2,子优先级为0
break;
default:
break;
}
timer_deinit(timer_periph); //复位TIMERx
TIMERx配置开始
TimerParameterStruct.period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TimerParameterStruct.prescaler = psc-1; //设置用来作为TIMx时钟频率除数的预分频值(APB2时钟分频值)
TimerParameterStruct.clockdivision = TIMER_CKDIV_DIV1; //设置时钟分母值为1
//计算公式:arr*psc/108000000/1,当arr=250,psc=108时,则为0.25ms,误差为1us;
TimerParameterStruct.counterdirection = TIMER_COUNTER_UP; //设置计数方向为"向上计数"
TimerParameterStruct.alignedmode = TIMER_COUNTER_EDGE; //设置为无中央对齐计数模式(边沿对齐模式)
TimerParameterStruct.repetitioncounter = 0; //设置"重复计数次数"为0
timer_init(timer_periph,&TimerParameterStruct);//根据TimerParameterStruct所指向的参数初始化TIMERx的时间基数单位
TIMERx配置结束
timer_counter_value_config(timer_periph,0);//设置TIMERx的计数器初始值为0
//timer_counter_read(timer_periph);//读取TIMERx的计数器值
timer_auto_reload_shadow_enable(timer_periph);//使能TIMERx自动重装载
timer_flag_clear(timer_periph,TIMER_FLAG_UP); //清除"TIMERx更新标志位"
timer_interrupt_flag_clear(timer_periph,TIMER_INT_FLAG_UP); //清除"TIMERx更新中断标志位"
timer_interrupt_enable(timer_periph,TIMER_INT_UP); //使能"TIMERx更新"产生中断
timer_internal_clock_config(timer_periph);//设置"内部时钟"作为定时器时钟
//timer_slave_mode_select(timer_periph,TIMER_SLAVE_MODE_DISABLE);
//设置"关闭从模式",如果TIMER计数器使能,则预分频器直接由内部时钟驱动
timer_enable(timer_periph);//TIMERx计数器使能,开始工作
}
//函数功能:TIMER0更新中断服务程序
void TIMER0_UP_IRQHandler(void)
{
if( timer_interrupt_flag_get(TIMER0,TIMER_INT_FLAG_UP) )// 读取更新中断标志位
{
MCU_Led_Toggle();
timer_flag_clear(TIMER0,TIMER_FLAG_UP); //清除"TIMER0更新标志位"
timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_UP); //清除"更新中断标志位"
}
}
#include "LED.h"
void LED_Init(void);
//函数功能:初始化MCU_Led
void LED_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOD);//使能GPIOD时钟,enable GPIO clock
gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
//将GPIOD15设置为输出上拉
MCU_Led_Off();
// GPIO_BC(GPIOD) = GPIO_PIN_15;//清除GPIOD15输出,GPIO bit clear register
}
#ifndef __LED_H
#define __LED_H
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#define MCU_Led_Off() GPIO_BOP(GPIOD)=GPIO_PIN_15 //GD15输出高电平
#define MCU_Led_On() GPIO_BC(GPIOD)=GPIO_PIN_15 //GD15输出低电平
#define MCU_Led_Toggle() gpio_bit_write( GPIOD,GPIO_PIN_15,(bit_status)((1-gpio_input_bit_get(GPIOD,GPIO_PIN_15))) )
//GD15取反输出电平
extern void LED_Init(void);
#endif
main.c程序如下:
#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "delay.h"
#include "LED.h"
#include "Timer0.h"
int main(void)
{
//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
INTX_ENABLE();//开启所有中断
LED_Init();//初始化MCU_Led
delay_init();//系统时钟配置
Timer_Interrupt_Initializtion(TIMER0,50000,1080);//设置TIMER0中断周期为500ms,误差为10us;
while(1)
{
delay_ms(200);//软件延时200ms
}
}