Forum: Mikrocontroller und Digitale Elektronik Asynchroner Timer: Zugriff auf Variablen


von Chris R. (mrgreen)


Lesenswert?

Hallo,
ich glaube beobachtet zu haben, dass mein Programm spinnt, wenn ich aus 
dem asynchron getakteten Timer heraus auf Variablen zugreife. Das würde 
ja auch Sinn ergeben, eben weil der Zugriff sozusagen asynchron erfolgt.

Wie kann ich es denn jetzt aber machen, dass z.B. eine Variable in dem 
Timer asynchron hochgezählt und an anderer Stelle ausgelesen werden 
kann?


Gruß
Mr.Green

von Maxi (Gast)


Lesenswert?


von Johannes M. (johnny-m)


Lesenswert?

"Aus einem Timer heraus" kann auf gar nichts zugegriffen werden. Du 
meinst schätzungsweise einen Timer-Interrupt-Handler...

Ohne Deinen Code zu sehen, kann man auch nur Vermutungen anstellen, was 
da schiefgehen könnte (z.B. volatile bei der Variablendeklaration 
vergessen usw...).

von Chris R. (mrgreen)


Lesenswert?

Ja, natürlich die ISR...
Also: Timer2 ISR.
Timer2 ist asynchron getaktet.

Die Variable ist volatile.

Code:
1
uint16_t sec_counter = 0;
2
3
volatile uint8_t start_meas = 0;
4
5
volatile uint8_t meas_time = 0;
6
7
#define MEAS_TIME  5  
8
9
int main() {
10
11
  uint16_t i;
12
13
  //Asynchron getaktet
14
15
  ASSR |= 1<<AS2;  //async Takt
16
17
18
  //Auf Einschwingen des 32k Quarzes warten
19
20
  for(i=0; i<100; i++)
21
    _delay_ms(10);
22
23
  TCCR2 = (1<<CS22)|(1<<CS21);  //genau 2 sec
24
25
  while(! ASSR & (1<<TCR2UB))
26
    ;  //Warten bis Update der Register möglich
27
28
  TIMSK |= (1<<TOIE2);
29
30
  sei();
31
32
  while(1) {
33
    //Oszi braucht einige Zeit zum Einschwingen
34
    //Auf Einschwingen des 32k Quarzes warten; dummy write
35
36
    OCR2 = 0;
37
38
    while(! ASSR & (1<<OCR2UB))
39
      ;  //Warten bis Update der Register möglich    
40
41
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
42
    sleep_mode();
43
44
    if(start_meas == 1) {
45
46
      [...]      
47
48
49
50
    } 
51
  }
52
  return 0;
53
}
54
55
56
//TImer 2 ISR: Asynchon getaktet
57
//weckt den Atmega aus dem Sleepmode auf
58
59
ISR(TIMER2_OVF_vect) // timer_overflow
60
{  
61
  if(meas_time == 1) {
62
    start_meas = 1;
63
    meas_time = 0;
64
  } else
65
    meas_time++;
66
}

Die ISR wird aufgerufen, selten wird start_meas auch 1, sodass er in die 
if innerhalb der main reingeht. Manchmal aber auch nicht.

von Maxi (Gast)


Lesenswert?

> selten wird start_meas auch 1
Das es das überhaupt wird, würde mich stark wundern. Es sei denn der 
Code zeigt hier nicht das wesentliche. Was versteckt sich hinter dem 
...?

Auf welche Weise wird denn meas_time == 1?  Voodoo?


Bitte

http://www.avrfreaks.net/index.php?name=PNphpBB2&a...

lesen
und Frage überarbeiten.

von Maxi (Gast)


Lesenswert?

Und was soll dieses "asynchron" andauernd? Externer Takt oder was? Dann 
schreib das doch, bitte.

von Chris R. (mrgreen)


Lesenswert?

Wie meas_time== 1 wird? Nun, durch den else-Zwei würde ich sagen. Dafür 
braucht es nicht mal Voodoo...

Was in der [...] steckt ist vollkommen ohne Belang, dahin kommt er ja 
nicht (wie ich oben schrieb)

Asynchron heißt asynchron. Genauso, wie Atmel es im Datenblatt 
beschreibt (Mega8: S 119 ff). Nichts anderes. Natürlich extern getaktet; 
intern wäre es synchron zur Main-Clockdomain.

von Johannes M. (johnny-m)


Lesenswert?

Maxi wrote:
> Und was soll dieses "asynchron" andauernd? Externer Takt oder was? Dann
> schreib das doch, bitte.
Wozu? Wenn Du Ahnung von der Materie hättest, dann wäre "asynchroner 
Timer 2" im Zusammenhang mit AVR völlig eindeutig.

Du solltest übrigens Deinen Umgangston hier im Forum ganz schnell 
verbessern! Du bist mir in den letzten Tagen häufiger mit extrem 
unverschämten Äußerungen aufgefallen. Man kann sich auch einigermaßen 
normal unterhalten.

von Maxi (Gast)


Lesenswert?

>Wie meas_time== 1 wird? Nun, durch den else-Zwei würde ich sagen. Dafür
>braucht es nicht mal Voodoo...

In dem Fall schon, denn wie kommt er denn in den Else-Zeig?

>Asynchron heißt asynchron.
Aber nicht so, wie Du das Wort verwendest. Es setzt nämlich zwei 
verschiedene Dinge in Beziehung. Wie in "X ist asynchron zu Y". Ob das 
Atmel richtig schreibt ist mir wurscht. Du fragst ja "hier" und nicht 
bei Atmel.

von Maxi (Gast)


Lesenswert?

Na gut. Dann halte ich halt die Klappe.

von Maxi (Gast)


Lesenswert?

>>Wie meas_time== 1 wird? Nun, durch den else-Zwei würde ich sagen. Dafür
>>braucht es nicht mal Voodoo...

>In dem Fall schon, denn wie kommt er denn in den Else-Zeig?

Na, toll. Das war dann auch noch Mist von mir. Grrrr.

Jedenfalls, ist es doch aber so, das er immer zwischen dem if- und dem 
else hin und her pendelt.
Am Anfang ist meas_time == 0, dann geht er einmal in den else-zweig und 
setzt meas_time = 1. Dann wieder in den true-zweig und setzt meas_time = 
0.

Jetzt bin ich aber still.

von Chris R. (mrgreen)


Lesenswert?

Ja richtig! Das ist der gleiche Effekt, den ein Modulo hätte. Das habe 
ich aber gar nicht zur Diskussion gestellt..............

von Johannes M. (johnny-m)


Lesenswert?

Maxi wrote:
> Na gut. Dann halte ich halt die Klappe.
Du sollst nicht die Klappe halten (es ist ja durchaus schön, dass Du 
helfen willst!), sondern Du sollst dieses überhebliche 
"Ich-weiß-alles"-Gehabe sein lassen...

von Bernhard M. (boregard)


Lesenswert?

Eigentlich sollte es nicht das Problem sein (wegen untersch. Gross / 
Kleinschreibung), aber es ist gefährlich zwei gleichlautende Bezeichner 
zu haben:
1
volatile uint8_t meas_time = 0;
2
3
#define MEAS_TIME  5

Ruck zuck verliert man den Überblick, was wofür verwendet wird..

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.