Forum: Mikrocontroller und Digitale Elektronik membervariable in isr ändern


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Franz (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Franz schrieb:
> aber dadurch das in der ISR kein Objekt vorhanden ist,

Dann musst du die Objekte bekanntmachen.

von Franz (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.