1-12 GD32基于定时器输入捕获

前言:


基于本人对相关知识回顾与思考,仅供学习参考


目录

前言:

1.0 输入捕获

 2.0 信号周期

3.0 定时器配置

4.0 定时器配置

5.0 定时器中断

后记:


1.0 输入捕获



 2.0 信号周期


获取信号周期的方法,在第一次捕获与第二次不会之间做差值运算,最后乘以计数周期得到信号周期。

还有月中方式是,在第一次获取计数寄存器数值时,将计数寄存器里面的数组设置为0,这样等到下一次计数时就能从0重新开始计数,通过这个方法就不用做差值运算了。


3.0 定时器配置


4.0 定时器配置


初始化GPIO 

static void GpioInit(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
}

开启GPIOA时钟,初始化GPIOA管脚,使用浮空输入,输入频率为10MHz,输入引脚为第0号引脚


使能定时器时钟

	// 使能定时器1时钟
	rcu_periph_clock_enable(RCU_TIMER1);
	// 复位定时器
	timer_deinit(TIMER1);

定时器初始化

	timer_parameter_struct timerInitPara;
	// 初始化定时器值
	timer_struct_para_init(&timerInitPara);
	// 设置预分频器的值
	timerInitPara.prescaler = 120 - 1;
	// 设置CRA重装计数器的值
	timerInitPara.period 	= 65536 - 1;
	// 定时器初始化
	timer_init(TIMER1, &timerInitPara);

定时器通道配置

	// 定时器输入捕获
	timer_ic_parameter_struct icInitPara;
	// 输入捕获通道赋初始值
	timer_channel_input_struct_para_init(&icInitPara);
	// 设置上升沿捕获/下降沿捕获
	icInitPara.icpolarity  = TIMER_IC_POLARITY_RISING;
	// 设置输入通道
	icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;
	timer_input_capture_config(TIMER1, TIMER_CH_0, &icInitPara);

使能定时器

	// 清除定时器中断标志位
	timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH0);
	// 使能定时器中断
	timer_interrupt_enable(TIMER1, TIMER_INT_CH0);

	// 使能定时器中断优先级
	nvic_irq_enable(TIMER1_IRQn, 0, 0);

	// 使能定时器
	timer_enable(TIMER1);

5.0 定时器中断

static uint32_t g_icValue;

void TIMER1_IRQHandler(void)
{
	if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0) == SET)
	{
		timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0);
		// 读取输入捕获寄存器里面的数值
		g_icValue = timer_channel_capture_value_register_read(TIMER1, TIMER_CH_0) + 1;
		// 将计数寄存器的数值清除为 0 
		timer_counter_value_config(TIMER1, 0);
	}
}

void CaptureDrvInit(void)
{
	GpioInit();
	TimerInit();
}

void CaptureDrvTest(void)
{
	printf("period is %d us.\n", g_icValue);
	DelayNms(500);
}

6.0 全部程序

|---------------------capture_drv.h---------------------|-------------------------
#ifndef _CAPTURE_DRV_H_
#define _CAPTURE_DRV_H_

void CaptureDrvInit(void);
void CaptureDrvTest(void);
#endif

|---------------------capture_drv.c---------------------|-------------------------
#include <stdint.h>
#include <stdio.h>
#include "gd32f30x.h"
#include "delay.h"

static void GpioInit(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
}

static void TimerInit(void)
{
	// 使能定时器1时钟
	rcu_periph_clock_enable(RCU_TIMER1);
	// 复位定时器
	timer_deinit(TIMER1);

	timer_parameter_struct timerInitPara;
	// 初始化定时器值
	timer_struct_para_init(&timerInitPara);
	// 设置预分频器的值
	timerInitPara.prescaler = 120 - 1;
	// 设置CRA重装计数器的值
	timerInitPara.period 	= 65536 - 1;
	// 定时器初始化
	timer_init(TIMER1, &timerInitPara);

	// 定时器输入捕获
	timer_ic_parameter_struct icInitPara;
	// 输入捕获通道赋初始值
	timer_channel_input_struct_para_init(&icInitPara);
	// 设置上升沿捕获/下降沿捕获
	icInitPara.icpolarity  = TIMER_IC_POLARITY_RISING;
	// 设置输入通道
	icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;
	timer_input_capture_config(TIMER1, TIMER_CH_0, &icInitPara);

	// 清除定时器中断标志位
	timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH0);
	// 使能定时器中断
	timer_interrupt_enable(TIMER1, TIMER_INT_CH0);

	// 使能定时器中断优先级
	nvic_irq_enable(TIMER1_IRQn, 0, 0);

	// 使能定时器
	timer_enable(TIMER1);
}

static uint32_t g_icValue;

void TIMER1_IRQHandler(void)
{
	if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0) == SET)
	{
		timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0);
		// 读取输入捕获寄存器里面的数值
		g_icValue = timer_channel_capture_value_register_read(TIMER1, TIMER_CH_0) + 1;
		// 将计数寄存器的数值清除为 0 
		timer_counter_value_config(TIMER1, 0);
	}
}

void CaptureDrvInit(void)
{
	GpioInit();
	TimerInit();
}

void CaptureDrvTest(void)
{
	printf("period is %d us.\n", g_icValue);
	DelayNms(500);
}



编译结果:

后记:

……

作者:_沧浪之水_

物联沃分享整理
物联沃-IOTWORD物联网 » 1-12 GD32基于定时器输入捕获

发表回复