10121|30

72

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

版主,请教个PWM_INPUT问题 [复制链接]

STM32101RC, CPU主频18MHz,TIM4分频值180,所以timer4主频100000Hz
现在我输入一个3.320KHz的频率,用PWM_INPUT方式捕获,读出值为3315,误差感觉比较大。我需要的精度是正负0.5Hz。 如果输入频率降低,精度会变好。

输入频率范围0-4KHz。

PWM_INPUT方式精度可以做到多少?
此帖出自stm32/stm8论坛

最新回复

                                 我还是这么处理比较妥当: IT_Status = TIM4->SR & (TIM_IT_CC1 | TIM_IT_Update);     IT_Enable = TIM4->DIER & (TIM_IT_CC1 | TIM_IT_Update);     IT_Flag = IT_Status & IT_Enable;     //TIM4->SR = (INT16U)(~(TIM_IT_CC1 | TIM_IT_Update));     if (ValBit(IT_Flag, 0))     {             TIM_ClearITPendingBit(TIM4, TIM_IT_Update);         O4FLOW2_FreqA_Step_CNT1++;     } //==     if (ValBit(IT_Flag, 1))     {        // TIM_IT_CC1         // Clear TIM2 Capture compare interrupt pending bit         TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);           ...............           ...............           ...............    }  详情 回复 发表于 2010-2-9 11:45
点赞 关注
 

回复
举报

81

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
                                 楼主可以通过软件处理来减小误差啊
此帖出自stm32/stm8论坛
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
你的问题与分辨率有关。

如果设置TIMER的频率为100kHz,计数器每计数一次,则是10us。

3.320kHZ的信号,周期为1/3320=3012us,计数器的计数值要么是301,要么是302,再换算回来就是3322或是3311,可见你得到的3315已经是非常好的结果。

按照这个思路,你通过把TIMER的频率提高(比如1MHz),就可以达到高的精度。
此帖出自stm32/stm8论坛
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 在调捕获的时候,始终无法很好的解决定时器溢出的问题,特别是溢出很多次,不知版主是否有好的方法
此帖出自stm32/stm8论坛
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

5
 
                                 可以判断溢出次数,然后软件处理
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

6
 
                                 使用溢出中断,按照5楼的办法做就可以了。
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                 如果只捕获一路,可以再每次捕获完后,把定时器清零,这样就可以防止定制器周期读数,导致的溢出,当然,单次如果还是溢出,说明频率相当低,还是要按照楼上的做
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

8
 

低频



谢谢版主! 不过TIM频率越高,对于低频率的输入,精度就差了。
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

9
 
谢谢版主! 不过TIM频率越高,对于低频率的输入,精度就差了。
这怎么可能?你能保证你的操作正确吗?

按照我在3楼给出的计算方法,应该是TIM频率越高,精度越高才对呀。
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

10
 
不是,我的意思是: 我现在输入频率范围是0---4KHz。
我现在TIM主频跑到最高,36MHz, 4K的输入精度是没问题了。 但是如果按照这个频率,T=0.027us,那么当输入频率是1Hz的时候,周期是1S;  因为计数器是16位的,所以65536*0.027 = 1796.472us,不可能达到1S, 如果我打开UIF标志,那要连续计数了。那样的话,我是否必须要用输入捕获模式? 我其实不想用输入捕获模式,因为中断开销很大,我还是倾向于用PWM_INPUT模式。
此帖出自stm32/stm8论坛
 
 
 

回复

99

帖子

0

TA的资源

一粒金砂(初级)

11
 
1)你要求的精度是多少?

2)是否可以进行2次测量?先用较低的TIM频率测量输入信号,得到低精度的数据,再提高TIM频率至合适的范围,得到高精度的数据。
此帖出自stm32/stm8论坛
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

12
 
Maximum error 0.5% 1-1000Hz; +/-0.5Hz, 1000-4000Hz; +/-0.5%

我设了TIM时钟频率后,就不会去变动了。因为Flow是外接的,所以对CPU来说,不知道Flow什么时候会接上,一旦接上了,就要准确测出频率。
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

13
 
                                 改变TIM时钟频率是个很容易的事情,时间也不长;为什么程序中不能改变TIM时钟频率?有什么难处吗?
此帖出自stm32/stm8论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

14
 


关键无法确定接进来的Flow是多少频率,而是需要CPU去测量的。
而且一旦接了Flow,如果这时候是3KHz,在不断掉Flow情况下,Flow的输入频率还是会改变的,可能过一会就变成100Hz了,再一会变成1Hz
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

15
 
我的意思是先测量出信号的频率(虽然精度不够),再改变TIM频率以提高精度。

因为改变TIM时钟频率再次测量,并不需要花很长时间,不影响外部信号的改变,只要外部信号保持3个周期不变即可。如果外部信号不能在3个周期内保持不变,你的测量意义也就不大了。
此帖出自stm32/stm8论坛
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

16
 
                                 这样子的话,临界点是不好预估的。
此帖出自stm32/stm8论坛
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

17
 
