Forum: Mikrocontroller und Digitale Elektronik ATMega 2560 Timer Interrupt absetzen


von Jochen (Gast)


Lesenswert?

Schönen guten Abend,
ich versuche auf dem AT2560 ein Time-Interrupt auszulösen.
Beim meinem Vorgehen habe ich mich an
http://www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/
orientiert.
Leider wird das Interrupt nicht abgesetzt (die LEDS in der ISR Routine 
bleiben allesammt aus). Was ist zu ändern?
Schönen dank,
jo
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define TCCR0 _SFR_IO8(0x33)
4
#define CS00 0
5
#define CS01 1
6
#define CS02 2
7
#define WGM01 3
8
#define COM00 4
9
#define COM01 5
10
#define WGM00 6
11
12
volatile uint8_t count;
13
int a=1;
14
int main( void )
15
{
16
  
17
  DDRL=0xff;
18
  // initialize Timer1
19
    cli();          // disable global interrupts
20
    TCCR1A = 0;     // set entire TCCR1A register to 0
21
    TCCR1B = 0;     // same for TCCR1B
22
 
23
    // set compare match register to desired timer count:
24
    OCR1A = 15624;
25
    // turn on CTC mode:
26
    TCCR1B |= (1 << WGM12);
27
    // Set CS10 and CS12 bits for 1024 prescaler:
28
    TCCR1B |= (1 << CS10);
29
    TCCR1B |= (1 << CS12);
30
    // enable timer compare interrupt:
31
    TIMSK1 |= (1 << OCIE1A);
32
    sei();          // enable global interrupts
33
 
34
 
35
while( 1 );
36
}
37
38
ISR(TIMER0_OVF_vect)
39
{
40
   //This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
41
   //CPU automatically call this when TIMER0 overflows.
42
   if(a=1){
43
   PORTL=0b00000111;
44
   a=0;
45
   }   else {
46
     a=1;
47
     PORTL=0b00000000;
48
   }
49
}

von Helfender (Gast)


Lesenswert?

Hallo,

ich habe das Programm nur kurz überflogen, aber eines ist mir direkt 
aufgefallen: Du gibst beim Timer1 den Compare-Interrupt frei, aber der 
ISR-Vektor ist der vom Timer0-Overflow-Interrupt. Das passt irgendwie 
nicht zusammen (und dürfte so nicht funktionieren) ...
Verwende den ISR-Vektor vom Compare-Interrupt des Timers 1.

MfG

von Jochen (Gast)


Lesenswert?

Helfender, danke für den Tipp. Das ist dann klar, dass der Interrupt 
nicht ausgelöst wird.
Nun leuchten die 3 Leds, d.h. die if-Anweisung
1
 if(a=1){
2
   PORTL=0b00000111;
3
   a=0;
4
   }
wird offenbar ausgeführt. Jedoch leuchten die LEDs dauerhaft, was ich 
mir nicht erklären kann. Mit jeder 2ten Interrupt Routine sollten sie 
ausgeschaltet werden.
Was ist am Code noch nicht OK?

von Jochen (Gast)


Lesenswert?

entweder der Interrupt wird nur einmal ausgelöst, oder an der "Schalt 
Logik" der LEDs ist etwas verkehrt. Nur was?
beste Grüße

von M. K. (avr-frickler) Benutzerseite


Lesenswert?

Jochen schrieb:
> int a=1;

Jochen schrieb:
> Jedoch leuchten die LEDs dauerhaft, was ich
> mir nicht erklären kann. Mit jeder 2ten Interrupt Routine sollten sie
> ausgeschaltet werden.
> Was ist am Code noch nicht OK?

Stiochwort: volatile
Versuch mal
1
volatile int a=1

Jochen schrieb:
> #define TCCR0 _SFR_IO8(0x33)
> #define CS00 0
> #define CS01 1
> #define CS02 2
> #define WGM01 3
> #define COM00 4
> #define COM01 5
> #define WGM00 6

Warum die ganzen defines? Die sollten eigentlich schon alle über 
#include <avr/io.h> definiert sein.

von Jochen (Gast)


Lesenswert?

Danke! Die LEDs blinken leider immer noch nicht. Was kann das noch sein?

von Thomas E. (thomase)


Lesenswert?

Jochen schrieb:
> Danke! Die LEDs blinken leider immer noch nicht. Was kann das noch sein?
Wenn du schon irgendwo abschreibst, dann schreib wenigstens richtig ab:

>And we’ll need to replace our overflow ISR with a compare match version:

>1234 ISR(TIMER1_COMPA_vect) {     digitalWrite(LEDPIN, !digitalRead
>(LEDPIN)); }

Helfender schrieb:
> ich habe das Programm nur kurz überflogen, aber eines ist mir direkt
> aufgefallen: Du gibst beim Timer1 den Compare-Interrupt frei, aber der
> ISR-Vektor ist der vom Timer0-Overflow-Interrupt. Das passt irgendwie
> nicht zusammen (und dürfte so nicht funktionieren) ...
> Verwende den ISR-Vektor vom Compare-Interrupt des Timers 1.
Steht doch alles schon da.

mfg.

von Jochen (Gast)


Lesenswert?

Den Interruptvektor habe ich direkt nach dem Hinweis angepasst. Der Code 
gestaltet sich nach den Tipps nun
[
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
volatile uint8_t count;
6
volatile int a=1;
7
int main( void )
8
{
9
  
10
  DDRL=0xff;
11
  // initialize Timer1
12
    cli();          // disable global interrupts
13
    TCCR1A = 0;     // set entire TCCR1A register to 0
14
    TCCR1B = 0;     // same for TCCR1B
15
 
16
    // set compare match register to desired timer count:
17
    OCR1A = 15624;
18
    // turn on CTC mode:
19
    TCCR1B |= (1 << WGM12);
20
    // Set CS10 and CS12 bits for 1024 prescaler:
21
    TCCR1B |= (1 << CS10);
22
    TCCR1B |= (1 << CS12);
23
    // enable timer compare interrupt:
24
    TIMSK1 |= (1 << OCIE1A);
25
    sei();          // enable global interrupts
26
 
27
 
28
while( 1 );
29
}
30
31
ISR(TIMER1_COMPA_vect)
32
{
33
   //This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
34
   //CPU automatically call this when TIMER0 overflows.
35
    if(a=1){
36
   PORTL=0b01000111;
37
   a=0;
38
   }   else {
39
     a=1;
40
     PORTL=0b00000000;
41
   }
42
     
43
   }

Dennoch blinken die LEDs nicht.

von test (Gast)


Lesenswert?

Jochen schrieb:
> if(a=1){

Schau dir das mal genau an.

von Thomas E. (thomase)


Lesenswert?

Jochen schrieb:
> if(a=1){
Fällt dir da auch was auf?

mfg.

von Helfender (Gast)


Lesenswert?

> if(a=1)

Stichwort: Unterschied der Schreibweise bei Vergleich und Zuweisung! 
(C-Grundlagen)

von Jochen (Gast)


Lesenswert?

gleich 3 mal ;) Ja klar (bin noch relativ Anfänger ....)
danke an alle Helfer!!

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.