GD32VF103_定时器中断

文章目录

    • 前言
    • 新建工程
    • 定时器
    • 定时器中断代码
    • 工程代码

前言

上节我们讲了 GD32VF103CBT6的点灯与按键的外部中断的NucleiStudio工程:
GD32VF103_环境配置_GPIO_外部中断
本节我们继续点灯, 只不过用定时器中断的方式2s翻转一次灯的状态.

新建工程

  • File -> New -> C/C++ Project, 选择C Managed Build
  • 选择GigaDevice RISC-V Project, 填入工程名
  • MCU默认暂时只有GD32VF103, 然后Demo也没法选, 只有Running_LED, 不变
  • 下一步, 完成.

定时器

具体可参考 GD32VF103用户手册:
GD32VF103_定时器中断_第1张图片
我们要做的就是 设置预分频器降频, 向上计数到预设的计数值就产生了定时器中断, 中断中清除中断标志位, 定时器会自动加载计数值, 重新从0开始计数.

定时器中断代码

main.c我们删掉代码, 重新改为:

#include "gd32vf103.h"
#include "systick.h"

#define LED_PIN 	  GPIO_PIN_7
#define LED_GPIO_PORT GPIOA
#define LED_GPIO_CLK  RCU_GPIOA

void led_config(void) {
	rcu_periph_clock_enable(LED_GPIO_CLK);	//enable the peripherals clock
	gpio_init(LED_GPIO_PORT, GPIO_MODE_OUT_PP,
			GPIO_OSPEED_50MHZ, LED_PIN);	//GPIO output with push-pull
	GPIO_BC(LED_GPIO_PORT) = LED_PIN;	//bit clear
}

void led_toggle(void) {
	gpio_bit_write(LED_GPIO_PORT, LED_PIN,
			(bit_status)(1-gpio_input_bit_get(LED_GPIO_PORT, LED_PIN)));
}

void timer_config(uint32_t timer_periph, uint32_t time_interval_ms) {
    timer_parameter_struct timer_initpara;

    switch(timer_periph){
    case TIMER0:
    	rcu_periph_clock_enable(RCU_TIMER0);
    	break;
    case TIMER1:
        rcu_periph_clock_enable(RCU_TIMER1);
        break;
    case TIMER2:
        rcu_periph_clock_enable(RCU_TIMER2);
        break;
    case TIMER3:
        rcu_periph_clock_enable(RCU_TIMER3);
        break;
    case TIMER4:
        rcu_periph_clock_enable(RCU_TIMER4);
        break;
    case TIMER5:
        rcu_periph_clock_enable(RCU_TIMER5);
        break;
    case TIMER6:
        rcu_periph_clock_enable(RCU_TIMER6);
        break;
    default:
    	break;
    }

    timer_deinit(timer_periph);
    timer_struct_para_init(&timer_initpara);
    timer_initpara.prescaler         = 10799;	//108M/10800 = 10K Hz
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = (uint32_t)10*time_interval_ms;//(uint32_t)1000000U/time_interval_us;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_init(timer_periph, &timer_initpara);

    timer_interrupt_enable(timer_periph, TIMER_INT_UP);	//update interrupt
    timer_enable(timer_periph);
}

int main(void) {
	led_config();

	eclic_global_interrupt_enable();
	eclic_set_nlbits(ECLIC_GROUP_LEVEL3_PRIO1);
	eclic_irq_enable(TIMER3_IRQn,1,0);

	timer_config(TIMER3, 2000);	//2s

	while(1) {

	}
	return 0;
}

void TIMER3_IRQHandler(void) {
	if(SET == timer_interrupt_flag_get(TIMER3, TIMER_INT_FLAG_UP)){
		/* clear channel 0 interrupt bit */
		timer_interrupt_flag_clear(TIMER3, TIMER_INT_FLAG_UP);
		led_toggle();
	}
}

我们设置定时器预分配(prescaler)为10799, 也就是定时器的时钟为108M / 10800 = 10K Hz, 一个周期计数 2000 * 10 = 20K, 所以一个周期 20K / 10K = 2s.

调试运行, 可以看到灯2s翻转一次状态.

工程代码

https://download.csdn.net/download/weifengdq/11940038

你可能感兴趣的:(RISC-V)