这是我第一个使用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;
}
答案 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);
}