Forum: Mikrocontroller und Digitale Elektronik Adressübergabe einer Variable an eine Funktion


von GC (Gast)


Lesenswert?

Hallo zusammen,
Kann mir vielleicht jemand helfen?

Stehe ein wenig auf dem Schlauch

ich will einer Funktion die Variable Unterpunkt und Menuepunkt 
übergeben.
Aber es kommt nur blödsinn raus wenn ich das mache.
Ich habe mir mal die unterpunkt-Variable anzeigen lasen und es kommt 10 
raus jedoch sollte die Funktion jetzt noch nichts machen....
1
#define F_CPU 16000000
2
3
#include <avr/io.h>      // Header-Datei f. IO-Register
4
#include <avr/interrupt.h>  // Header-Datei f. Interruptfunktion
5
#include <stdint.h>         // Header-Datei f. standard Datentypen
6
#include <avr/pgmspace.h>
7
#include <util/delay.h>
8
#include <string.h>
9
#include <stdlib.h>
10
#include <math.h>
11
12
#include "SoftwareTerrariumDisplay.h"
13
#include "spi/spi_master_slave.h"
14
#include "Treiber/eadog128-6.h"
15
#include "Menue/menuepunkte.h"
16
........
17
........
18
/********************************************************************************
19
Main Programm
20
********************************************************************************/
21
int main(void)
22
{
23
  int menuepunkt = 0;      // Menuepunkt in dem man sich befindet
24
  int unterpunkt = 0;      // Unterpunkt in dem man sich befindet
25
  char tmp[100];
26
  char time[22];        // Zeitausgabe fürs Display 
27
  
28
  initPort();          // Portinitalisierung
29
  cli();            // Disable all interrupts
30
  spi_init_master();      // Inizialisierung SPI
31
  display_init();        // Inizialisierung Display
32
  InitTimer0();        // Inizialisierung Timer0
33
  sei();            // enable all interrupts
34
  
35
  SET_LED_TASTER_OFF;      // Tasterhintergrundbeleuchung ausschalten
36
  SET_DISPLAY_BRIGHTNESS_OFF; // Displayhintergrundbeleuchung ausschalten
37
  
38
  _delay_ms(500);    // Abwarten bis Einlesung zum erstern mal abgefragt wird
39
  readsystemtime();  // Systemzeit abfragen
40
  readsystem_sonnenauf_untergang(1, 1); // Sonnenauf- Untergang von Basiseinheit abfragen 
41
  readsystemtemp(1, 1); // Temperaturen  von Basiseinheit abfragen
42
  readsystem_manual(1, 1);  // Manuelle Einstellmöglichkeiten einlesen
43
  
44
    while(1)
45
    {
46
    SWITCH_LED1;  
47
        
48
    if ( (read_taster(PIN_TASTER_ENTER) == 1) && (hintergrungbeleuchtungszaehler<=1) )    //
49
    {
50
      display_clear();  // Diplay Löschen
51
      menuepunkt = 0;    // Start an Hauptmenue
52
      unterpunkt = 0;
53
    }
54
    
55
    if(hintergrungbeleuchtungszaehler>0)      // In Menues Unterwegs da ein Taster gedrückt wurde
56
    {
57
      readsystemtime();
58
      sprintf(time, "%02d:%02d:%02d %02d:%02d:%02d\n", systemtime.datum.day, systemtime.datum.month, systemtime.datum.year, systemtime.time.hour, systemtime.time.minute, systemtime.time.second);
59
      
60
      switch(menuepunkt)
61
      {
62
        case 0:  // Hauptmenue
63
            display_write("Einstellung",0,0);
64
            if (read_taster(PIN_TASTER_DOWN) == 1)
65
            {
66
              unterpunkt++;
67
              if (unterpunkt >= 4)
68
                unterpunkt = 1;
69
            }
70
            if (read_taster(PIN_TASTER_UP) == 1)
71
            {
72
              unterpunkt--;
73
              if (unterpunkt == 0)
74
                unterpunkt = 3;
75
            }
76
            display_write(time,0,7);
77
            
78
            switch(unterpunkt)
79
            {
80
              case 0:  display_write(" Terrarium 1",0,2);
81
                  display_write(" Terrarium 2",0,3);
82
                  display_write(" Time",0,4);
83
                  break;
84
              case 1:  display_write(">Terrarium 1",0,2);
85
                  display_write(" Terrarium 2",0,3);
86
                  display_write(" Time",0,4);
87
                  if (read_taster(PIN_TASTER_ENTER) == 1)    // Enter wurde gedrückt
88
                  {
89
                    display_clear();  // Diplay Löschen
90
                    menuepunkt = 1;    // Menue Terrarium 1 Einstellung
91
                    unterpunkt = 0; 
92
                  }
93
                  break;
94
              case 2:  display_write(" Terrarium 1",0,2);
95
                  display_write(">Terrarium 2",0,3);
96
                  display_write(" Time",0,4);
97
                  if (read_taster(PIN_TASTER_ENTER) == 1)    // Enter wurde gedrückt
98
                  {
99
                    display_clear();  // Diplay Löschen
100
                    menuepunkt = 2;    // Menue Terrarium 1 Einstellung
101
                    unterpunkt = 0; 
102
                  }
103
                  break;
104
              case 3:  display_write(" Terrarium 1",0,2);
105
                  display_write(" Terrarium 2",0,3);
106
                  display_write(">Time",0,4);
107
                  if (read_taster(PIN_TASTER_ENTER) == 1)    // Enter wurde gedrückt
108
                  {
109
                    display_clear();  // Diplay Löschen
110
                    menuepunkt = 3;    // Menue Terrarium 1 Einstellung 
111
                    unterpunkt = 0;
112
                  }
113
                  break;
114
              default:
115
                  break;
116
            }
117
            break;
118
            
119
        case 1:  // Terrarium 1 Einstellungsmenue
120
            display_write("Terrarium 1",0,0);
121
            terrarium_menue(&terrariumsteuerung_a, 1, 0, &unterpunkt, &menuepunkt);
122
            break;
123
          
124
        case 2:  // Terrarium 2 Einstellungsmenue
125
            display_write("Terrarium 2",0,0);
126
            break;
127
        default://menuepunkt = 0;
128
            break;
129
      }
130
    }
131
132
    sprintf(tmp, "Unterpunkt: %d\n", unterpunkt);
133
    display_write(tmp,0,5);
134
    sprintf(tmp, "Menuepunkt: %d\n", menuepunkt);
135
    display_write(tmp,0,6);
136
  }  // Ende While-Schleife
137
138
}  // Ende main
1
......
2
/********************************************************************************
3
Function Prototypes
4
********************************************************************************/
5
void initPort(void);          // Inizialisierung der Portpins
6
int read_taster(int tasterpin);      // Einlesen der Taster und zustandsvariable setzen
7
void InitTimer0(void);          // Inizialisierung des Timers für 1ms
8
double parseInt();            // funktion zum Zerlegen des bekommen String der Basiseinheit
9
void readsystemtime(void);        // Einlesen der Systemzeit von der Basisplatine
10
void readsystemtemp(int terrariumA, int terrariumB);  // Temperatureinstellungen und dazugehörige Temperauren an NTCs von Terrarim A der Basisplatine einlesen
11
void readsystem_sonnenauf_untergang(int terrariumA, int terrariumB);  // Sonnenauf-untergang von der Basiseinheit abfragen
12
void readsystem_manual(int terrariumA, int terrariumB);  // Manuelle Einstellmöglichkeiten von Basiseinheit einlesen
1
#include "menuepunkte.h"
2
3
/********************************************************************************
4
Terrarium Untermenue 1 und zwei
5
Übergabewerte Strucktur terrarium A oder B
6
terrariumA = 1(ja) oder 0(nein)
7
terrariumB = 1(ja) oder 0(nein)
8
9
*******************************************************************************/
10
void terrarium_menue(struct TERRARIUMEINSTELLUNG *terrarium, int terrariumA, int terrariumB, int *unterpunkt_ptr, int *menuepunkt_ptr)
11
{
12
}
1
/*
2
 * menuepunkte.h
3
 */ 
