跳到主要内容

Arduino 输入捕获

介绍

Arduino的输入捕获功能是一种强大的工具,用于测量外部信号的脉冲宽度和频率。通过输入捕获,Arduino可以精确地记录外部信号的变化时间,从而计算出信号的周期、占空比等参数。这对于需要精确时间测量的应用场景非常有用,例如测量旋转编码器的转速、检测PWM信号的频率等。

输入捕获的工作原理

Arduino的输入捕获功能依赖于定时器和外部中断。当外部信号的电平发生变化时,定时器会记录当前的时间值。通过比较两次变化的时间值,可以计算出信号的脉冲宽度和频率。

定时器与输入捕获

Arduino的定时器是一个计数器,它以固定的频率递增。当输入捕获事件发生时,定时器的当前值会被保存到一个寄存器中。通过读取这个寄存器的值,我们可以知道信号变化发生的确切时间。

外部中断

外部中断是Arduino检测外部信号变化的一种方式。当外部信号的电平发生变化时,Arduino会触发一个中断,执行相应的中断服务程序(ISR)。在ISR中,我们可以读取定时器的值,并进行相应的计算。

代码示例

以下是一个简单的Arduino代码示例,展示了如何使用输入捕获功能来测量外部信号的脉冲宽度。

cpp
volatile unsigned long startTime = 0;
volatile unsigned long pulseWidth = 0;

void setup() {
Serial.begin(9600);
pinMode(8, INPUT); // 将引脚8设置为输入
attachInterrupt(digitalPinToInterrupt(8), capturePulse, CHANGE); // 设置中断
}

void loop() {
if (pulseWidth > 0) {
Serial.print("Pulse Width: ");
Serial.print(pulseWidth);
Serial.println(" us");
pulseWidth = 0; // 重置脉冲宽度
}
}

void capturePulse() {
static unsigned long lastTime = 0;
unsigned long currentTime = micros();

if (digitalRead(8) == HIGH) {
startTime = currentTime; // 记录上升沿时间
} else {
pulseWidth = currentTime - startTime; // 计算脉冲宽度
}
}

代码解释

  1. volatile 关键字:用于声明变量 startTimepulseWidth,表示这些变量可能会在中断服务程序中被修改。
  2. attachInterrupt():将引脚8的中断与 capturePulse() 函数关联,当引脚8的电平发生变化时,capturePulse() 函数会被调用。
  3. micros():返回从Arduino启动以来的微秒数,用于记录时间。
  4. capturePulse():中断服务程序,记录信号的上升沿和下降沿时间,并计算脉冲宽度。

实际应用案例

测量旋转编码器的转速

旋转编码器是一种用于测量旋转角度和速度的设备。通过Arduino的输入捕获功能,我们可以测量编码器输出的脉冲宽度,从而计算出转速。

cpp
volatile unsigned long lastTime = 0;
volatile unsigned long pulseWidth = 0;
volatile int pulseCount = 0;

void setup() {
Serial.begin(9600);
pinMode(8, INPUT);
attachInterrupt(digitalPinToInterrupt(8), capturePulse, RISING);
}

void loop() {
if (pulseCount > 0) {
float rpm = 60000000.0 / (pulseWidth * pulseCount); // 计算转速
Serial.print("RPM: ");
Serial.println(rpm);
pulseCount = 0; // 重置脉冲计数
}
}

void capturePulse() {
unsigned long currentTime = micros();
pulseWidth = currentTime - lastTime;
lastTime = currentTime;
pulseCount++;
}

代码解释

  1. RISING:仅在信号的上升沿触发中断。
  2. rpm 计算:通过脉冲宽度和脉冲计数计算出转速(RPM)。

总结

Arduino的输入捕获功能为精确测量外部信号的脉冲宽度和频率提供了强大的工具。通过结合定时器和外部中断,我们可以轻松实现各种时间测量任务。本文介绍了输入捕获的基本原理,并提供了代码示例和实际应用案例,帮助初学者理解和应用这一功能。

附加资源与练习

  • 练习1:修改代码示例,使其能够测量信号的占空比。
  • 练习2:尝试使用输入捕获功能测量PWM信号的频率。
  • 资源:Arduino官方文档中关于定时器和中断的详细说明。
提示

在编写中断服务程序时,尽量保持代码简洁,避免使用耗时的操作,以确保中断响应的实时性。

警告

使用输入捕获功能时,注意信号的频率和Arduino的处理能力,避免因信号频率过高而导致的数据丢失。