CTC timer v mikrokontroléru ATtiny84

Zápisník experimentátora

Hierarchy: Časovač (timer)

ATtiny84 obsahuje dva timery. Jeden je 8bitový a druhý timer je 16bitový. V tomto článku se podíváme na časovače z hlediska CTC režimu. Na generování programů budeme využívat online kalkulátor. Já jsem použil mikrokontrolér ATtiny84 ve verzi SMD a proto jsem ho měl na adaptéru, který lze zasunout do breadboardu. Použil jsem stejné zapojení jako v článku o programování ATtiny84 pomocí Arduina.

Použité součástky

Při práci s ATtiny84 používám na programování Arduino. Možná to byla náhoda, ale přes USBasp se mi jednou při programování pojistek ATtiny84 zaseklo. Při použití Arduina jsem tento problém neměl.

Zdrojové kódy jsem psal pro frekvence 1 MHz a 8 MHz. Používal jsem jádro https://github.com/SpenceKonde/ATTinyCore. Pro každý timer jsou dva příklady. Všechny blikají LED diodou, která je připojena na pin 10. Pin 10 je na mikrokontroléru umístěn podle obrázku. Je třeba si ale vybrat správnou orientaci (counterclockwise) při nastavování desky.

Timer0

Timer0 je 8bitový čítač. Pokud ho chceme použít k vytvoření nižší frekvence, musíme si pomoci interní děličky, která je vytvořena pomocí proměnné divider. V tomto případě je frekvence přerušení 100 Hz a pomocí děličky je upravena na 1 Hz.

#define ledPin 10
volatile int divider=0;

void setupTimer0() {
  noInterrupts();
  // Clear registers
  TCCR0A = 0;
  TCCR0B = 0;
  TCNT0 = 0;

  // 100.16025641025641 Hz (1000000/((155+1)*64))
  OCR0A = 155;
  // CTC
  TCCR0A |= (1 << WGM01);
  // Prescaler 64
  TCCR0B |= (1 << CS01) | (1 << CS00);
  // Output Compare Match A Interrupt Enable
  TIMSK0 |= (1 << OCIE0A);
  interrupts();
}

void setup() {
  pinMode(ledPin, OUTPUT);
  setupTimer0();
}

void loop() {
}

ISR(TIMER0_COMPA_vect) {
  if(divider==0)
    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
  divider++;
  divider%=100;
}

Timer1

Timer1 je 16bitový čítač. Díky tomu se bez problémů nastavují i nízké frekvence. V tomto případě je frekvence 1 Hz.

#define ledPin 10

void setupTimer1() {
  noInterrupts();
  // Clear registers
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  // 1 Hz (1000000/((15624+1)*64))
  OCR1A = 15624;
  // CTC
  TCCR1B |= (1 << WGM12);
  // Prescaler 64
  TCCR1B |= (1 << CS11) | (1 << CS10);
  // Output Compare Match A Interrupt Enable
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void setup() {
  pinMode(ledPin, OUTPUT);
  setupTimer1();
}

void loop() {
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

Zdrojový kód

Zdrojový kód se nachází na serveru GitHub.


09.03.2018


Menu