4
#ifndef MENUEPUNKTE_H_
5
#define MENUEPUNKTE_H_
6
7
#define F_CPU 16000000
8
9
#include <avr/io.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#include <util/delay.h>
13
#include <avr/interrupt.h>
14
15
#include "../SoftwareTerrariumDisplay.h"
16
17
void terrarium_menue(struct TERRARIUMEINSTELLUNG *terrarium, int terrariumA, int terrariumB, int *unterpunkt_ptr, int *menuepunkt_ptr);

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Aufruf der leeren Funktion "terrarium_menue" änder den Wert der 
Variablen?

Dann ist da irgendwas anderes nicht in Ordnung, die Art und Weise des 
Aufrufs ist korrekt.

Ist denn Dein Stack ausreichend groß? Bereits in main() belegst Du um 
die 130 Bytes davon, und jeder Funktionsaufruf belegt weiteren Platz auf 
dem Stack, der von "terrarium_menue" ca. 12 Bytes (5 Parameter, int bzw. 
Pointer + Rücksprungadresse).

von Klaus (Gast)


Lesenswert?

Hallo,

menuepunkt und unterpunkt sind vom Typ int. In der Funktion 
terrarium_menue hast Du jedoch Zeiger verwendet. Also entweder alles auf 
int oder alles auf Zeiger umbauen !

