Difference between revisions of "AVR Embedded Tutorial - Timer, Counter/de"

From Free Pascal wiki
Jump to navigationJump to search
Line 14: Line 14:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
program Project1;
 
program Project1;
 
  procedure cli; assembler; inline; // Interrupt aus
 
  asm
 
          Cli
 
  end;
 
 
  procedure sei; assembler; inline; // Interrupt ein
 
  asm
 
          Sei
 
  end;
 
  
 
   procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
 
   procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
 
   const
 
   const
     t = 10;         // LED sollte nur bei jedem 10. Durchlauf umschalten.
+
     t         = 10; // LED sollte nur bei jedem 10. Durchlauf umschalten.
     z: integer = 0; // Zähler für Leerdurchläufe.
+
     z: integer = 0; // Zähler für Leerdurchläufe.
 
   begin
 
   begin
 
     TCNT0 := 128;                      // Speed halbieren  0 = langsam (default)
 
     TCNT0 := 128;                      // Speed halbieren  0 = langsam (default)
Line 35: Line 25:
 
       PORTD := PORTD or (1 shl 0);      // LED Pin0 ein
 
       PORTD := PORTD or (1 shl 0);      // LED Pin0 ein
 
     end;
 
     end;
     if (z = t * 2) then begin
+
     if (z = t shl 1) then begin
 
       PORTD := PORTD and not (1 shl 0); // LED Pin0 aus
 
       PORTD := PORTD and not (1 shl 0); // LED Pin0 aus
 
       z := 0;
 
       z := 0;
Line 43: Line 33:
 
   procedure Timer1_Interrupt; public Name 'TIMER1_COMPA_ISR'; interrupt;
 
   procedure Timer1_Interrupt; public Name 'TIMER1_COMPA_ISR'; interrupt;
 
   const
 
   const
     t = 500;       // LED sollte nur bei jedem 500. Durchlauf umschalten.
+
     t         = 500; // LED sollte nur bei jedem 500. Durchlauf umschalten.
     z: integer = 0; // Zähler für Leerdurchläufe.
+
     z: integer =   0; // Zähler für Leerdurchläufe.
 
   begin
 
   begin
 
     Inc(z);
 
     Inc(z);
Line 50: Line 40:
 
       PORTD := PORTD or (1 shl 1);      // LED Pin1 ein
 
       PORTD := PORTD or (1 shl 1);      // LED Pin1 ein
 
     end;
 
     end;
     if (z = t * 2) then begin
+
     if (z = t shl 1) then begin
 
       PORTD := PORTD and not (1 shl 1); // LED Pin1 aus
 
       PORTD := PORTD and not (1 shl 1); // LED Pin1 aus
 
       z := 0;
 
       z := 0;
Line 58: Line 48:
  
 
begin
 
begin
   // Interupt unterbinden.
+
   // -- Interupt unterbinden.
   cli();
+
   asm cli end;
  
   // -- Bit 0 und 1 von PortD auf Ausgabe stellen.
+
   // -- Bit 0 und 1 von PORTD auf Ausgabe stellen.
   DDRD := DDRD or (1 shl 0) or (1 shl 1);
+
   DDRD   := %00000001;
  
 
   // -- Timer0 initialisieren.
 
   // -- Timer0 initialisieren.
 
   TCCR0A := 0;
 
   TCCR0A := 0;
   TCCR0B := %101;                   // CPU-Takt / 1024
+
   TCCR0B := %101;                   // CPU-Takt / 1024
   TIMSK := TIMSK or (1 shl OCIE0A); // Timer0 soll Interrupt auslösen.
+
   TIMSK := TIMSK or (1 shl OCIE0A); // Timer0 soll Interrupt auslösen.
  
 
   // -- Timer1 initialisieren.
 
   // -- Timer1 initialisieren.
   TCCR1A := 1;                     // CTC-Modus
+
   TCCR1A := 1;                       // CTC-Modus
   TCCR1B := %010;                   // CPU-Takt / 8
+
   TCCR1B := %010;                   // CPU-Takt / 8
   TIMSK := TIMSK or (1 shl OCIE1A); // Timer1 soll Interrupt auslösen.
+
   TIMSK := TIMSK or (1 shl OCIE1A); // Timer1 soll Interrupt auslösen.
  
 
   // -- Interrupt aktivieren.
 
   // -- Interrupt aktivieren.
   sei();
+
   asm sei end;
 +
 
 +
  // -- Hauptschleife
 
   repeat
 
   repeat
 
     // Mache Irgendwas.
 
     // Mache Irgendwas.

Revision as of 22:45, 26 November 2017

Template:Translate

Timer / Counter

Titel

Dieses Beispiel zeigt, wie man die beiden Timer eines ATtiny2313 verwenden kann.

Jeder Timer steuert eine LED an, welche an Bit 0 und 1 des PortD sind. Dabei sollte die LED an Pin0 etwas schneller blinken.

Hier geht es nicht darum, alle Register zu verstehen. Dies sollte nur ein praktisches Beispiel sein, wie man es in FPC umsetzt.

Genauere Details gibt es hier: https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR

Beispiel-Code

program Project1;

  procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
  const
    t          = 10; // LED sollte nur bei jedem 10. Durchlauf umschalten.
    z: integer =  0; // Zähler für Leerdurchläufe.
  begin
    TCNT0 := 128;                       // Speed halbieren  0 = langsam (default)
    Inc(z);
    if (z = t) then begin
      PORTD := PORTD or (1 shl 0);      // LED Pin0 ein
    end;
    if (z = t shl 1) then begin
      PORTD := PORTD and not (1 shl 0); // LED Pin0 aus
      z := 0;
    end;
  end;

  procedure Timer1_Interrupt; public Name 'TIMER1_COMPA_ISR'; interrupt;
  const
    t          = 500; // LED sollte nur bei jedem 500. Durchlauf umschalten.
    z: integer =   0; // Zähler für Leerdurchläufe.
  begin
    Inc(z);
    if (z = t) then begin
      PORTD := PORTD or (1 shl 1);      // LED Pin1 ein
    end;
    if (z = t shl 1) then begin
      PORTD := PORTD and not (1 shl 1); // LED Pin1 aus
      z := 0;
    end;
  end;


begin
  // -- Interupt unterbinden.
  asm cli end;

  // -- Bit 0 und 1 von PORTD auf Ausgabe stellen.
  DDRD   := %00000001;

  // -- Timer0 initialisieren.
  TCCR0A := 0;
  TCCR0B := %101;                    // CPU-Takt / 1024
  TIMSK  := TIMSK or (1 shl OCIE0A); // Timer0 soll Interrupt auslösen.

  // -- Timer1 initialisieren.
  TCCR1A := 1;                       // CTC-Modus
  TCCR1B := %010;                    // CPU-Takt / 8
  TIMSK  := TIMSK or (1 shl OCIE1A); // Timer1 soll Interrupt auslösen.

  // -- Interrupt aktivieren.
  asm sei end;

  // -- Hauptschleife
  repeat
    // Mache Irgendwas.
  until 1 = 2;
end.

Stolperfalle

Die Namen der Proceduren können abweichen, ein Beispiel:

// ATtiny2313
procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
// ATtiny44
procedure Timer0_Interrupt; public Name 'TIM0_COMPA_ISR'; interrupt;

Siehe auch