捕获模式下,16位定时器时间不准求助

2019-07-20 04:37发布

在使用STM32F7定时器捕获时,同时开启多路通道,分别对其实时进行频率的计算,共开启了8路定时捕获。其中,TIM2和TIM5为32位定时器,TIM9----TIM14为16为定时器。测试结果发现,所有16位定时器在长时间运行之后(几分钟),频率和时间以及捕获的脉冲数量会不准,表现为脉冲数量增大,运行时间减小(几十毫秒)。并且在捕获频率增大情况下,出现问题的时间也会缩短。TIM2和TIM5为32位定时器所在的通道脉冲时间及频率十分稳定。
捕获的脉冲由脉冲发生器产生,很稳不存在问题。也不是因为几个通道同时开产生的原因,即使只开启一个通道,也是一样的情况。个人能力水平有限,身边没有同行能指导的人,现贴上源码,求助路过吧友。麻烦路过的各位集思广益,指出不对的地方和其他想法,谢谢。
[mw_shl_code=c,false]void TIM1_BRK_TIM9_IRQHandler(void)
{
        u16 tsr;
        tsr=TIM9->SR;
        TIM9->SR=0;//Çå3yÖD¶Ï±ê־λ
//        EXTI->IMR&=~(1<<5);
        if(tsr&0X01)//ò&#231;3&#246;
        {
                TIM9CH1_CAPTURE_STA++;
//                TIM9->SR&=~(1<<0);//&#206;&#241;±&#216;&#199;&#229;3y&#214;D&#182;&#207;±ê&#214;&#190;&#206;&#187;
        }
        else if(tsr&0x02)//2&#182;&#187;&#241;1·¢éú2&#182;&#187;&#241;ê&#194;&#188;t
        {       
                                StandSign2Num+=1;
                                if(StandSign2Num==1)
                                {
                                        StandSign2m0=TIM9->CCR1+(TIM9CH1_CAPTURE_STA<<16);//&#187;&#241;è&#161;μ±&#199;°μ&#196;2&#182;&#187;&#241;&#214;μ.
                                        Readystate=0;//
                                        addr_data[30]=0x01;               /* é&#207;éy&#209;&#216;1yà′£&#172;&#188;&#198;3&#245;&#214;μ   */
                                }
                                else if(DoubleTime_flag==4)                          /* &#197;D&#182;&#207;±&#187;&#188;ì±íê&#199;·&#241;à′×&#238;oóò&#187;&#184;&#246;é&#207;éy&#209;&#216;  */
                                {
                                        StandSign2m1=TIM9->CCR1+(TIM9CH1_CAPTURE_STA<<16); /* é&#207;éy&#209;&#216;1yà′£&#172;&#188;&#198;×&#238;oó&#214;μ   */
                                        Stand2WorkState=1;
                                        if(Stand1WorkState&Stand2WorkState&Stand3WorkState&Stand4WorkState&Stand5WorkState&Stand6WorkState&Stand7WorkState)
                                        {
                                                DoubleTime_flag=0;
                                                addr_data[30] = 0x0002;                 /* &#188;ì&#182;¨±ê&#214;&#190;íê3é£&#172;&#188;&#196;′&#230;&#198;÷μ&#216;&#214;·±&#216;D&#235;&#191;&#191;oó,ê1á|&#191;&#216;èí&#188;t&#196;ü&#197;D&#182;¨±ê&#182;¨íê3é*/
                                                addr_data[8] = 0x0002;                   /* &#188;ì&#182;¨×′ì&#172;&#214;&#195;2  */       
                                                Readystate=1;
                                        }
                                       
                                        TIM9->DIER&=~(1<<1);           //1&#216;±&#213;2&#182;&#187;&#241;1&#214;D&#182;&#207;                               
                                        TIM9->DIER&=~(1<<0);           //1&#216;±&#213;&#184;üD&#194;&#214;D&#182;&#207;       
                                        TIM9->CR1&=~(1<<0)                ;//1&#216;±&#213;&#182;¨ê±&#198;÷
                                       
                                }               
                        if(StandSign2Num>=2)//·à&#214;1àà&#203;&#198;0/0&#214;&#174;ààNot a Number′í&#206;ó&#188;&#198;&#203;&#227;
                        {
                                StandSign2m1=TIM9->CCR1+(TIM9CH1_CAPTURE_STA<<16);//
                                StandSign2m=(StandSign2m1-StandSign2m0);

                                addr_data2[6]=(Fpclk/(StandSign2m))*((StandSign2Num-1));              /* ±ê×&#188;±í2&#198;μ&#194;ê  */
                                addr_data[68]=((u16 *)(& addr_data2[6]))[0];
                                addr_data[69]=((u16 *)(& addr_data2[6]))[1];
                       

                                addr_data2[12]=(StandSign2Num-1);//&#206;aê2&#195;′òaoí±&#187;&#188;ì±íμ&#196;ê±&#188;&#228;×&#246;±è&#189;&#207;£&#191;&#213;a&#209;ùμ&#196;&#189;á1&#251;óDDT&#213;yòaê&#182;£&#172;2&#187;·&#251;o&#207;êμ&#188;ê
                                addr_data[44]=((u16 *)(& addr_data2[12]))[0];  /* ±ê×&#188;±í2&#194;&#246;3&#229;êy */
                                addr_data[45]=((u16 *)(& addr_data2[12]))[1];
               
                                addr_data2[18]=(StandSign2m)/(Fpclk);                        /* ±ê×&#188;±í2ê±&#188;&#228; */
                                addr_data[32]=((u16 *)(& addr_data2[18]))[0];
                                addr_data[33]=((u16 *)(& addr_data2[18]))[1];       
                       
                        }

        }
}[/mw_shl_code]