Viele Grüsse, Klaus

von GC (Gast)


Lesenswert?

hallo
also mein Output zeigt das hier an:
ask "RunOutputFileVerifyTask"
        Program Memory Usage   :  11520 bytes   35,2 % Full
        Data Memory Usage     :  1822 bytes   89,0 % Full

kann das daran liegen?

von Max H. (hartl192)


Lesenswert?

Klaus schrieb:
> menuepunkt und unterpunkt sind vom Typ int. In der Funktion
> terrarium_menue hast Du jedoch Zeiger verwendet. Also entweder alles auf
> int oder alles auf Zeiger umbauen !
Das passt schon so, beim Aufruf wird durch den Address-of Operator ein 
Pointer auf die Variable übergeben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Klaus schrieb:
> menuepunkt und unterpunkt sind vom Typ int. In der Funktion
> terrarium_menue hast Du jedoch Zeiger verwendet.

Das muss er auch, wenn die Funktion die Werte der Variablen verändern 
soll.

Nein, das ist soweit korrekt.

GC schrieb:
> Data Memory Usage     :  1822 bytes   89,0 % Full

Das kann in der Tat ein Problem sein. Dein µC hat also insgesamt 2 kByte 
RAM, und davon belegt Dein Programm --ohne Stack!-- bereits 1822 Byte. 
Bleiben also 202 Byte für Stack und gegebenenfalls Heap übrig.

Bedenke, daß wegen der "genialen" Harvard-Architektur der AVRs jede 
Stringkonstante auch Platz im RAM benötigt.

Stichwort "pgmspace.h" und Konsorten.

von Huhu (Gast)


Lesenswert?

Sollten die nicht "static" sein ?

int menuepunkt = 0;      // Menuepunkt in dem man sich befindet
int unterpunkt = 0;      // Unterpunkt in dem man sich befindet

von Max H. (hartl192)


Lesenswert?

Die Verwendung von sprintf und double sind auch nicht für sparsamen 
Umgang mit Speicher bekannt.

Huhu schrieb:
> Sollten die nicht "static" sein ?
>
> int menuepunkt = 0;      // Menuepunkt in dem man sich befindet
> int unterpunkt = 0;      // Unterpunkt in dem man sich befindet
Was sollte das bringen?

von GC (Gast)


Lesenswert?

aber komisch ist halt das sobald ich da ein "&" vor dem unterpunktsetze 
das programm mir direkt den unterpunkt auf 10 setzt.
....
siehe da das static hat geholfen.... jetzt passiert das nicht mehr!
Kann mir das vielleicht jemand erklären?

von Klaus (Gast)


Lesenswert?

static bedeutet ja nur, das eine Variable auch nach dem Verlassen einer 
Funktion / eines Programmabschnitts ihren Wert behält. Ohne static ist 
der Wert vermutlich undefiniert und zufällig gleich 10.

von Max H. (hartl192)


Lesenswert?

GC schrieb:
> siehe da das static hat geholfen.... jetzt passiert das nicht mehr!
> Kann mir das vielleicht jemand erklären?
Damit hast du wahrscheinlich nur die Symptome und nicht das Problem 
gelöst. Mit static Kommen die Variablen ist Data Segment statt in den 
Stack, das ändert aber nichts daran, dass du irgendwelche Daten auf dem 
Stack überschreibst, falls das die Ursache war.


Klaus schrieb:
> static bedeutet ja nur, das eine Variable auch nach dem Verlassen
> einer
> Funktion / eines Programmabschnitts ihren Wert behält. Ohne static ist
> der Wert vermutlich undefiniert und zufällig gleich 10.
Wenn die main() verlassen wird ist sowieso nicht mehr wichtig was in den 
Variablen stand.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Huhu schrieb:
> Sollten die nicht "static" sein ?

Wozu?

Die Variablen sind innerhalb von main deklariert und behalten somit 
während der gesamten Laufzeit von main ihren Inhalt. main wird 
schließlich nicht mehrfach aufgerufen.

GC schrieb:
> siehe da das static hat geholfen.... jetzt passiert das nicht mehr!

Das ist ein deutliches Indiz dafür, daß Du Probleme mit dem Stack 
hast.

Ohne "static" ist das eine automatische Variable, die beim Aufruf von 
main auf dem Stack angelegt wird. Mit "static" aber ist das eben eine 
statische Variable, die nicht auf dem Stack landet; der von ihr 
verwendete Speicher ist fest reserviert und liegt daher an einem anderen 
Adressbereich als der Stack.

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.