Forum: Mikrocontroller und Digitale Elektronik Timer Interrupt AVR90CAN128


von Alexander (Gast)


Lesenswert?

Schönen guten Tag,

ich bin seit knapp einer Woche am µC programmieren und wollte nun einen 
Interrupt bei jedem Übergang von Timer0 (8-bit) auslösen.
Funktion des Programms und Aufbau sind eigentlich sehr simpel: Eine LED 
(PortE am PIN4) soll vom Interrupt immer wieder eingeschaltet werden.

int main(void)
{DDRE= (1<<DDE4);

 TCCR0A= (1<<CS02) | (0<<CS01) | (1<<CS00); //Prescaler 1024
 TCNT0= 0x00;                               //Zähler auf 0 gesetzt
 TIMSK0= (1<<TOIE0);                        //Timer0 wird aktiviert

 sei();

while(1)
    {
    PORTE= (1<<PE4);
    }
}

ISR(TIMER0_OVF_vect)
{
  PORTE = (0<<PE4);
}

Allerdings geht es das Programm gar nicht in den Interrupt und die LED 
bleibt dauerhaft aus. Mittlerweile habe ich das Datenblatt schon 100x 
durchwühlt, mit anderen Codes verglichen etc...
Ich muss irgendwie an einer Stelle ein riesiges Brett vorm Kopf haben :)

Liebe Grüße,
Alex

von M. S. (elpaco)


Lesenswert?

Also was zunächst mal auffällt, du willst die LED mit "0" einschalten 
und mit "1" ausschalten?

Zudem wirst du das, was die ISR macht gar nicht bemerken, da sofort 
deine Hauptschleife die LED wieder auf "1" setzt:

>while(1)
>    {
>    PORTE= (1<<PE4);
>    }

von Alexander (Gast)


Lesenswert?

Alles klar, vielen Dank. Das stimmt natürlich! Jetzt steht in der 
while-Schleife nichts und im ISR Folgendes:

ISR(TIMER0_OVF_vect)
{
  if (PORTE & (0<<PE4))
  {
    PORTE = (1<<PE4);
  }
  if (PORTE & (1<<PE4))
  {
    PORTE = (0<<PE4);
  }
Anfangs habe ich PE4 im Main auf 0 gestzt. Die LED leuchtet dauerhaft 
und geht immer noch nicht in den ISR

Ich muss den Pin zum Einschalten der LED auf 0 setzen, damit er auf 
Masse gezogen wird.

von spess53 (Gast)


Lesenswert?

Hi

>    PORTE = (1<<PE4);
>  }
>  if (PORTE & (1<<PE4))
>  {
>    PORTE = (0<<PE4);
>  }

Rate mal was die if-Anweisung macht, wenn du vorher PR4 auf 1 gesetzt 
hat?

MfG spess

von M. S. (elpaco)


Lesenswert?

Am einfachsten kannst du den Pin mit einem XOR toggeln:

PORTE ^= (1<<PE4);

Angenommen, PE4 = 0: 0 XOR 1 = 1
analog PE4 = 1: 1 XOR 1 = 0

Dein µC sollte auch ein PINE4 = 1 zum toggeln verwenden können.


Allgemein ist auch die Schreibweise ~(1<<PE4) verbreiteter als (0<<PE4).

von Karl H. (kbuchegg)


Lesenswert?

> Allgemein ist auch die Schreibweise ~(1<<PE4) verbreiteter als (0<<PE4).


'verbreiteter' ist gut gesagt.
Man könnte auch so sagen, dass (0<<PE4) einfach nur Unsinn ist, auch 
wenn es in diesem konkreten Programm keine Rolle spielt, weil nur 1 Pin 
am Port benutzt wird.
Wenn schon, dann könnte man auch so sagen, dass ein simples 0 
verbreiteter ist als (0<<PE4). Denn
1
   PORTE = (0<<PE4);
ist in allen Belangen identisch zu
1
   PORTE = 0;

das Erwähnen von PE4 dient hier nur der "Ablenkung" (freundlich 
ausgedrückt).


