Forum: Mikrocontroller und Digitale Elektronik c-Files mit Timer "auslagern"


von Christian M. (krusti)


Lesenswert?

Hallo,

ich bin mal wieder an meinem Projekt von hier dran: 
Beitrag "ATmega8 ADC-Durchschnittsberechnung"

Weil ich aber ein neues grundsätzliches Problem habe, will ich es in 
einem neuen Beitrag nachfragen.

Ich will in meinem 500-Zeilen-Code die einzelnen Funktionen "auslagern". 
Das klappt nur leider nicht mit allen Funktionen.
Ich habe die Beobachtung gemacht, dass ich Funktionen welche auf einen 
Timer zugreifen nicht separieren kann. Steht mein resetService mit in 
meiner main.c dann läuft es einwandfrei.

Ähnliches Problem wir in diesem Beitrag hier: 
Beitrag "Funktionen in mehrere c files auslagern funktioniert nicht"

Meinen Hauptcode hab ich jetzt erst mal nicht mit angehängt, weil wie 
gesagt 500 Zeilen. Bei Bedarf poste ich den gerne.

Timer läuft über einen ISR.

Ausgelagerter Code:
resetService.c
1
#include "resetService.h"
2
3
void resetService()
4
{
5
  arbeitstag = 0;
6
  eeprom_update_byte(&eeTage, arbeitstag);
7
  
8
  digit[2] = r;
9
  digit[1] = E;
10
  digit[0] = S;
11
  
12
///////////////////////////////////////////////////////
13
//Auf meiner 7-Seg wird nur rES angezeigt, weiter passiert nicht mehr
14
15
  timer2_wert = 0;
16
  
17
  //Timerschleife zur Anzeige der Ausgabe auf dem Display
18
  //Wartezeit 2 sec
19
  while (1) {
20
    if (timer2_wert >= 200) {
21
      break;
22
    }
23
  }
24
  digit[2] = ZERO;
25
  digit[1] = ZERO;
26
  digit[0] = ZERO;
27
}
resetService.h
1
#ifndef RESETSERVICE_H_
2
#define RESETSERVICE_H_
3
4
#include <stdint.h>
5
#include <avr/eeprom.h>
6
#include "SegementZeichen.h"
7
8
extern uint16_t arbeitstag;
9
extern uint8_t digit [3];
10
extern uint8_t eeTage;
11
extern uint16_t timer2_wert;
12
13
#endif /* RESETSERVICE_H_ */

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian M. schrieb:
> Ich habe die Beobachtung gemacht, dass ich Funktionen welche auf einen
> Timer zugreifen nicht separieren kann.

Fehlermeldung?

von linker linker (Gast)


Lesenswert?

Was für eine Fehlermeldung bekommst Du denn ?
Welchen Compiler/IDE nimmst Du ?
Makefile bzw. Projekt auch angepaßt das Deine externen Dateien auch 
eingebunden sind ?

von Christian M. (krusti)


Lesenswert?

Keine.

von Ähm... (Gast)


Lesenswert?

Was mir auf anhieb auffällt:
- volatile bei Interruptvariablen!
- warum benutzt du einen Timer wenn du dein Programm an der while(1) eh 
zwangs-lahmlegst?

Grüße

von Stefan K. (stefan64)


Lesenswert?

extern uint16_t timer2_wert;

ist nicht volatile definiert.
Selbst wenn timer2_wert irgendwo anders geändert wird: Deine while(1) 
Schleife bekommt davon nichts mit.

Gruß, Stefan

von linker linker (Gast)


Lesenswert?

Ähm... schrieb:
> Was mir auf anhieb auffällt:
> - volatile bei Interruptvariablen!

Ist ja extern deklariert kann also volatile sein.

> - warum benutzt du einen Timer wenn du dein Programm an der while(1) eh
> zwangs-lahmlegst?
>

O_o das kann natürlich voll ins Auge gehen.
Sollte man mit zwei Variablen lösen, eine für gerade aktualisiert also 
erstmal nicht ändern und den Timestamp ab wann wieder geändert werden 
darf.
Gibt auch andere Lösungen ...
Nur ohne Fehlermeldung bzw. was nun sein eigentliches Problem ist kann 
nicht geholfen werden.

von Christian M. (krusti)


