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