[研电赛技术支持] GD32基于定时器输入捕获

[复制链接]
49|0
八层楼 发表于 2026-2-4 10:11 | 显示全部楼层 |阅读模式

1.0 输入捕获

86126981858918abe.png

2.0 信号周期

75918698185830bff0.png

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

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

3.0 定时器配置

960256981857a6555f.png

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);
}





编译结果:

811846981855cc4a29.png

————————————————
版权声明:本文为CSDN博主「_沧浪之水_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45973003/article/details/144242822
176586981852661a27.png
6227369818536ab60b.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

154

主题

4499

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部
0