CapSean 发表于 2021-4-25 10:57

GD32F305VG timer0输入捕获无反应

各位大佬好!      我按照GD32F30x的标准库配置了GD32F305VG 的timer0定时器并开启了输入捕获功能,配置代码如下:
void timer_config(void)
{
/* -----------------------------------------------------------------------
    timer_parameter_struct timer_initpara;
    timer_ic_parameter_struct timer_icinitpara;

    rcu_periph_clock_enable(RCU_TIMER0);

    timer_deinit(TIMER0);

    /*NVIC config*/
    nvic_irq_enable(TIMER0_UP_TIMER9_IRQn, 1, 1);
    nvic_irq_enable(TIMER0_Channel_IRQn, 1, 0);
    /* TIMER0 configuration */
    timer_initpara.prescaler         = 119;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection= TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    timer_initpara.clockdivision   = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);

    timer_icinitpara.icpolarity      = TIMER_IC_POLARITY_RISING;
    timer_icinitpara.icselection   = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler   = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter      = 0x0;
    timer_input_capture_config(TIMER0, TIMER_CH_0, &timer_icinitpara);

    timer_input_capture_config(TIMER0, TIMER_CH_3, &timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER0);
    timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_CH0);
    timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_CH3);
    timer_interrupt_enable(TIMER0,TIMER_INT_CH0);
    timer_interrupt_enable(TIMER0,TIMER_INT_CH3);
    timer_interrupt_enable(TIMER0,TIMER_INT_UP);
    timer_enable(TIMER0);
}


/*中断服务程序*/
void TIMER0_UP_TIMER9_IRQHandler(void) {

if ( timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_UP) != RESET ) {
    timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_UP);
    timer0tick++;
}
}

void TIMER0_Channel_IRQHandler() {

if ( timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH0) != RESET) {
    timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH0);
}
else if (timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH3) != RESET){   
    timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH3);
    rcvcnt++;
}
}


    TIMER0 CH0和CH3的GPIO口确定可以正常检测到高低电平,然而软件在运行中,只有更新中断是正常的,输入捕获中断一直触发不了,不知道各位大佬们是否有遇到过此类问题,恳请指点一二,感谢!

sonicll 发表于 2021-4-25 14:17

timer配置应该没有问题,你用的是哪两个GPIO,确定这个两个GPIO是TIMER0的CH0和CH3吗?

CapSean 发表于 2021-4-25 15:08

sonicll 发表于 2021-4-25 14:17
timer配置应该没有问题,你用的是哪两个GPIO,确定这个两个GPIO是TIMER0的CH0和CH3吗? ...
谢谢回复!
Timer0的CH0和CH3分别用的PE9和PE14管脚,因为管脚输入端口上拉并用二极管做了输入保护,所以先通过给这两个管脚高电平和低电平检查输入回路信号是否可以正确到达MCU, 现在确定在IO模式下两个端口可以正确测到高低电平。但是在定时器输入捕获模式下,信号边沿检测始终没有触发。最初我是用的ST F10X标准库做的功能,输入捕获没有成功所以又基于GD32 的F30x标准库做了改动来验证功能,结果还是没有成功。现在因为没有输入捕获功能正常的Demo来比对,所以不太清楚是硬件问题还是软件没有配置对。再次感谢关注这个问题。

sonicll 发表于 2021-4-25 15:39

CapSean 发表于 2021-4-25 15:08
谢谢回复!
Timer0的CH0和CH3分别用的PE9和PE14管脚,因为管脚输入端口上拉并用二极管做了输入保护,所以 ...

PE9和PE14需要配置remap才能作为TIMER0的通道使用:

rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);

CapSean 发表于 2021-4-25 17:36

sonicll 发表于 2021-4-25 15:39
PE9和PE14需要配置remap才能作为TIMER0的通道使用:

rcu_periph_clock_enable(RCU_AF);


再此感谢答复,问题已经解决!确实问题在你说的端口重映射上,增加端口重映射后,输入捕获可以正常工作了。GD提供的标准库没有添加端口重映射函数,可能是因为有多种重映射方式可选择,所以留给了用户自己添加。这点对于老手来说应该很容易注意到,但感觉比较容易误导新人。

CapSean 发表于 2021-4-25 17:37

另外附上在GD标准库main()函数基础上修改的代码,已测试验证过。
/*!
    \file    main.c
    \brief   TIMER0 complementary signals demo for gd32f30x

    \version 2017-02-10, V1.0.0, firmware for GD32F30x
    \version 2018-10-10, V1.1.0, firmware for GD32F30x
    \version 2018-12-25, V2.0.0, firmware for GD32F30x
    \version 2020-09-30, V2.1.0, firmware for GD32F30x
*/

/*
    Copyright (c) 2020, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include <stdio.h>
#include "gd32f30x_it.h"
#include "systick.h"

void gpio_config(void);
void timer0_config(void);

extern uint32_t timer0tick;
/*!
    \brief      configure the GPIO ports
    \paramnone
    \param none
    \retval   none
*/
void gpio_config(void) {
rcu_periph_clock_enable(RCU_GPIOC);
/*cofig PC11 as output PP mdoe*/
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_11);
}