Lesenswert?

AVR-Studio 6 und keine Fehlermeldung. Die Dateien habe ich mit dem 
Solution Explorer erzeugt, entfernt, eingefügt, wieder entfernt,...

Ähm... schrieb:
> Was mir auf anhieb auffällt:
> - volatile bei Interruptvariablen!
> - warum benutzt du einen Timer wenn du dein Programm an der while(1) eh
> zwangs-lahmlegst?
>
> Grüße
Zur while(1). Ich will ja dass die 2sec auf jeden Fall durchgeführt 
werden und ich habe zu dem Zeitpunkt der programmierung keine andere 
Möglichkeit gefunden/gesehen zu warten bis mein Zähler auf 200 ist und 
ihn dann abzufragen. In der Zeit soll auch ruhig nichts anderes 
passieren. Quasi wie die _delay Funktion. Nicht gerade schön aber in 
meinem Fall funktional gewesen bis ich ein extra C machen wollte.

timer2_wert ist in der main voltaile

von Peter II (Gast)


Lesenswert?

Christian M. schrieb:
> timer2_wert ist in der main voltaile

das klingt komisch, wieso ist er dort anders definiert? Hast du 
eventuell jetzt 2 Variablen mit dem gleichen Namen?

von Christian M. (krusti)


Lesenswert?

Peter II schrieb:
> Christian M. schrieb:
>> timer2_wert ist in der main voltaile
>
> das klingt komisch, wieso ist er dort anders definiert? Hast du
> eventuell jetzt 2 Variablen mit dem gleichen Namen?

Vllt habe ich es auch falsch gemacht?
Kurz zum Verständnis: Muss ich die variablen beide exakt so nennen? Also 
volatile uint16_t timer2_wert? Und bei bedarf mit ergänze ich mit 
extern, z.B. bei einer neuen C-Datei? Oder darf/muss ich nur einmal 
voltaile schreiben?

von Peter II (Gast)


Lesenswert?

Christian M. schrieb:
> Vllt habe ich es auch falsch gemacht?
> Kurz zum Verständnis: Muss ich die variablen beide exakt so nennen?

eigentlich muss du sie gar nicht neu benennen. Du machst ja ein include 
mit der Headerdatei. Damit ist sie ja bekannt.

von Mein grosses V. (vorbild)


Lesenswert?

linker linker schrieb:
> Ist ja extern deklariert kann also volatile sein.

Nein, kann es nicht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian M. schrieb:
> Oder darf/muss ich nur einmal voltaile schreiben?

Du musst jedesmal volatile schreiben. Woher soll sonst der Compiler 
beim Übersetzen der einzelnen Module wissen, daß die Variable volatile 
ist?

von Stefan K. (stefan64)


Lesenswert?

Wenn der Compiler ResetService.c übersetzt, dann sieht er das volatile 
nicht. Und deswegen wird er an dieser Stelle:
1
  while (1) {
2
    if (timer2_wert >= 200) {
3
      break;
4
    }
5
  }
optimieren und timer2_wert EINMAL in ein Register einlesen und danach 
dieses Register forever auf >= 200 vergleichen. Kann sogar sein, daß der 
Vergleich nur einmal ausgeführt wird und der effektive Code dann so 
aussieht:
1
  if (timer2_wert >= 200)
2
  else
3
  {
4
    while (1);
5
  }

Gruß, Stefan

von Christian M. (krusti)


Lesenswert?

Das war es. Volatile bei digit und timer2_wert dazu und schon läuft das 
ganze, wie urspünglich. Im Nachhinein eigentlich logisch das volatile 
benötigt wird, da ich ja sonst quasi nur einmal den Wert übergebe und 
zwar der der Initialisierung. So gesehen ist klar, dass ich nicht aus 
meiner Schleife raus komme.
Danke für die Hilfe. Hoffe so werden die anderen Funktionen auch 
funktionieren.

von Stefan K. (stefan64)


Lesenswert?

Wenn Du dort, wo timer2_wert definiert wird, die .h Datei einbindest, in 
der timer2_wert als extern deklariert wird (also "resetService.h"), dann 
kann Dir der Fehler nicht mehr passieren, weil dann der Compiler einen 
Fehler wirft, sobald sich beide unterscheiden.

Gruß, Stefan

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.