Timer Interrupt AVR90CAN128

Gast #3840802
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
Gast #3840892
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.
#3840939
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).
#3841034
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.
Gast #3841976
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
#3842014
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?
Gast #3842109
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
}
Gast #3842123
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 ;-)
#3842144
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren