问答

汇集网友智慧,解决技术难题

21ic问答首页 - 用GD32F103RCT6的TIM2捕获中断有丢中断的现象?

用GD32F103RCT6的TIM2捕获中断有丢中断的现象?

用GD32F103RCT6芯片的TIM2做两咱频率测量,有时捕获中断有丢中断的现象?即有时有两个脉冲输入,但CPU只调用TIM2中断函数一次,导致频率计数不对。溢出中断也有这种情况,明明已经发生了溢出但CPU不调TIM2中断函数,通多次测试发现,当在CPU调用TIM2中断函数并手动清除中断标志位时,如果这个发生另一个TIM2中断,这时置位TIM2中断标志就有可能不成功。有没有朋友知道是什么原因?
回答 +关注 6
2844人浏览 8人回答问题 分享 举报
8 个回答
  • 谢谢<span style="margin: 0px; padding: 0px; color: rgb(144, 153, 172); font-family: &quot;Microsoft yahei&quot;; background-color: rgb(255, 255, 255); text-decoration-line: none !important;"><a  target="_blank" style="margin: 0px; padding: 0px; color: rgb(144, 153, 172); font-family: &quot;Microsoft yahei&quot;; background-color: rgb(255, 255, 255); text-decoration-line: none !important;">qintian0303</a>的回答,我测的两路频率都是1000Hz,一些一个中断函数执行时间不会大于1mS,所以在执行中断函数时,相同中断不会发生,所以不会因中断函数执行时间过长导致脉冲丢失的情况!</span>
  • 应该硬件操作优先级更高,你说的没有操作应该是已经操作了不过状态一致而已。比如你就在这个中断里执行,比还会进入这个中断吗?同一个中断没法优先级或者排队等待的,当你跳出中断后就会硬件改变状态了,所以就会传被“吃”的现象。
  • GD32好像没有勘误手册,我用STM32芯片没有这个问题?
  • 有没有勘误手册之类的,说什么没有
  • 把TIM_ICInitStructure.TIM_ICFilter = 0xF改为0,这个我也试过,不能解决问题,我的理解是,在用TIM_ClearITPendingBit(TIM2, TIM_IT_CC2)清中断标志位时,这时硬件正要置位中断标志位,这时硬件操作就被放弃了。
  • 把TIM_ICInitStructure.TIM_ICFilter = 0xF改为0试试
  • 这是我的定时器配置函数与中断函数
    void Timer2_Configuration(void)
    {
        TIM_ICInitTypeDef  TIM_ICInitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

        TIM_DeInit(TIM2);

        TIM_TimeBaseStructure.TIM_Period = 49999; //0xFFFF;
        TIM_TimeBaseStructure.TIM_Prescaler = 71;      //1M
        TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;  
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0xF;
        TIM_ICInit(TIM2, &TIM_ICInitStructure);

        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;   
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICFilter = 0xF;
        TIM_ICInit(TIM2, &TIM_ICInitStructure);

        TIM_ClearFlag(TIM2, TIM_FLAG_Update);
        TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_Update, ENABLE);
        TIM_Cmd(TIM2, ENABLE);
    }


    vu16 T2_CCR;
    vu16 T2_SR;

    void TIM2_IRQHandler(void)
    {
        T2_SR = TIM2->SR;

        if(T2_SR & 2) //通道1
        {

            T2_CCR = TIM2->CCR1;
            TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);


            if(U_Freq_Count == 0)
            {
                U_Freq_First_Cap = T2_CCR;
                U_T2_OverFlow    = 0;
            }
            U_Freq_Count++;
            U_T2_OverFlowForErr = 0;     
            if((U_T2_OverFlow > T2_OverFlowForFreq - 2) && (U_T2_OverFlow > 4))
            {
                if(U_Freq_Count > 1)
                {
                    U_Freq_Last_Cap      = T2_CCR;
                    U_Freq_First_Cap_Bak = U_Freq_First_Cap;
                    U_Freq_First_Cap     = U_Freq_Last_Cap;
                    U_Freq_Count_Bak     = U_Freq_Count;
                    U_Freq_Count         = 1;
                    U_T2_OverFlow_Bak    = U_T2_OverFlow;
                    U_T2_OverFlow        = 0;
                    U_En_Freq_Calculate  = TRUE;
                }
            }
        }

        if(T2_SR & 4) //通道2
        {
            T2_CCR = TIM2->CCR2;
            TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
            if(I_Freq_Count == 0)
            {
                I_Freq_First_Cap = T2_CCR;
                I_T2_OverFlow    = 0;
            }
            I_Freq_Count++;
            if((I_T2_OverFlow > T2_OverFlowForFreq - 2) && (I_T2_OverFlow > 4))
            {
                if(I_Freq_Count > 1)
                {
                    I_Freq_Last_Cap      = T2_CCR;
                    I_Freq_First_Cap_Bak = I_Freq_First_Cap;
                    I_Freq_First_Cap     = I_Freq_Last_Cap;
                    I_Freq_Count_Bak     = I_Freq_Count;
                    I_Freq_Count         = 1;
                    I_T2_OverFlow_Bak    = I_T2_OverFlow;
                    I_T2_OverFlow        = 0;
                    I_En_Freq_Calculate  = TRUE;
                }
            }
        }

        if(T2_SR & 1) //溢出
        {
            TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
            U_T2_OverFlow++;      
            if(U_T2_OverFlow> T2_OverFlowForFreq)  
            {
                U_Freq_Count  = 0;
                U_T2_OverFlow = 0;         
                U_Freq_Err    = TRUE;

            }
            I_T2_OverFlow++;
            if(I_T2_OverFlow > T2_OverFlowForFreq)
            {
                I_Freq_Count  = 0;
                I_T2_OverFlow = 0;
                I_Freq_Err    = TRUE;

            }
        }
    }





  • 可以把代码发出来看看吗

您需要登录后才可以回复 登录 | 注册