Forum: Compiler & IDEs probleme mit funktionsaufruf


von holgie (Gast)


Lesenswert?

Hallo zusammen,
ich möchte in Zukunft meine S0 Schnittstelle des Stromzählers auslesen 
und die Zeit zwischen zwei Impulsen erfassen. Als ersten Teilschritt 
wollte ich dazu eine einfache Uhr programmieren. Nun bin ich dabei auf 
ein Problem gestoßén welches ich nicht verstehe. Ich habe es mitterweile 
soweit eingegrenzt: In dem Stoppuhrmodul wird die Funktion anzeige() 
aufgerufen. Das funktioniert auch, die Uhr zeigt mir im LCD Display die 
Sekunden und Minuten im 1/10 sec takt an. Wenn ich jedoch die Funktion 
jede sekunde aufrufen will (siehe unten in dem Stoppuhrmodul den zweiten 
Funktionsaufruf, der auskommentiert ist)funktioniert das ganze nicht 
mehr. Ich sehe auf dem LCD nur noch die Info:" Booting..."
Ich meine eigentlich dass es vor einigen Tagen funktioniert hat. Wie 
kann das sein?
Danke
gruß
HOlgie
1
#include <avr/io.h>        //Header-Datei für I/O Konfiguration 
2
#include <avr/interrupt.h>
3
#include <stdint.h>          //Header-Datei zur Definition der Zahlentypen 
4
#include <stdbool.h>        //Header-Datei zur Definition der 1-Bit-Variablen bool
5
#include <util/delay.h>        //Header_Datei für delay
6
#include "lcd.h"
7
#include <string.h>
8
#include <stdlib.h>
9
10
//------------------------------------------------------------------------------
11
//************** Konstantendeklaration *******************
12
//-----------------------------------------------------------------------------
13
14
#define VORTEILER_WERT    18
15
#define HUNDERSTEL_WERT   10
16
#define ANZEIGETAKT_WERT      5
17
18
void anzeige();
19
//-----------------------------------------------------------------------------
20
//**************** Variablendeklaration ******************
21
//-----------------------------------------------------------------------------
22
23
24
bool bTakt100ms       = false;        // Takt für Stoppuhrmodul
25
26
unsigned char zehntel_sek     = 0;        // Variable für Zehntelsekundenzählung
27
unsigned char sek      = 0;        // Variable für Sekundenzählung
28
unsigned char min      = 0;        // Variable für Minutenzählung
29
unsigned char zw_zehntel_sek  = 0;        // Variable für Zwischenzeit der Zehntelsekunden
30
unsigned int zw_sek    = 0;        // Variable für Zwischenzeit der Sekunden
31
unsigned char zw_min    = 0;        // Variable für Zwischenzeit der Minuten
32
unsigned char vorteiler     = VORTEILER_WERT;       // Für 10ms Takt
33
34
unsigned char hundertstel     = HUNDERSTEL_WERT;    // Für 100ms Takt
35
unsigned int i,z;          // Zählvariable für Warteschleife (Displayausgabe)
36
37
  char t[100];
