Използване на таймери на Arduino

Използвам този код на Arduino, за да генерирам 5V, 200 KHz импулс с 50% ширина на импулса.

void setup() {
  // put your setup code here, to run once:
  pinMode(pwmpin, OUTPUT);
  pinMode(FBo, INPUT);
  pinMode(FBi, INPUT);
  noInterrupts(); // disable all interrupts 
  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0  = 0;
  OCR0A = 40; // compare match register Duty Cycle *   16MHz/200kHz
  OCR0B = 40; // compare match register 1 - Duty Cycle * 16MHz/200kHz
  TIMSK0 |= (1 << OCIE0A); // enable timer compare interrupt
  digitalWrite(pwmpin,HIGH);
  TCCR0B |= (1 << CS00);
  interrupts(); // enable all interrupts
}

ISR(TIMER0_COMPA_vect) {
  digitalWrite(pwmpin, digitalRead(pwmpin) ^ 1);
  //TIMSK0 |= (1 << OCIE0B);  // enable timer compare interrupt
  //TIMSK0 &= ~(1 << OCIE0A);  // disable timer compare interrupt
}

Вместо 5V 200 KHz импулс, той ми показва приблизително 2V 30 KHz сигнал. Може ли някой да ми каже какъв е проблема?


person Atal Khattak    schedule 06.01.2016    source източник


Отговори (1)


Проблемът е, че работите с Timer/Counter0 в нормален режим вместо в режим CTC.

Опитайте да добавите

TCCR0A |=  (1 << WGM01);

към вашата рутинна настройка, за да активирате нулиране на брояча при сравняване.


Нормалният режим позволява на таймера да брои от BOTTOM (0) до MAX (255) независимо от това на каква стойност сте задали OCR0A. Това ще задейства прекъсване на всеки 256 тактови цикъла (62,5 kHz с тактова честота 16 MHz). Вашият ISR трябва да превключи изходния щифт два пъти, за да изпълни един пълен цикъл на ШИМ, давайки наблюдаваната честота на ШИМ от около 30 kHz.

От Лист с данни на ATmega:

15.7.1 Нормален режим

[...] В този режим посоката на броене винаги е нагоре (нараства) и не се извършва изчистване на брояча. Броячът просто превишава, когато премине максималната си 8-битова стойност (TOP = 0xFF) и след това се рестартира от дъното (0x00).

и

15.7.2 Изчистване на таймера при режим на съпоставяне (CTC)

В режим Изчистване на таймера при сравнение или CTC (WGM02:0 = 2), регистърът OCR0A се използва за манипулиране на резолюцията на брояча. В режим CTC броячът се изчиства до нула, когато стойността на брояча (TCNT0) съвпада с OCR0A. [...]

За 2V, моето предположение е, че измервате средно напрежение (4.?V @ 50% работен цикъл) вместо PWM пиково напрежение.

person vega8    schedule 06.01.2016
comment
Благодаря ти за помощта. - person Atal Khattak; 06.01.2016