[mw_shl_code=c,true]void TIM9_CH1_Cap_Init(u16 arr,u16 psc)
{                 
        RCC->APB2ENR|=1<<16;           //TIM9 ê±&#214;óê1&#196;ü
        RCC->AHB1ENR|=1<<4;           //ê1&#196;üPORTEê±&#214;ó       
        GPIO_Set(GPIOE,PIN5,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//&#184;′ó&#195;1|&#196;ü,&#207;&#194;à-
        GPIO_AF_Set(GPIOE,5,3);        //PE5,AF3
          
        TIM9->ARR=arr;                  //éè&#182;¨&#188;&#198;êy&#198;÷×&#212;&#182;ˉ&#214;&#216;×°&#214;μ   
        TIM9->SC=psc;                  //&#212;¤·&#214;&#198;μ&#198;÷

        TIM9->CCMR1|=1<<0;                //CC1S=01         &#209;&#161;&#212;&#241;ê&#228;è&#235;&#182;&#203; IC1ó3é&#228;μ&#189;TI1é&#207;
        TIM9->CCMR1|=0<<4;                 //IC1F=0000 &#197;&#228;&#214;&#195;ê&#228;è&#235;&#194;&#203;2¨&#198;÷ 2&#187;&#194;&#203;2¨
        TIM9->CCMR1|=0<<10;         //IC1PS=00         &#197;&#228;&#214;&#195;ê&#228;è&#235;·&#214;&#198;μ,2&#187;·&#214;&#198;μ

        TIM9->CCER|=0<<1;                 //CC1P=0        é&#207;éy&#209;&#216;2&#182;&#187;&#241;
        TIM9->CCER|=1<<0;                 //CC1E=1         &#212;êDí2&#182;&#187;&#241;&#188;&#198;êy&#198;÷μ&#196;&#214;μμ&#189;2&#182;&#187;&#241;&#188;&#196;′&#230;&#198;÷&#214;D

        TIM9->EGR=1<<0;                        //èí&#188;t&#191;&#216;&#214;&#198;2úéú&#184;üD&#194;ê&#194;&#188;t,ê1D′è&#235SCμ&#196;&#214;μá¢&#188;′éúD§,·&#241;&#212;ò&#189;&#171;&#187;áòaμèμ&#189;&#182;¨ê±&#198;÷ò&#231;3&#246;2&#197;&#187;áéúD§!
        TIM9->DIER|=1<<1;           //&#212;êDí2&#182;&#187;&#241;1&#214;D&#182;&#207;                               
        TIM9->DIER|=1<<0;           //&#212;êDí&#184;üD&#194;&#214;D&#182;&#207;       
        TIM9->CR1|=0x01;            //ê1&#196;ü&#182;¨ê±&#198;÷2
        MY_NVIC_Init(0,6,TIM1_BRK_TIM9_IRQn,4);//&#199;à&#213;&#188;2£&#172;×óó&#197;&#207;è&#188;&#182;0£&#172;×é2          
}[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
l68715553
1楼-- · 2019-07-20 05:28
 精彩回答 2  元偷偷看……
l68715553
2楼-- · 2019-07-20 10:27
对不住各位,后面的注释贴上来就乱码了。void TIM9_CH1_Cap_Init(u16 arr,u16 psc)是定时器9的初始化函数,void TIM1_BRK_TIM9_IRQHandler(void)是TIM9的中断服务函数。Fpclk为定时器的采样频率,为1M。
addr_data2[6]=(Fpclk/(StandSign2m))*((StandSign2Num-1));为从第一个上升沿开始至今的频率
addr_data2[12]=(StandSign2Num-1);为所捕获的脉冲数量,上升沿捕获,脉冲数量=捕获数量-1。
addr_data2[18]=(StandSign2m)/(Fpclk); 为第一个上升沿开始至今的时间
提到的不准的问题, 就是上面三个参数不准。
另贴出TIM5的源码,和这大同小异,仅在溢出情况下一个左移16位,一个左移32位。
[mw_shl_code=c,false]void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{                 
        RCC->APB1ENR|=1<<3;           //TIM5 ê±&#214;óê1&#196;ü
        RCC->AHB1ENR|=1<<0;           //ê1&#196;üPORTAê±&#214;ó       
        GPIO_Set(GPIOA,PIN0,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//&#184;′ó&#195;1|&#196;ü,&#207;&#194;à-
        GPIO_AF_Set(GPIOA,0,2);        //PA0,AF2
          
        TIM5->ARR=arr;                  //éè&#182;¨&#188;&#198;êy&#198;÷×&#212;&#182;ˉ&#214;&#216;×°&#214;μ   
        TIM5->SC=psc;                  //&#212;¤·&#214;&#198;μ&#198;÷

        TIM5->CCMR1|=1<<0;                //CC1S=01         &#209;&#161;&#212;&#241;ê&#228;è&#235;&#182;&#203; IC1ó3é&#228;μ&#189;TI1é&#207;
        TIM5->CCMR1|=0<<4;                 //IC1F=0000 &#197;&#228;&#214;&#195;ê&#228;è&#235;&#194;&#203;2¨&#198;÷ 2&#187;&#194;&#203;2¨
        TIM5->CCMR1|=0<<10;         //IC1PS=00         &#197;&#228;&#214;&#195;ê&#228;è&#235;·&#214;&#198;μ,2&#187;·&#214;&#198;μ
        if(addr_data[8] == 0x0005||addr_data[8] == 0x0001)//&#184;&#223;μ&#231;&#198;&#189;′¥·¢
        {
                TIM5->CCER&=~(1<<3);                 //CC1NP=0       
                TIM5->CCER|=(0<<1);                 //CC1P=0 &#207;&#194;&#189;μ&#209;&#216;2&#182;&#187;&#241;
        }
        else if(addr_data[8] == 0x0009)//&#184;&#223;μíμ&#231;&#198;&#189;&#190;ù′¥·¢
        {
                TIM5->CCER|=(1<<3);                 //CC1NP=1       
                TIM5->CCER|=(1<<1);                 //CC1P=1       
        }

        TIM5->CCER|=1<<0;                 //CC1E=1         &#212;êDí2&#182;&#187;&#241;&#188;&#198;êy&#198;÷μ&#196;&#214;μμ&#189;2&#182;&#187;&#241;&#188;&#196;′&#230;&#198;÷&#214;D

        TIM5->EGR=1<<0;                        //èí&#188;t&#191;&#216;&#214;&#198;2úéú&#184;üD&#194;ê&#194;&#188;t,ê1D′è&#235SCμ&#196;&#214;μá¢&#188;′éúD§,·&#241;&#212;ò&#189;&#171;&#187;áòaμèμ&#189;&#182;¨ê±&#198;÷ò&#231;3&#246;2&#197;&#187;áéúD§!
        TIM5->DIER|=1<<1;           //&#212;êDí2&#182;&#187;&#241;1&#214;D&#182;&#207;                               
        TIM5->DIER|=1<<0;           //&#212;êDí&#184;üD&#194;&#214;D&#182;&#207;       
        TIM5->CR1|=0x01;            //ê1&#196;ü&#182;¨ê±&#198;÷2
        MY_NVIC_Init(0,4,TIM5_IRQn,4);//&#199;à&#213;&#188;2£&#172;×óó&#197;&#207;è&#188;&#182;0£&#172;×é2          
}[/mw_shl_code]


[mw_shl_code=c,false]void TIM5_IRQHandler(void)                    
{
        u16 tsr;
        tsr=TIM5->SR;
        if(tsr&0X01)//ò&#231;3&#246;
        {             
                TIM5CH1_CAPTURE_STA++;
                TIM5->SR=0;//&#206;&#241;±&#216;&#199;&#229;3y&#214;D&#182;&#207;±ê&#214;&#190;&#206;&#187;
        }
        else if(tsr&0x02)//2&#182;&#187;&#241;1·¢éú2&#182;&#187;&#241;ê&#194;&#188;t
        {       
                StandSign1Num+=1;
                TIM5->SR=0;//&#199;&#229;3y&#214;D&#182;&#207;±ê&#214;&#190;&#206;&#187;
                if(StandSign1Num==1)
                {
//                TIM3->CNT=0;                                        //&#188;&#198;êy&#198;÷&#199;&#229;&#191;&#213;,CCR1ò&#209;±£′&#230;&#214;&#174;&#199;°μ&#196;CNT&#214;μ£&#172;2&#187;&#191;é&#199;&#229;&#191;&#213;
        //                TIM5CH1_CAPTURE_STA=0;
                        StandSign1m0=TIM5->CCR1+(TIM5CH1_CAPTURE_STA<<32);//&#187;&#241;è&#161;μ±&#199;°μ&#196;2&#182;&#187;&#241;&#214;μ.
                        Readystate=0;
                        addr_data[30]=0x01;               /* é&#207;éy&#209;&#216;1yà′£&#172;&#188;&#198;3&#245;&#214;μ   */
                }
                if(StandSign1Num>=2)//·à&#214;1àà&#203;&#198;0/0&#214;&#174;ààNot a Number′í&#206;ó&#188;&#198;&#203;&#227;
                {
                        StandSign1m1=TIM5->CCR1+(TIM5CH1_CAPTURE_STA<<32);//′&#203;ó&#239;&#190;&#228;óD&#206;êìa
                        StandSign1m=(StandSign1m1-StandSign1m0);

                        addr_data2[4]=(Fpclk/StandSign1m)*((StandSign1Num-1));              /* ±ê×&#188;±í&#198;μ&#194;ê  */
                        addr_data[26]=((u16 *)(& addr_data2[4]))[0];
                        addr_data[27]=((u16 *)(& addr_data2[4]))[1];
               
                        addr_data2[2]=(a/StandSign1m)*(StandSign1Num-1);//
                        addr_data[18]=((u16 *)(& addr_data2[2]))[0];  /* è&#244;2&#187;ê&#199;£&#172;±ê×&#188;±í&#194;&#246;3&#229;êy */
                        addr_data[19]=((u16 *)(& addr_data2[2]))[1];
               
                        addr_data2[1]=(StandSign1m)/Fpclk;                        /* ±ê×&#188;±íê±&#188;&#228; */
                        addr_data[12]=((u16 *)(& addr_data2[1]))[0];
                        addr_data[13]=((u16 *)(& addr_data2[1]))[1];       
                }
        }
}[/mw_shl_code]
l68715553
3楼-- · 2019-07-20 11:32
将8个通道全部短接在一起输入1K频率的脉冲,测得结果如图片所示。
TIM2比其他定时器时间多1ms,为个人设置,并不是误差。其他所有定时器时间脉冲数和频率应和TIM5时间一样才对的。
有路过朋友提点意见吗?
l68715553
4楼-- · 2019-07-20 12:12
 精彩回答 2  元偷偷看……

一周热门 更多>