Forum: Mikrocontroller und Digitale Elektronik membervariable in isr ändern


von Franz (Gast)


Lesenswert?

Hallo,
ich versuche zum ersten mal einen Mikrocontroller in C++ zu 
Programmieren. Das funktioniert auch soweit ganz gut, bis auf ISR. Diese 
habe ich als external "C" eingebunden.
Hierbei habe ich Probleme.
So habe ich eine ISR für einen Timer,
timer.h
1
#ifndef TIMER_H_
2
#define TIMER_H_
3
4
#include <avr/interrupt.h>
5
#include <avr/io.h>
6
#include <stdint.h>
7
8
extern "C" void TIMER0_COMPA_vect(void) __attribute__ ((signal));
9
extern "C" void TIMER2_COMPA_vect(void) __attribute__ ((signal));
10
11
class timer {
12
    
13
    public:
14
    timer(volatile uint8_t &tccra, uint8_t tccraNewState,
15
          volatile uint8_t &tccrb, uint8_t tccrbNewState,
16
          volatile uint8_t &ocra, uint8_t ocraNewState,
17
          volatile uint8_t &timsk, uint8_t timskNewState);
18
    ~timer();
19
20
    uint16_t getMilliseconds();
21
    uint8_t getSeconds();
22
    uint8_t getMinutes();
23
    uint8_t getHours();
24
    bool    getNewTime();
25
26
    void setMilliseconds(uint16_t milliseconds);
27
    void setSeconds(uint8_t seconds);
28
    void setMinutes(uint8_t minutes);
29
    void setHours(uint8_t hours);
30
    void setNewTime(bool newTime);
31
32
    friend void TIMER0_COMPA_vect(void);
33
    friend void TIMER2_COMPA_vect(void);
34
    
35
    static uint8_t _newTime;
36
37
    private:
38
    uint8_t _tccrb;
39
    uint8_t _tccrbNewState;
40
    static uint16_t _milliseconds;
41
    static uint8_t _seconds;
42
    static uint8_t _minutes;
43
    static uint8_t _hours;
44
45
46
};
47
48
#endif

timer.cpp
1
#include <avr/interrupt.h>
2
#include <avr/io.h>
3
#include "timer.h"
4
#include "../Button/button.h"
5
6
uint16_t timer::_milliseconds = 0;
7
uint8_t timer::_seconds = 0;
8
uint8_t timer::_minutes = 0;
9
uint8_t timer::_hours = 0;
10
uint8_t timer::_newTime = 0;
11
12
13
14
timer::timer(volatile uint8_t &tccra, uint8_t tccraNewState,
15
             volatile uint8_t &tccrb, uint8_t tccrbNewState,
16
             volatile uint8_t &ocra, uint8_t ocraNewState,
17
             volatile uint8_t &timsk, uint8_t timskNewState)
18
{
19
    tccra |= tccraNewState;
20
    tccrb |= tccrbNewState;
21
    ocra |= ocraNewState;
22
    timsk |= timskNewState;
23
}
24
25
timer::~timer()
26
{
27
}
28
29
uint16_t timer::getMilliseconds()
30
{
31
    return _milliseconds;
32
}
33
34
void timer::setMilliseconds(uint16_t milliseconds)
35
{
36
    _milliseconds = milliseconds;
37
}
38
39
uint8_t timer::getSeconds()
40
{
41
    return _seconds;
42
}
43
44
void timer::setSeconds(uint8_t seconds)
45
{
46
    _seconds = seconds;
47
}
48
49
uint8_t timer::getMinutes()
50
{
51
    return _minutes;
52
}
53
54
void timer::setMinutes(uint8_t minutes)
55
{
56
    _minutes = minutes;
57
}
58
59
uint8_t timer::getHours()
60
{
61
    return _hours;
62
}
63
64
void timer::setHours(uint8_t hours)
65
{
66
    _hours = hours;
67
}
68
69
bool timer::getNewTime()
70
{
71
    return _newTime;
72
}
73
74
void timer::setNewTime(bool newTime)
75
{
76
    _newTime = newTime;
77
}
78
79
void TIMER0_COMPA_vect(void)
80
{
81
    timer::_milliseconds++;
82
    timer::_newTime = true;
83
    if(timer::_milliseconds >= 500 )
84
    {
85
        PORTB ^= ( 1 << PORTB5 );
86
        timer::_seconds++;
87
        timer::_milliseconds = 0;
88
        timer::_newTime = true;
89
        if(timer::_seconds >= 10 )
90
        {
91
            timer::_minutes++;
92
            timer::_seconds = 0;
93
            if(timer::_minutes >= 10)
94
            {
95
                timer::_hours++;
96
                timer::_minutes = 0;
97
                if(timer::_hours >= 10)
98
                {
99
                    timer::_hours = 0;
100
                }
101
            }
102
        }
103
    }
104
}
105
106
107
void TIMER2_COMPA_vect(void)
108
{
109
    static uint16_t millis = 0;
110
    static uint8_t seconds = 0;
111
    millis++;
112
    if(millis >= 500 )
113
    {
114
        //PORTB ^= ( 1 << PORTB5 );
115
        seconds++;
116
        millis = 0;
117
    }
118
119
}

