Inhaltsverzeichnis

Timer

Begriffe

Output Compare Units

Double Buffered Register

Clear Timer on Compare Match

Fast PWM (Asymmetric PWM)
Bild10

Glitch Free, Phase Correct PWM (Symmetric PWM)

8-Bit Timer

Output Compare Match / Waveform Generator

Double Buffering

Erzeugen von Timings

Auto Reload: CTC (clear timer on compare match)

Timer1 16Bit

Input Capture

Waveform Generation Mode

Timer Counter ATMEGA328p

Qellen

 

Timer

Begriffe

Timer/Counter

Prescaler

Multiplexer

Output Compare Units

Double Buffered Register

Clear Timer on Compare Match

Fast PWM (Asymmetric PWM)
Bild10

Glitch Free, Phase Correct PWM (Symmetric PWM)

Bild9

man sieht: symmetrisch/asymmetrisch bezogen auf die Mitte der Periode. Beim Umschalten auf ein neues Puls/Pause-Verhältnis erzeugt die symmetrische Variante weniger Oberwellen (Störungen, Glitches)

8-Bit Timer

Definition

BOTTOM: Zählerstand 0

MAX: Zählerstand 0xFF

TOP:  höchster Zählerstand; normalerweise TOP=MAX,
                     aber es kann auch TOP=OCR0A eingestellt werden.

Betriebsarten

Register

 

 

 

Mögliche Interrupt Flags:

Signale an den Zähler:

 

 

Der Zähler zählt bis 255 und läuft dann auf 0 über. Dabei setzt er ein Overflow-Flag und fordert einen Interrupt an. Wenn dere Interrupt erlaubt ist wird die zugehörige ISR (Interrupt Service Routine) angesprungen.

Getaktet wird der Zähler über die Flags TCCR0.CS02, TCCR0.CS01 und TCCR0.CS00. Der Takt kann 0 (Zähler stopp), intern oder extern sein.

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

int main(void)
{
TCCR0 = (1<<CS01); // Prescaler 8
TIMSK |= (1<<TOIE0);
sei();

while(1)
{

}
}

ISR (TIMER0_OVF_vect)
{
/* Interrupt Aktion alle
(1000000/8)/256 Hz = 488,28125 Hz
bzw.
1/488,28125 s = 2,048 ms
*/

}

 

Output Compare Match / Waveform Generator

Begriffe:

Bild7

 

Double Buffering

Doppelte Pufferung: die CPU greift auf das Schattenregister von OCR0x.
Normalbetrieb: die CPU greift direkt auf OCR0x zu.

Doppelte Pufferung synchronisiert das Update der OCR0x Register zu TOP bzw. BOTTOM der Zählsequenz. Dies verhindert unsymmetrische PWM Signale => Glitch-Free Output

 

Erzeugen von Timings

Am Pin PB0 soll folgendes Timing erzeugt werden:

Bild2

Idee: der Timer wird mit einem Wert geladen, so dass er nach 5ms überläuft. Dies löst einen Interrupt aus. In der ISR wird der Wert auf 3ms umgestellt usw.

Taktrate des Oszillators: 16MHz   Tosc=62.5ns

Überlauf beim Zählerstand 255 d.h. nach 256 Zyklen, also alle 256*62.5ns = 16µs. Viel zu schnell.

Wenn man den Takt herunterteilt ergeben sich:

Teiler

Periode des Taktes

Überlauf nach 256 Zyklen

1

62.5ns

16µs

8

500ns

128µs

64

4µs

1.024ms

256

16µs

4.096ms

1024

64µs

16.384ms

 

Man sieht: für ein Timing von 5ms eignet sich bei 8Bit und 16MHz nur der Teiler 1024. Ein Zählschritt dauert dann 64µs. Die gewünschten 5ms entsprechen daher 78.125 Taktperioden. Das Timing ist also nicht genau erreichbar.

Der Zähler wird nicht bei Null, sondern so gestartet, dass er nach 5ms überläuft. Der Wert dafür (preload value) ist 256-78 = 178.

Nachteil dieser Methode: das Laden der Timer in der ISR benötigt zusätzliche Rechenzeit und ändert daher das Timing leicht.

#define F_CPU 16000000

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

#define LED 0
#define PRELOAD_5MS 0x100 - 78
#define PRELOAD_3MS 0x100 - 47     //Timer overflow after 3 ms @16MHz

void setup();
int main(void)
{   setup();
sei();
while(1)
{
//TODO:: Please write your application code
for (volatile int i; i<10;i++);
}
}

void setup(){
// div 1024 ==> CS0=5
TCCR0B |=_BV(CS02)|_BV(CS00);
TIMSK0 |= _BV(TOIE0); //int enable
DDRB |= _BV(LED);
}

ISR(TIMER0_OVF_vect){
PORTB ^= _BV(LED); //Toggle Pin
if (PORTB & _BV(LED))
TCNT0 = PRELOAD_5MS;   //no need to stop counter (8bit operation)
else
TCNT0 = PRELOAD_3MS;


}

Auto Reload: CTC (clear timer on compare match)

 

  1. Bild3Register OCR0A setzen

  2. Wenn der Zählerstand den Wert OCR0A erreicht hat und überläuft, wird wahlweise ein Pin (OC0A) gesetzt (Null, Eins, Toggle) und/oder ein Interrupt ausgelöst

 

/* kner 2015

   CTC Autoreload:  set a Compare Value und restart at that value

*/

 

#include <avr/io.h>

#include <avr/interrupt.h>

void setup(){

    DDRD=(1<<DDD6);  //OC0A pin

 

    // Timer/Counter 0 initialization

    // Clock source: System Clock

    // Clock value: 15,625 kHz

    // Mode: CTC top=OCR0A

    // OC0A output: Toggle on compare match

    // OC0B output: Disconnected

    // Timer Period: 8,192 ms

    // Output Pulse(s):

    // OC0A Period: 16,384 ms Width: 8,192 ms

 

    // COM0A1/A0 0 1 Toggle OC0A on Compare Match

    // WGM02 WGM01 WGM00   010 for CTC Mode

    TCCR0A=(1<<COM0A0) | (1<<WGM01);

    TCCR0B=(1<<CS02) | (0<<CS01) | (1<<CS00);

    TCNT0=0x00;

    OCR0A=0x7F;  //COMPARE VALUE

 

    // Timer/Counter 0 Interrupt(s) initialization

    TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (1<<TOIE0);

    sei();

}

int main(void)

{  setup();

   while (1)

    {

        volatile int i; i++;

    }

}

ISR(TIMER0_OVF_vect)

{

    // never reached

    volatile static int i; i++;

}

 

ISR(TIMER0_COMPA_vect)

{

    // count the compare matches

    volatile static int i; i++;

}

 

Timer1 16Bit

Input Capture

Waveform Generation Mode

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Timer Counter ATMEGA328p

Bild4

 

Qellen

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR

Template für ATMEL Studio 6.2 Counter0.zip