lpc17xx采用轮询频率检测方波

时间:2015-06-17 05:13:58

标签: algorithm microcontroller cortex-m3 lpc nxp-microcontroller

我必须通过查询5个不同的引脚来读取高达20KHz的5种不同频率(方波)。 我只使用一个定时器中断,每1毫秒。 引脚的轮询将在ISR中完成。

到目前为止我想到的算法是: 1. HIGH的数量 2. LOW的数量 3.检查HIGH + LOW的总和=时间段。 这个算法似乎很慢,不实用。

是否有任何滤波器功能可用于检查引脚的频率,以便我所要做的就是调用该功能? 用于频率检测的任何其他算法都会很好。

我的代码中仅限于1个中断(定时器中断)

1 个答案:

答案 0 :(得分:0)

您需要记住输入信号属性是什么

  • 因为你只限于一次中断(这很奇怪)
  • 且计时器只有1 KHz
  • 输入信号不得高于0.5 KHz
  • 如果信号有噪音,频率很容易超过多次

<强>速度

  • 你写道,简单的计算期间方法很慢
  • 你有什么CPU和IO能力?
  • 我习惯于在ARM皮质芯片之前2代的Atmel AVR32 AT32UC3芯片
  • 我有大约96MIPS和2-5 MHz引脚R / W频率,没有DMA或中断
  • 那个方法到底有什么缓慢的呢?

我会用这样的约束来编码它(它只是不使用你的平台的C ++伪代码):

const int n=5;
volatile int T[n],t[n],s[n],r[n]; // T last measured period,t counter,s what edge is waitng for?
int T0[n]={?,?,?,...?}; // periods to compare with

void main() // main process
 {
 int i;
 for (i=0;i<n;i++) { T[i]=0; t[i]=0; s[i]=0; r[i]=0; }
 // config pins
 // config and start timer
 for (;;) // inf loop
  {
  for (i=0;i<n;i++)            // test all pins
   if (r[i]>=2)                 // ignore not fully measured pins
    {
    r[i]=2;
    if (abs(T[i]-T[0])>1)     // compare +/- 1T of timer can use even bigger number then 1
     // frequency of pin(i) is not as it should be
    }
  }
 }

void ISR_timer() // timer interrupt
 {
 // test_out_pin=H
 int i;
 bool p;
 for (i=0;i<n;i++)
  {
  p=get_pin_state(i);                                // just read pin as true/false H/L
  t[i]++;                                             // inc period counter
  if (s[i]==0){ if ( p) s[i]=1; }                   // edge L->H
  else         { if (!p) s[i]=0; T[i]=t[i]; t=0; r[i]++; } // edge H->L
  } 
 // test_out_pin=L
 }
  • 您还可以扫描最后一个引脚状态和实际
  • 之间的比较
  • 可以消除s[]
  • 的需要
  • 类似于p0=p1; p1=get_pin_state(i); if ((p1)&&(p0!=p1)) { T[i]=t[i]; t[i]=0; }
  • 的内容
  • 这样您也可以更轻松地实现SW故障过滤器
  • 但我认为MCU也应该有硬件过滤器(就像大多数MCU一样)

如果没有您的奇怪限制,我该怎么做?

  • 我会使用外部中断
  • 通常可将它们配置为在信号的特定边缘触发
  • 还包括噪声的HW过滤
  • 每个中断的
  • 取内部CPU时钟计数器值
  • 如果它没有处理,那么计时器/计数器状态
  • 减去最后测量的
  • 从溢出中恢复(如果发生)
  • 根据需要更改为sHz
  • 通过这种方式,我可以可靠地以30MHz时钟扫描MCU上的引脚,频率高达15MHz(用于IRC解码器)
  • 并且是的IRC可以在某些情况下(状态之间的边缘)为您提供1 MHz以上的频率
  • 如果你想要比例,你也可以:
  • 有2个中断,一个用于正边,第二个用于负边
  • 或只使用一个并在每次击中后重新配置边缘(我之前使用的Atmel UC3L芯片由于内部错误而导致此问题)

[注释]

  • 您访问的引脚必须位于相同的IO端口
  • 所以你可以一次阅读所有内容,然后在
  • 之后解码引脚
  • 此外,GPIO模块通常是可配置的,因此请检查
  • 支持的时钟
  • 通常有2个时钟用于连接GPIO模块和CPU内核
  • 和GPIO本身的第二个,所以检查两个
  • 您也可以使用DMA代替外部中断
  • 如果您可以配置为通过DMA读取IO端口...到某处的内存
  • 然后您可以检查独立于IO的后台进程