Bitmanipulation
Der Teil muss im übrigen aus dem FF sitzen, wenn du zu Timern 
voranschreitest. Bits gezielt setzen, löschen und abfragen zu können ist 
Grundfertigkeit in der µC-Programmierung. Das muss auch nach 
durchzechter Nacht um 6 Uhr früh aus dem Stegreif fehlerfrei und wie aus 
der Pistole geschossen funktionieren.

von Alexander (Gast)


Lesenswert?

Ja ihr hattet Recht. Habe jetzt das mit der Bitmanipulation noch einmal 
gründlichst studiert und so weit es geht verinnerlicht...Übung macht den 
Meister :)

Allerdings leuchtet die LED immer noch dauerhaft, obwohl ich jetzt Pin4 
im Interrupt toggeln lasse.

Habt ihr vielleicht noch andere Ansätze was falsch gehen könnte?

Gruß,
Alex

von Karl H. (kbuchegg)


Lesenswert?

Alexander schrieb:

> Allerdings leuchtet die LED immer noch dauerhaft, obwohl ich jetzt Pin4
> im Interrupt toggeln lasse.

Das würden wir gerne alles mal sehen.

Wie immer gilt: Wenn du Hilfe zu einem Programm willst - zeig dein 
Programm.
Und zwar so, wie es jetzt ist. Was du gestern programmiert hast, gilt 
alles nichts mehr, denn in der Zwischenzeit hast du Veränderungen am 
Programm gemacht. Auf dieser Seite des Monitors kann aber keiner 
riechen, welche Veränderungen du vorgenommen hast.


Im übrigen: Hast du schon mal durchgerechnet, wie schnell deine LED 
eigentlich blinken sollte?

von Alexander (Gast)


Lesenswert?

> Im übrigen: Hast du schon mal durchgerechnet, wie schnell deine LED
> eigentlich blinken sollte?

Ja das sollte bei meinem 16MHz Prozessor, dem 8-bit Timer und dem 
Prescaler von 1024 so um die 30Hz sein. Ich denke, man erkennt dann 
wenigstens ein Flackern der LED.

Hier der Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
int main(void)
5
{DDRE= (1<<DDE4);  
6
 PORTE= (1<<PE4);  
7
 TIMSK0= (1<<TOIE0);
8
 TCCR0A= (1<<CS02) | (0<<CS01) | (1<<CS00);
9
 TCNT0= 0x00;
10
   
11
 sei();  
12
13
while(0)
14
    {
15
     }
16
}
17
18
ISR(TIMER0_OVF_vect)
19
{
20
  PORTE ^= (1<<PE4);
21
}

von asterix (Gast)


Lesenswert?

mach dir das leben doch nicht so schwer... entweder setzt du dir einen 
breakpoint, um festzustellen ob die die ISR routine erreichst... oder du 
setzt den PIN einfach HIGH... sobald die LED leuchtet weißt du die ISR 
wurde erreicht.. durch das fehlerhafte bit shifting und vielleicht auch 
fehlerhafte timing bekommst du nie das vor augen was du gerne hättest... 
fang doch erst mal klein an ;-)

von Karl H. (kbuchegg)


Lesenswert?

Alexander schrieb:

> Ja das sollte bei meinem 16MHz Prozessor, dem 8-bit Timer und dem
> Prescaler von 1024 so um die 30Hz sein. Ich denke, man erkennt dann
> wenigstens ein Flackern der LED.

Darauf würde ich nicht wetten.
1
uint8_t cnt;
2
3
....
4
5
ISR(TIMER0_OVF_vect)
6
{
7
  cnt++;
8
9
  if( cnt == 20 ) {
10
    cnt = 0;
11
    PORTE ^= (1<<PE4);
12
  }
13
}


Jetzt müsstest du das Blinken auf jeden Fall sehen.

von Alexander (Gast)


Lesenswert?

So habe jetzt mal zur Sicherheit den 16-bit Timer genommen und den Pin 
toggeln lassen. Jedenfallf funktioniert es jetzt und ich danke recht 
herzlich für die Hilfe!

Gruß,
Alex

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.