如何消除Arduino UNO中一连串脉冲中的抖动?

时间:2016-12-21 18:31:46

标签: timer arduino arduino-uno pwm

这是我第一个使用Arduino UNO的实际项目,事实是我没有触及任何简单的事情:(我需要将我的Arduino转换为14位编码器驱动程序,我需要生成14脉冲训练到大于30 Khz的固定频率,并在每列火车之间建立一个50微秒的死区时间,或直到更多。 在我已经意识到的所有变体中,我在示波器上偶然发现了波形中令人讨厌的抖动或相移,这应该尽可能干净。 这是我的第一个粗略变体:

void setup() {
    pinMode(11, OUTPUT);
}

void loop() {
    for (int i=0; i<15; i++){
        digitalWrite(11, HIGH);
        delayMicroseconds(12);
        digitalWrite(11, LOW);
        delayMicroseconds(12);
    }
delayMicroseconds(50);
}

然后我尝试使用计时器来解决它,并且似乎有一个时间偏移产品停止并总结计时器以弥补死时间。我使用我下载的TimerOne库:https://github.com/PaulStoffregen/TimerOne

#include <TimerOne.h>
const byte CLOCKOUT = 11;
volatile long counter=0;

void setup() {
    Timer1.initialize(15);         //Cada 15 microsegundos cambio el estado del pin en la funcion onda dando un periodo
    Timer1.attachInterrupt(Onda);  //de 30 microsegundos
    pinMode (CLOCKOUT, OUTPUT);
    digitalWrite(CLOCKOUT,HIGH);
}

void loop() {
    if (counter>=29){                //con 29 cambios logro los pulsos que necesito
        Timer1.stop();               //Aqui creo el tiempo muerto, el cual esta debe estar en HIGH
        digitalWrite(CLOCKOUT,HIGH);
        counter=0;
        delayMicroseconds(50);
        Timer1.resume();
    }
}

void Onda(){
    digitalWrite(CLOCKOUT, digitalRead(CLOCKOUT) ^ 1);   //Cambio el estado del pin
    counter+=1;
}

1 个答案:

答案 0 :(得分:0)

我在CTC模式下使用timer2找到了更好的解决方案

#include <avr/io.h>
#include <avr/interrupt.h>

volatile byte counter=0;

void setup() {
   pinMode(11, OUTPUT);
   Serial.begin(57600);
   digitalWrite(11,HIGH);

   noInterrupts(); 


     TCCR2A = 0;
     TCCR2B = 0;
     TCNT2 = 0;

     TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20);
     TCCR2B = _BV(WGM22) | _BV(CS22);
     OCR2A = 4;
     TIMSK2 |= (1 << OCIE2A);

     interrupts(); // enable all interrupts

      }
    ISR (TIMER2_COMPA_vect){   
          counter+=1;
          if (counter==31){
            //PORTB = B00001000;
             OCR2A = 110;
              }
           else{
             if (counter>31){
                OCR2A = 6;
               counter=0;
                 }
             }

          }

      void loop() {
        Serial.print(counter);


        }