Forum: Mikrocontroller und Digitale Elektronik Timerinterrupt C++ wird nicht ausgelöst


von Franz (Gast)


Lesenswert?

Hallo,
ich bekomme es leider immer noch nicht vernünftig hin, Interruptroutinen 
für einen Atmega in C++ zu implementieren.
Jetzt wollte ich die Objekte Global machen und in den ISRs dann die 
entsprechende Funktion aufrufen.
1
#include "system.h"
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include "Timer/timer.h"
5
6
timer timer0(TCCR0A,
7
             ~(1 << WGM00) | (1 << WGM01),
8
             TCCR0B,
9
             (1 << CS00) | (1 << CS01) & ~(1 << CS02),
10
             OCR0A,
11
             OCR0A = 250 - 1,
12
             TIMSK0,
13
             (1 << OCIE0A));
14
15
int main(void)
16
{
17
  while(1)
18
  {
19
    if(timer0.getNewTime() == true){
20
    ....
21
    }
22
  }
23
}
24
25
void TIMER0_COMPA_vect(void)
26
{    
27
    timer0.interrupt();
28
}

in timer.cpp
1
timer::timer(volatile uint8_t &tccra, uint8_t tccraNewState,
2
             volatile uint8_t &tccrb, uint8_t tccrbNewState,
3
             volatile uint8_t &ocra, uint8_t ocraNewState,
4
             volatile uint8_t &timsk, uint8_t timskNewState)
5
{
6
    tccra |= tccraNewState;
7
    tccrb |= tccrbNewState;
8
    ocra |= ocraNewState;
9
    timsk |= timskNewState;
10
}
11
12
timer::~timer()
13
{
14
}
15
16
bool timer::getNewTime()
17
{
18
    return _newTime;
19
}
20
void timer::interrupt()
21
{
22
    _milliseconds++;
23
    if(_milliseconds >= 500)
24
    {
25
        _milliseconds = 0;
26
        _seconds++;
27
        PORTB ^= ( 1 << PORTB5 );
28
        //_newTime = true;
29
    }
30
}

Zum Testen möchte ich zunächst wieder die LED and PB5 blinken lassen. 
Aber diese bleibt aus. Auch in der Simulation wird nicht in die ISR 
gesprungen. Kann mir da jemand evtl. sagen, wieso die ISR nicht 
aufgerufen wird?
In der Simulation wird der Brakepoint an der Stelle
1
if(timer0.getNewTime() == true){
auch nie erreicht. Vorher wird alles Resettet und von vorne gestartet.

Gruß
Franz

von hp-freund (Gast)


Lesenswert?

Habe lange nichts mit Atmel gemacht, aber braucht das nicht ein:

sei();

von Stefan E. (sternst)


Lesenswert?

avr/interrupt.h einbinden, und das ISR()-Makro verwenden.

von Matthias H. (hallamen)


Lesenswert?

Bitte ganzen Code posten:

#include "system.h"
#include "Timer/timer.h"

von Franz (Gast)


Lesenswert?

hp-freund schrieb:
> sei();

natürlich, das habe ich ausversehen mit rausgelöscht. habe ich aber vor 
der while-schleife stehen.

Stefan E. schrieb:
> avr/interrupt.h einbinden, und das ISR()-Makro verwenden.

habe ich geändert
1
ISR(TIMER0_COMPA_vect)
2
{    
3
    timer0.interrupt();
4
}

Matthias H. schrieb:
> #include "system.h"
> #include "Timer/timer.h

system.h: hier ist nur F_CPU definiert
1
#ifndef SYSTEM_H_
2
#define SYSTEM_H_
3
4
#define  F_CPU 16000000
5
6
#endif

timer.h
1
#ifndef TIMER_H_
2
#define TIMER_H_
3
4
#include <avr/io.h>
5
#include <stdint.h>
6
7
8
class timer {
9
    
10
11
    public:
12
    timer(volatile uint8_t &tccra, uint8_t tccraNewState,
13
          volatile uint8_t &tccrb, uint8_t tccrbNewState,
14
          volatile uint8_t &ocra, uint8_t ocraNewState,
15
          volatile uint8_t &timsk, uint8_t timskNewState);
16
    ~timer();
17
18
    uint16_t getMilliseconds();
19
    uint8_t getSeconds();
20
    uint8_t getMinutes();
21
    uint8_t getHours();
22
    bool    getNewTime();
23
24
    void setMilliseconds(uint16_t milliseconds);
25
    void setSeconds(uint8_t seconds);
26
    void setMinutes(uint8_t minutes);
27
    void setHours(uint8_t hours);
28
    void setNewTime(bool newTime);
29
    void interrupt();
30
    
31
32
    private:
33
    
34
    bool _newTime;
35
    
36
    uint16_t _milliseconds;
37
    uint8_t _seconds;
38
    uint8_t _minutes;
39
    uint8_t _hours;
40
};
41
42
#endif

von Werner (Gast)


Lesenswert?

Schau mal bei Ihm hier, ruft sogar direkt die Methode auf:

https://github.com/Phunkafizer/avr_seesys/blob/master/timer.h

(unten)

Werner

von Vincent H. (vinci)


Lesenswert?

Franz schrieb:
> habe ich geändert
>
1
> ISR(TIMER0_COMPA_vect)
2
> {
3
>     timer0.interrupt();
4
> }


Übersetzt du den obigen Code mit g++?
Wenn ja, dann musst du die Funktion als extern "C" deklarieren.
1
extern "C" ISR(TIMER0_COMPA_vect)
2
{
3
    timer0.interrupt();
4
}


Generell sollte man die Nutzung von C-Makros unter C++ vermeiden, vor 
allem wenn sie wie im Fall von Atmel offensichtlich nicht für C++ 
ausgelegt sind.


Die Methode direkt Aufrufen ist ausschließlich dann möglich, wenn sie 
statisch ist.

von Wilhelm M. (wimalopaan)


Lesenswert?

Franz schrieb:
> Hallo,
> ich bekomme es leider immer noch nicht vernünftig hin, Interruptroutinen
> für einen Atmega in C++ zu implementieren.

Ich denke, mal, dass der Timer gar nicht läuft. Du stellst da TimerMode 
6 (reserved) ein. Schau Dir mal an, was Du in tccr0a schreibst.

von Stefan E. (sternst)


Lesenswert?

Vincent H. schrieb:
> Übersetzt du den obigen Code mit g++?
> Wenn ja, dann musst du die Funktion als extern "C" deklarieren.

Nein, muss er nicht. Das erledigt das ISR-Makro bereits.

Vincent H. schrieb:
> wenn sie wie im Fall von Atmel offensichtlich nicht für C++
> ausgelegt sind

Wie kommst du darauf?

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.