-         

Ergebnis 1 bis 6 von 6

Thema: Problem mit return

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.04.2006
    Ort
    Bayern
    Alter
    27
    Beiträge
    182

    Problem mit return

    Anzeige

    Hallo,
    ich bin dabei meine ersten größeren Programme in C zu schreiben.

    Derzeit möchte ich eine Steuerung für eine Heizung programmieren.

    Zur Tasterentprellung habe ich die Routine aus dem mikrocontroller.net genommen.(habe ich im Code-Tag entfernt).

    Die Definitionen sind in einer Datei ausgelagert(define.c).

    Jetz habe ich das Problem, wenn ich eine Funktion(menue_auswahl)aus main heraus aufrufe, und durch ein return wieder zurück will, das mir der Controller einen Reset macht.

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <lcd.h>
    #include <string.h>
    #include <avr/eeprom.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <define.c>
    #include <avr/pgmspace.h>
    
    // hier stünde normal die Tastenentprellungsroutine (die hat
     //in vorherigen Programmen auch schon super funktioniert
    //und es wurde nichst daran geändert.
    
    
    void menue_auswahl(uint8_t m_auswahl_page);
    //#######################################################################################
    //#####################################################################################
    
    void init_controller(void)
    {
    	DDRA = 0b00000011;			// PORTA als Ausgang 
    	DDRC = 0xFF;				// PORTC 0 Ausgang
    	DDRB = 0x00;				// PORTB = Eingang
    	PORTB = 0xFF;
    
    	TCCR0 = (1<<CS02)|(1<<CS00);			// divide by 1024
      	TIMSK = 1<<TOIE0;				// enable timer interrupt
    				// Pullups aktiviert
    
    	lcd_init(LCD_DISP_ON);	
    	
    	lcd_puts_p(PSTR("Steuerung1.0"));
    	_delay_ms(1000);
    	lcd_clrscr();
    	startup ++;
    	return;	
    }
    
    int main(void)
    {
    if (startup<1)
    {
    init_controller();
    }
    while(1)						//Hauptprogrammschleife/Startseite
    {
    
    if ( get_key_short( 1<<KEY0 ))
    		{
          menue_auswahl(1);
     		}
    	
    	lcd_gotoxy(0, 0);
    	lcd_puts_p(PSTR("Brauchwasser: 42ßC"));
    	lcd_gotoxy(10,2);
    	lcd_puts("MENUE");
    	lcd_gotoxy(0,2);
    	lcd_puts("OK");
    
    
    
    }
    return(0);
    
    }
    //########################################################################################
    //###########################################################################################
    //AuswahlMenü Ebene1
    //#######################################################################################
    void menue_auswahl(uint8_t m_auswahl_page)
    {
    	char zeile1_m_auswahl[12];
    
    lcd_clrscr();	
    while(1)
    {
    	switch (m_auswahl_page) 
    {
        case 1: strcpy_P (zeile1_m_auswahl, PSTR("A.Aktoren         "));
    	break;
    	case 2: strcpy_P (zeile1_m_auswahl, PSTR ("B.Schaltschwellen ")); 
    	break;
    	case 3: strcpy_P (zeile1_m_auswahl, PSTR ("C.Sensoren        "));
    	break; 
      	case 4: strcpy_P (zeile1_m_auswahl, PSTR ("D.Betriebszeiten  ")); 
    	break;
    	case 5: strcpy_P (zeile1_m_auswahl, PSTR ("Einstellungen     "));
    	break;
        default: strcpy_P (zeile1_m_auswahl, PSTR ("Fehler           "));
    	break;
      }
    
    
    
    	lcd_gotoxy(0, 0);
    	lcd_puts(zeile1_m_auswahl);
    	lcd_puts(itoa( startup, temp_string1, 10 ));
    	lcd_gotoxy(0, 1);
    	lcd_gotoxy(10,2);
    	lcd_puts_p(PSTR ("AENDERN"));
    
    
    
    if( get_key_press( 1<<KEY0 ))
          switch (m_auswahl_page) 
    	  {
    	  	lcd_clrscr();
        	//case 1 : menue_aktoren();
    		//break;
       		//case 2 : menue_werte();
    		//break;
    		//case 3: menue_sensoren();
    		//break;
    		default: return ;//dieses return macht Probleme
     		 }		
    
    if( get_key_press( 1<<KEY1 )) 
    	 {
    	 m_auswahl_page++;
          		if (m_auswahl_page>5)
    			{
    			m_auswahl_page = 1;
    			} 		
    		
    	  }
    	if( get_key_press( 1<<KEY2 ))
    	{
    	m_auswahl_page--;
    	 		if (m_auswahl_page<1)
    			{
    	 	m_auswahl_page =5;
    			 }
    			
    	}
    	 
    if( get_key_press( 1<<KEY3 ))
    	{ 
    	lcd_clrscr();
        return; // dieses return mach ebenfalls Probleme
    	  }
      
    }
    return;
    }
    Die beiden return-Anweisungen( im letzen drittel, mit Kommentar versehen) werden durch Tasten aufgerufen(Rücksprung zur Hauptseite).
    Danach beginnt der Controller von neuem.
    Er fürht die init_controller neu aus, obwohl in der Variablen startup bereits eine 1 steht.

    Kann mal jemand bitte über den Code schauen, da ich vorher nich solche Probleme hatte und schon alles mögliche ausprobiert habe.

    mfg Benedikt

    PS Sonst muss ich wieder zurück zu BASCOM!^^

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Könnte es sein das der Speicher (RAM) zu knapp ist. Dann besteht die Gefahr das sich Stack und Daten in Gehege kommen. Bei einem Mega48 könnte das schon mal kanpp werden. Welcher µC wird benutz ?

    Erfahrung habe ich damit auch noch nicht, aber es gibt da tool die den Stack testen. Ganz Einfach ist das nicht, da ja auch locale Daten genutzt werden.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.04.2006
    Ort
    Bayern
    Alter
    27
    Beiträge
    182
    Hallo,

    das Programm läuft auf einem MEGA16.

    Denke nicht das der Ram voll ist, da ich auf dem MEGA16 schon C-Programme in ähnlicher größe betrieben habe.

    Außerdem habe ich alle Texte die auf dem LCD angezeigt werden in den FLASH verbannt.


    mfg Benedikt

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Code:
    void menue_auswahl(uint8_t m_auswahl_page)
    {
       char zeile1_m_auswahl[12];
    ...
       case 1: strcpy_P (zeile1_m_auswahl, PSTR("A.Aktoren         "));
       break;
       case 2: strcpy_P (zeile1_m_auswahl, PSTR ("B.Schaltschwellen "));
       break;
       case 3: strcpy_P (zeile1_m_auswahl, PSTR ("C.Sensoren        "));
       break;
       case 4: strcpy_P (zeile1_m_auswahl, PSTR ("D.Betriebszeiten  "));
       break;
       case 5: strcpy_P (zeile1_m_auswahl, PSTR ("Einstellungen     "));
       break;
       default: strcpy_P (zeile1_m_auswahl, PSTR ("Fehler           "));
       break;
    Wenn du die Rücksprungadresse auf dem Stack überschreibst, kann das return auch nicht mehr funktionieren.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Deine lokalen char-Arrays bekommen mehr Zeichen, als sie aufnehmen können. Daher wird mit strcpy* ein Teil des Stacks überschrieben, nicht unwahrscheinlich die Return-Adresse --> Programm landet im Nirwana.
    Disclaimer: none. Sue me.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.04.2006
    Ort
    Bayern
    Alter
    27
    Beiträge
    182
    Hallo,

    danke das ists!.

    Auf alles habe ich geachtet, aber auf die Zeichenlänge meiner strings nicht.

    Danke!


    mfg

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •