想用16位定时器捕捉1~200kHz的脉冲周期,求大神指点迷津!

2019-03-23 17:32发布

定时器配置:
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);       
                /*---------------------------- TIM16 Configuration ----------------------------*/
                /* Time base configuration */
                TIM_DeInit(TIM16);
                TIM_TimeBaseStructure.TIM_Period = 0xffff;
                TIM_TimeBaseStructure.TIM_Prescaler = 0;
                TIM_TimeBaseStructure.TIM_ClockDivision = 0;
                TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

                TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure);

                TIM_PrescalerConfig(TIM16, 0, TIM_PSCReloadMode_Update);

                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 = 0;

                TIM_ICInit(TIM16, &TIM_ICInitStructure);       

                NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                NVIC_Init(&NVIC_InitStructure);       

                TIM_ClearITPendingBit(TIM16,TIM_IT_CC1|TIM_IT_Update);
                TIM_ITConfig(TIM16, TIM_IT_CC1|TIM_IT_Update,ENABLE);  
                TIM_Cmd(TIM16, ENABLE);   
中断处理:
void TIM16_IRQHandler(void)
{
        if((TIM16CH1_CAPTURE_STA&0X80)==0)
        {          
                if((TIM_GetITStatus(TIM16, TIM_IT_CC1) != RESET))
                {
                        TIM_ClearITPendingBit(TIM16, TIM_IT_CC1);
                        if(TIM16CH1_CAPTURE_STA&0x40)
                        {
                                TIM16CH1_CAPTURE_STA |= 0x80;
                                Cap2 = TIM_GetCapture1(TIM16);
                                if(CapCount_H>0)
                                {
                                        TIM16CH1_CAPTURE_VAL2 = CapCount_H*65536 + 65536-Cap1+Cap2;                               
                                }
                                else
                                {
                                        TIM16CH1_CAPTURE_VAL2 = Cap2-Cap1;                               
                                }
                        }
                        else
                        {               
                                CapCount_H = 0;
                                Cap2 = 0;
                                Cap1 = TIM_GetCapture1(TIM16);
                                TIM16CH1_CAPTURE_STA |= 0x40;       
                        }               
                }
               
                if (TIM_GetITStatus(TIM16, TIM_IT_Update) != RESET)       
                {
                        TIM_ClearITPendingBit(TIM16, TIM_IT_Update);
                        if (TIM16CH1_CAPTURE_STA&0x40)         
                        {            
                                CapCount_H++;
                        }                       
                }       
        }
        else
                TIM_ClearITPendingBit(TIM16, TIM_IT_Update);
}
结果就是不对,望大神帮我找找bug!或者有别的思路或者程序都可以,急求急求!

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
1152075117
1楼-- · 2019-03-24 00:48
/ 别沉了!大家赶紧来参与讨论吧!
dontium
2楼-- · 2019-03-24 05:40
我用过PWM输入捕获功能,中断时,直接就在寄存器里读出高电平和低电平的持续时间了。
楼主用这个功能试一下。
Li_Lei
3楼-- · 2019-03-24 06:44
 精彩回答 2  元偷偷看……
1152075117
4楼-- · 2019-03-24 12:29
dontium 发表于 2017-9-8 09:39
我用过PWM输入捕获功能,中断时,直接就在寄存器里读出高电平和低电平的持续时间了。
楼主用这个功能试一 ...

这个功能我知道,但是用16位定时器捕捉周期的范围不够。
1152075117
5楼-- · 2019-03-24 14:49
huo_hu 发表于 2017-9-8 10:43
这么干看不行,你做几个实验看问题出在哪里

思路是第一次捕捉到上升沿时读一次capture,第二次捕捉到上升沿时再读capture,之间定时器有更新中断,然后根据这些计算出周期值。感觉思路没啥问题,但是捕捉到的值确实不对,可能是实现方面有问题。我是一直实验的,搞了好几天。。。唉,路漫漫。。。
吓于侠义
6楼-- · 2019-03-24 18:18
 精彩回答 2  元偷偷看……

一周热门 更多>