In der Hauptfunktion erstelle ich zwei Timer (timer0 timer2) (AVR, beide 
Timer 8-bit).

Problem 1)
in der while-Schleife in der Hauptfunktion frage ich die Variable 
_newTime ab. Wenn diese True ist, ist eine Sekunde vorüber. Zum Testen 
habe ihc diese mal vor dem Sekundenübergang gesetzt. Diese wird also bei 
jedem Interrupt true.
Aus der HAuptfunktion
1
if(timer0.getNewTime() == true)
2
    {
3
        timer0.setMilliseconds(0);

damit setzte ich die Millisekunden immer wieder auf null, sodass nie 
eine Sekunde vergeht und die LED nicht blinkt. Das funktioniert auch. 
schreibe ich allerdings
1
timer2.setMilliseconds(0)
passiert genau das selbe. Also die Millisekunden von Timer0 werden 
zurückgesetzt. Aber warum? Ich wollte eigentlich die Millisekunden von 
timer2 zurücksetzen.

Problem2)
Ich habe einen weiteren Interrupt(einen externen Interrupt -> Button). 
Wenn ich diesen drücke, möchte ich gerne die Zeiten alle auf 0 setzen. 
Allerdings kennt die ISR vom Button die Objekte timer0 und timer2 nicht. 
Wie kann ich dennoch auf die Variablen zugreifen?

Franz

von Rolf M. (rmagnus)


Lesenswert?

Franz schrieb:
> Also die Millisekunden von Timer0 werden zurückgesetzt. Aber warum?

Na weil du geschrieben hast, dass alle einen gemeinsamen 
millisekunden-Zähler haben sollen:

> static uint16_t _milliseconds;
  ~~~~~~

Was meinst du denn, was static macht?

von Franz (Gast)


Lesenswert?

Wie kann ich denn in der ISR auf die Variablen zugreifen? Habe sie schon 
Public gemacht, aber dadurch das in der ISR kein Objekt vorhanden ist, 
kennt diese die Variablen nicht.

von MaWin (Gast)


Lesenswert?

Franz schrieb:
> aber dadurch das in der ISR kein Objekt vorhanden ist,

Dann musst du die Objekte bekanntmachen.

von Franz (Gast)


Lesenswert?

MaWin schrieb:
> Dann musst du die Objekte bekanntmachen.

Weisst du auch, wie ich das am besten mache? Oder besser noch, hast du 
einen Link oder ähnliches, wo ich mir das beschrieben ist?

von MaWin (Gast)


Lesenswert?

Franz schrieb:
> Weisst du auch, wie ich das am besten mache? Oder besser noch, hast du
> einen Link oder ähnliches, wo ich mir das beschrieben ist?

Im einfachsten Fall sind die Instanzen einfach globale Objekte. Das kann 
dann natürlich noch beliebig komplizierter werden mit Pointern und new 
oder ähnlichem.

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.