我刚才计算了一下,如果我TIM主频跑到最高,36MHz,那么对于4K的Flow输入来说,精度肯定是最高的。
36MHz/65536 = 549.31Hz, 也就是说当TIM在36MHz的时候,我能检测到的精确的频率最小值是550Hz。再往下肯定精度失去,必须要计算溢出次数来重新计算计数值了。
也就是说在低频的时候,必须去计算UG更新事件的次数了,以此来重新计算计数值。

是这样吧
此帖出自stm32/stm8论坛
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

18
 


如果TIM计数器的频率是Fcounter,则最小步长为1/Fcounter,按照12楼的要求+/-0.5%,可以计算出测量一个频率的最小步长至少需要多少。

比如测量1Hz的信号,最小步长至少应小于5ms,即只要计数器的频率大于200Hz就可以满足要求。

我们知道计数器是16位的,它溢出之前最多可计数65536次,因此设定计数器的频率为Fcounter时,可测量的最低频率是Fcounter/65536。

根据这2个条件,可以很容易地找到临界点。

例如,你要求的测量范围是1~4000Hz,则可以先设定计数器的频率为小于65kHz的某个数值,这样足以测量1~4000Hz的所有频率,当检测出信号的频率范围,再按照前述的限定条件,重新计算计数器的频率,再进行一次测量,即可得到足够精度的结果。

假设设定计数器的频率为65kHz,如果计数器只计数16次,则可知输入信号为大于3823Hz,接近4000Hz,这时你可以再设定计数器频率为36MHz,即可得到精确的结果。
此帖出自stm32/stm8论坛
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

19
 
UIF:更新中断标记 (Update interrupt flag) 位0 当产生更新事件时该位由硬件置’1’。它由软件清’0’。 0:无更新事件产生; 1:更新中断等待响应。当寄存器被更新时该位由硬件置’1’: ? 若TIMx_CR1寄存器的UDIS=0、URS=0,当TIMx_EGR寄存器的UG=1时产生更新事件(软件对计数器CNT重新初始化); ? 若TIMx_CR1寄存器的UDIS=0、URS=0,当计数器CNT被触发事件重初始化时产生更新事件

我想请问一下,如果计数溢出,那么UIF肯定是置位的,硬件自动清零。 当CNT再次从0开始计数到某一值,未溢出。此时CC1IF置位,那么我肯定能得到当前总计数值是65536+当前CNT值,这样频率就可以计算出。不过我想问的是,这时的CC1IF置位,会导致UIF也置位吗? 如果UIF只跟计数值溢出重新归零有关,那我就可以直接判断溢出次数和最后一次CC1IF置位时的值,即可计算出频率了。
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

20
 
谈谈目前我的想法:
依然采用PWM_INPUT模式,当频率>=36MHz/65536 = 549.31Hz时,原PWM_INPUT中断处理方式等都不变。
当频率<549.31Hz时,当CNT达到65536时,肯定还没有一个周期结束,此时CNT归零,产生一个UIF事件中断位。TIM肯定进中断,中断里面记录这次计数值count,并清零SR的bit[0]。因为CC1IF此时肯定还未触发,所以理论上继续进中断,如果CNT溢出,则下一次中断count值++。

中断服务程序先判SR的bit[0],再判bit[1].  当周期结束的时候,肯定会进入CC1IF,bit[1]的处理,此时读出CNT值,再加上count*65536,那么整个值就应该是周期值了。

不过在具体操作时,我先Flow输入600Hz,理论上应该计数值未溢出,直接就中断里面判断CC1IF了。count应该还是0,但是好像SR的bit[0]位进了许多次,count值我发觉有0x15,不知道是哪里有问题。请教了。谢谢了。

附tim中断,IT_Update和IT_CC1中断都已打开:
    IT_Status = TIM4->SR & (TIM_IT_CC1 | TIM_IT_Update);
    IT_Enable = TIM4->DIER & (TIM_IT_CC1 | TIM_IT_Update);

    IT_Flag = IT_Status & IT_Enable;
    TIM4->SR = (INT16U)(~(TIM_IT_CC1 | TIM_IT_Update));

    if (ValBit(IT_Flag, 0))
    {
        O4FLOW2_FreqA_Step_CNT1++; //初始值是0
        TIM4->SR &= 0xfffe;
    }

//==
    if (ValBit(IT_Flag, 1))
    {        // TIM_IT_CC1
        // Clear TIM2 Capture compare interrupt pending bit
        TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

        // Get the Input Capture value
        O4Flow2_FreqA_IC1Value1 = TIM_GetCapture1(TIM4);

        if (O4Flow2_FreqA_IC1Value1 != 0)
        {
            // Duty cycle computation
            //DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;
            
            O4Flow2_FreqA_IC1Value1 += 0x10000*O4FLOW2_FreqA_Step_CNT1;
            // Frequency computation
            O4Flow2_FrequencyA = 36000000000  / O4Flow2_FreqA_IC1Value1;
        }
        else
        {
            //DutyCycle = 0;
            O4Flow2_FrequencyA = 0;
        }
    }
此帖出自stm32/stm8论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表