Arduino - 无中断计数脉冲

时间:2014-08-27 19:35:17

标签: arduino embedded electronics

我想知道是否有办法在Arduino上计算数字脉冲而不执行中断程序。

进一步说明:我有一个传感器输出与我想要计算的某些测量值成比例的数字脉冲。

2 个答案:

答案 0 :(得分:3)

你不仅可以在没有中断处理程序的情况下完成它,你可以做很少或没有软件,并且可以通过软件轮询或中断计数来处理更快的脉冲率。

大多数Arduinos所基于的Atmel AVR具有计数器/定时器硬件,可直接在输入引脚中进行脉冲计数。您所要做的就是配置硬件以进行计数器操作并读取计数器寄存器。 8位器件上的16位计数器有一个小的复杂性,但这很容易克服。 Arduino为默认的PWM操作配置定时器,但可以按照here所述进行覆盖(更多细节请参见AVR用户手册) - 您需要在CTC模式下使用定时器/计数器。

基于ARM的Arduninos和几乎任何其他微控制器都有类似的硬件设施;有些引脚可用于硬件计数,有些引脚具有更大的灵活性。

在AVR上有8位和16位计数器,如果需要更大的计数,则可能需要处理溢出中断。如果您将定期轮询计数器,您甚至可以在没有中断的情况下处理,同时只需通过在下一次溢出之前轮询溢出标志,以比输入脉冲速率低得多且可能非周期性的速率进行轮询。 / p>

在您的情况下,您可能需要以比计数器以最大预期脉冲速率溢出的时间更短的常规周期读取脉冲计数。因此,例如,如果您使用的是8位计数器且最大脉冲速率为1KHz,则需要每256/1000秒或更短的时间轮询一次,但通过尽可能长的时间来提供最大的精度。例如,您可能会遇到以下内容(这不是真正的代码,只有片段):

for(;;)
{
    delayMS( 250 ) ;
    frequency = 4 * readCounter() ;
}

另一种可获得更好的线性响应但非确定性读数的方法是轮询溢出标志,并测量计算固定数量脉冲所需的时间,从而确定您从固定计数的时间开始的测量而不是固定时间的计数。

for(;;)
{
    int start = getMillisec() ;

    while( !counterOVF() )
    {
        // Do nothing (or something useful but quick)
    }

    int t = getMillisec() - start ;
    frequency = 256 * t / 1000 ; 
}

答案 1 :(得分:1)

您可以使用模拟,前面有一点数字。 如果您的输入最大频率为1kHz,请使用此信号触发单稳态(边沿触发),脉冲输出为1ms(1 / fmax)。然后对其进行低通滤波(R串联,C接地,重复多极),最后读取最后一个电容上的模拟电压。如果R * C相对较小,模拟信号会快速反应,但会有波纹。如果它很大,反应时间会受到影响,但信号会更稳定。