void timer0_gpio_config(void)
{
    rcu_periph_clock_enable(RCU_GPIOE);
    rcu_periph_clock_enable(RCU_AF);

    /*configure PE9 PE14(TIMER0 CH0 CH3) as alternate function*/
    gpio_init(GPIOE,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_10MHZ,GPIO_PIN_9|GPIO_PIN_14);
   
    /*
    * GD32F30x标准库提供的例程虽然在GPIO初始化时有注释“configre xxx as alternate function”,
    * 但是只对GPIO做了基本的初始化,并未进行端口重映射,当然这一点对于老手来说应该很容易注意到,
    * 但是对外设配置不熟悉的新人来说很容易被误导,注意添加下方的端口重映射函数!
    */
    gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
}

/*!
    \brief      configure the TIMER peripheral
    \paramnone
    \param none
    \retval   none
*/
void timer0_config(void)
{

    timer_parameter_struct timer_initpara;
    timer_ic_parameter_struct timer_icinitpara;

    timer0_gpio_config();

    rcu_periph_clock_enable(RCU_TIMER0);

    timer_deinit(TIMER0);
   
    /*NVIC config*/
    nvic_irq_enable(TIMER0_UP_TIMER9_IRQn, 1, 1);
    nvic_irq_enable(TIMER0_Channel_IRQn, 1, 0);
    /* TIMER0 configuration */
    timer_initpara.prescaler         = 119;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection= TIMER_COUNTER_UP;
    timer_initpara.period            = 999;
    timer_initpara.clockdivision   = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);

    timer_icinitpara.icpolarity      = TIMER_IC_POLARITY_RISING;
    timer_icinitpara.icselection   = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler   = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter      = 0x0;
    timer_input_capture_config(TIMER0, TIMER_CH_0, &timer_icinitpara);

    timer_input_capture_config(TIMER0, TIMER_CH_3, &timer_icinitpara);
   
    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER0);
   
    timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_CH0);
    timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_CH3);
    timer_interrupt_enable(TIMER0,TIMER_INT_CH0);
    timer_interrupt_enable(TIMER0,TIMER_INT_CH3);
    timer_interrupt_enable(TIMER0,TIMER_INT_UP);
   
   
    timer_enable(TIMER0);
}


void gpio_togglepin(uint32_t gpio_periph, uint32_t pin) {

if ( GPIO_OCTL(gpio_periph) & pin) {
    GPIO_BC(gpio_periph) = pin;
}
else {
    GPIO_BOP(gpio_periph) = pin;
}

}
/*!
    \brief      main function
    \paramnone
    \param none
    \retval   none
*/
int main(void)
{
    static uint32_t tick = 0;
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    systick_config();
    gpio_config();
    timer0_config();
    tick = timer0tick;
    while (1) {
      gpio_bit_set(GPIOC, GPIO_PIN_11);
      delay_1ms(500);
      gpio_bit_reset(GPIOC, GPIO_PIN_11);
      delay_1ms(500);
    }
}

pandaxia 发表于 2024-4-28 16:02

我也遇到这个问题了,但是我只有PE11一个引脚去捕获pwm信号,初始化也加上重映射了,TIMER0_Channel_IRQHandler中断触发不了应该怎么做呢

芯路例程 发表于 2024-4-29 20:08

输入捕获的引脚配置了吗?

AIsignel 发表于 2024-4-29 20:38

直接使用官方的捕获例程能正常捕获吗?

4c1l 发表于 2024-6-30 23:30

通过串口输出或者LED指示灯,确认是否真的进入了输入捕获中断服务程序

tpgf 发表于 2024-7-3 09:11

换成其他的定时器配置输入捕获能有反应吗

wowu 发表于 2024-7-3 13:14

前期设计的时候没有考虑好硬件的影响啊

xiaoqizi 发表于 2024-7-3 13:46

把这个引脚的功能映射到其他引脚上去使用

木木guainv 发表于 2024-7-3 14:24

是不是可以考虑这两个功能进行分时复用呢

晓伍 发表于 2024-7-3 18:00

如果引脚资源不那么紧张的话 最好不要复用引脚

磨砂 发表于 2024-7-3 19:00

这种复用的情况对初始化的顺序有相应的要求吗

laocuo1142 发表于 2024-12-24 15:26

输入波形可能存在毛刺或不稳定,导致捕获不准确。

flycamelaaa 发表于 2024-12-24 16:00

检查输入波形,确保波形稳定且符合要求。可以尝试使用输入滤波器来消除噪声。

stormwind123 发表于 2024-12-24 17:30

可能没有正确使能捕获中断或中断优先级设置不正确。

probedog 发表于 2024-12-24 18:13

中断使能问题
页: [1]
查看完整版本: GD32F305VG timer0输入捕获无反应