我想通过使用计时器中断方法来测量Arduino UNO引脚2上两个输入脉冲之间的时间间隔,并且我已经编写了这段代码,但是它无法正常工作。
此代码仅显示一个实例的时间,因此我无法测量时间间隔。我是Arduino的新手,尝试制作呼吸机。任何建议将不胜感激。谢谢!
//Three timer interrupts
//timer setup for timer0,timer1 and timer2
//this code will enable all three arduino uno timer interrupts
//timer0 will interrupts at 2 KHz
//timer1 will interrupts at 1 Hz
//timer2 will interrupts at 8 KHz
//storage variables
boolean toggle0=0;
boolean toggle1=0;
boolean toggle2=0;
long count0=0;
long count1=0;
long count2=0;
float t=0;
float iT =0;
float fT =0;
float temp=0;
int switchPin = 2;
int switchState = 0;
void setup() {
cli(); //stop interrupts
//set timer0 interrupts at 2 KHz
TCCR0A = 0;//set entire TCCR0A register to 0
TCCR0B = 0;
TCNT0 = 0; //initialize counter value to 0
//set compare match register for 2KHz increments
OCR0A = 124;//=(16x10^6)/(2000x64)-1(must be <256)
//turn on CTC mode
TCCR0A |=(1 << WGM01);
//set CS01 and CS00 bits for 64 prescaler
TCCR0B |= (1 << CS01) | (1 << CS00);
//enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);
//set timer0 interrupts at 1 Hz
TCCR1A = 0;//set entire TCCR1A register to 0
TCCR1B = 0;
TCNT1 = 0; //initialize counter value to 0
//set compare match register for 1 Hz increments
OCR1A = 15624;//=(16x10^6)/(1x1024)-1(must be <65536)
//turn on CTC mode
TCCR1B |=(1 << WGM12);
//set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
//enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
//set timer0 interrupts at 8 KHz
TCCR2A = 0;//set entire TCCR2A register to 0
TCCR2B = 0;
TCNT2 = 0; //initialize counter value to 0
//set compare match register for 2KHz increments
OCR2A = 249;//=(16x10^6)/(8000x8)-1(must be <256)
//turn on CTC mode
TCCR2A |=(1 << WGM21);
//set CS21 bits for 8 prescaler
TCCR2B |= (1 << CS21);
//enable timer compare interrupt
TIMSK2 |= (1 << OCIE2A);
sei();//allow interrupts
pinMode(switchPin,INPUT);
Serial.begin(9600);
}
ISR(TIMER0_COMPA_vect){
//timer0 interrupts 2KHz toggles pin 8
//generate pulse wave of frequency 2KHz/2 = 1KHz
if(toggle0){
digitalWrite(8,HIGH);
toggle0 = 0;
count0++;
t = count0/1000;
}
else {
digitalWrite(8,LOW);
toggle0 = 1;
}
}
ISR(TIMER1_COMPA_vect){
//timer1 interrupts 1Hz toggles pin 8
//generate pulse wave of frequency 1Hz/2 = 0.5Hz
if(toggle1){
digitalWrite(13,HIGH);
toggle1 = 0;
count1++;
}
else {
digitalWrite(13,LOW);
toggle1 = 1;
}
}
ISR(TIMER2_COMPA_vect){
//timer2 interrupts 8KHz toggles pin 8
//generate pulse wave of frequency 8KHz/2 = 4KHz
if(toggle2){
digitalWrite(9,HIGH);
toggle2 = 0;
count2++;
}
else {
digitalWrite(9,LOW);
toggle2 = 1;
}
}
void loop() {
switchState = digitalRead(switchPin);
if ((switchState == 1) && (temp == 0)) {
temp = 1;
}
if ((switchState == 1) && (temp == 1)) {
temp = 0;
}
if(switchState){
if(temp == 0) {
iT = t;
}
if(temp == 1) {
fT = t;
}
}
//Serial.println(t);
//Serial.print("Count0 :");
//Serial.println(count0);
//Serial.print("count1 :");
//Serial.println(count1);
//Serial.print("count2 :");
//Serial.println(count2);
// Serial.print("Time : ");
//Serial.println(t);
//Serial.println(switchState);
Serial.print("First Ping Time :: ");
Serial.println(iT);
Serial.print("Second Ping Time :: ");
Serial.println(fT);
//Serial.print("Temp=");
//Serial.println(temp);
}
并且输出显示:
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
首先,您不应该惹麻烦timer0。 Arduino使用TIMER0进行计时。您不应该对此进行更改(因此,您发现它使millis()无法正常工作)。您可以使用TIMER1和TIMER2做任何您想做的事情。 (尽管某些库使用它们)。为什么不使用attachInterrupt()?Read here for How to并看到here for example code很抱歉,您没有深入研究您的长代码。
我将以更简单的方式解决此问题。始终尝试将问题分成较小的问题(不要过多!)。在这种情况下,我们想要:
让我们开始:
如果我们认为引脚的默认状态为LOW
,则代码应考虑输入为HIGH
,因此这将是我们loop()
部分中的第一条语句。读取引脚状态的功能是digitalRead()
。您将我们感兴趣的销钉的值提供给它,我们将收到状态HIGH
或LOW
。
if (digitalRead(pin) == HIGH){
}
现在我们知道何时开始时间,所以现在该考虑我们将如何利用它。我们可以在if语句中编写它,也可以通过创建新函数来编写它,这取决于您要使用的代码的用法。让我们直接在if语句中实现它。我们可以在循环中将1加到变量中,例如:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
elapsedTime = elapsedTime + 1;
}
但是我们想在一定时间(一秒钟后)增加一个。我们可以对董事会说嘿!添加一]后等待一秒钟。通过使用功能delay()
等待一秒钟即可实现此目标。我们需要指定多少,在这种情况下为1000
,因为一秒为1000毫秒。该功能的更多信息,here。现在,我们的代码如下所示:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
elapsedTime = elapsedTime + 1;
delay(1000);
}
一种更常见的添加方法如下:variable++
。另一个次要编辑将等待一秒钟,然后再添加一次,因为开始存储的时间是0,否1。让我们重新编写这些行:
elapsedTime = 0;
for (int i = 0; i <= 255; i++){
delay(1000);
elapsedTime = elapsedTime++;
}
现在,我们要执行此操作,直到再次回到引脚(HIGH)的激活状态,而不是等待255秒。在这种情况下,我们使用while
,这表示类似嘿板子!进行此操作,直到发生]]
while (digitalRead(pin) == LOW){ }
现在,我们在此函数中编写的内容将完成,直到获得错误的语句为止。使用我们之前写的内容:
elapsedTime = 0; while (digitalRead(pin) == LOW){ delay(1000); elapsedTime = elapsedTime++; }
最后,我们要在收到第一个
HIGH
输入时开始计数,因此我们将其包装在第一行代码中:
elapsedTime = 0; if (digitalRead(pin) == HIGH){ while (digitalRead(pin) == LOW){ delay(1000); elapsedTime = elapsedTime++; } }
全部完成!要获得结果,您可以打印结果,也可以做任何您想做的事情。您可以测量任何单位,而无需以秒为单位,只需将
delay()
中的值更改为所需的任何单位即可。例如,如果要测量毫秒,则为delay(1)
。