38
39
40
//--------------------------------------------------------------------------------
41
//******************* Unterprogramme ********************
42
//--------------------------------------------------------------------------------
43
44
void timer0 (void)            // TIMERINITIALISIERUNG
45
{
46
47
  TCCR0 |=  (1<<CS01);    // Prescaler = 8
48
  TIMSK |= (1<<TOIE0);        // Overflow_vector zulassen Interrupt 
49
}
50
void anzeige (void)        // ANZEIGEMODUL
51
{
52
53
ltoa(sek, t, 10);
54
    strcat(t, " ");            
55
  
56
lcd_send(BEFEHL, LCD_CLEAR);
57
  lcd_write(t);
58
  ltoa(min, t, 10);
59
  lcd_write(t);
60
61
_delay_ms(100);
62
63
}
64
65
void stoppuhr(void)          // STOPPUHRMODUL
66
{
67
PORTB |= (1<<PB0);
68
  zehntel_sek++;          // Zehntelsekunden um 1 erhöhen
69
  anzeige();// Hier funktioniert es!!!
70
  if(zehntel_sek > 9)          // Wenn Zehntelsekunden voll
71
  {
72
    
73
  zehntel_sek = 0;            sek++;  
74
  //  anzeige(); // Hier funktioniert es nicht!!!
75
        // Sekunden um 1 erhöhen
76
77
    if(sek > 59)        // Wenn Sekunden voll
78
    {
79
      sek = 0;        // Sekunden zurücksetzten und
80
      min++;        // Minuten um 1 erhöhen
81
82
      if(min > 59)      // Wenn Minuten voll
83
      {
84
        min = 0;      // Minuten zurücksetzten
85
      }
86
    }
87
  }
88
}
89
90
91
92
93
void zeit (void)      // ZWISCHENZEITMODUL
94
{
95
  zw_zehntel_sek = zehntel_sek;  // Aktuellen Wert in  Variable für Zwischenzeit abspeichern
96
  zw_sek = sek;      // Aktuellen Wert in  Variable für Zwischenzeit abspeichern
97
  zw_min = min;    // Aktuellen Wert in  Variable für Zwischenzeit abspeichern
98
    zehntel_sek = 0;    // Variablenwerte zehntel_sek, sek, min, zw_zehntel_sek, zw_sek, zw_min auf NULL setzen
99
  sek = 0;
100
  min = 0;
101
102
103
}
104
105
106
107
108
109
110
111
//-----------------------------------------------------------------------------
112
//****************** main-Schleife *********************
113
//----------------------------------------------------------------------------
114
115
int main (void)        // MAIN_SCHLEIFE
116
{
117
118
  PORTC |= (1<<PC0); //Pull up einschalten 
119
DDRC &= ~ (1<<PC0); // PDX als Eingang 
120
DDRB = (1<<PB0) | (1<<PB1)| (1<<PB2); // PBX als Ausgang 
121
122
  sei();        // Interrupts freischalten
123
  timer0();        // Aufruf Timer0 Initialisierung  
124
125
    /* LCD einschalten ... */
126
  lcd_init();
127
  lcd_write("Booting...");
128
  _delay_ms(100);
129
  
130
131
while(1)  
132
  {
133
134
135
  if(bTakt100ms == true )  // Wenn 100ms Takt vorhanden
136
  {
137
      bTakt100ms = false;  // 100ms Takt zurücksetzen
138
      stoppuhr();    // Aufruf des Stoppuhrmoduls (alle 100ms)
139
140
    }
141
142
143
144
  }
145
}
146
147
//------------------------------------------------------------------------------
148
// **************** Interrupt-Routine *********************
149
//------------------------------------------------------------------------------
150
151
ISR(TIMER0_OVF_vect)          //Taktgenerierung über Timer0 Overflow_Vector
152
{
153
  vorteiler--;          //  Vorteilerwert dekrementieren
154
  
155
  if(vorteiler == 0)
156
    {
157
      vorteiler = VORTEILER_WERT;  // Variable vorteiler auf den Wert der Konstanten 
158
    
159
      hundertstel--;      // Stoppuhrmodul-Takt runterzählen
160
    
161
162
    
163
      
164
      if(hundertstel == 0)
165
        {
166
          hundertstel = HUNDERSTEL_WERT;
167
          bTakt100ms = 1;        // Stoppuhrmodul-Takt setzen
168
        }  
169
    }
170
}

von Karl H. (kbuchegg)


Lesenswert?

Standardfehler
1
voilatile bool bTakt100ms       = false;

von Karl H. (kbuchegg)


Lesenswert?

leg das Hochzählen der
Zehntel, Sekunden und Minuten ebenfalls in die ISR. Da darf kein 
einziger Zählschritt verloren gehen, oder deine Zeit wird nicht stimmen.

Du hast da aber ein paar Ausgaben und auch einen _delay_ms. Daher kannst 
du nicht garantieren, dass dein Programm tatsächlich spätestens alle 100 
ms wieder in der Hauptschleife an der Abfrage vorbei kommt.

Zählst du die Zeit komplett in der ISR hoch, dann kann dir da nichts 
passieren. Und es ist wichtiger, dass die Zeit hochgezählt wird, als 
dass die Ausgabe auf LCD regelmässig erfolgt.

von holgie (Gast)


Lesenswert?

Hallo,
jetzt funktioniert es. Vielen Dank!!

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.