-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Funktion wird nicht richtig beendet

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    10.06.2005
    Ort
    Buchbrunn
    Alter
    28
    Beiträge
    68

    Funktion wird nicht richtig beendet

    Anzeige

    Hallo,

    ich soll für einen guten bekannten eine Geschwindigkeitsanzeige entwickeln die ihm die Geschwindigkeit seiner Modelle auf einer 4stelligen Dot-Matrix Anzeige in Wirklichkeit anzeigt. Ich hatte schoneinmal ein Programm dafür in Bascom angefangen, allerdings geht mir Bascom inzwischen ziemlich auf die Nerven weil der Compiler ein paar ziemliche Bugs bei den neueren Tinys hat, die einen immer ewig nach den Ursachen für die Fehler suchen lassen. Dies hier ist also mein erstes wirkliches Projekt in C deswegen bin ich in dieser Sprache noch nicht so bewandert. Als Display hab ich mir das SLR2016 vom Conrad ausgesucht weil es sich mit relativ wenigen Leitungen ansteuern lässt und weil es schön klein ist, zudem leuchten die Zahlen ordentlich hell.

    Gesteuert wird das ganze mit einem ATtiny44, die Anzeige hat auch schon funktioniert (allerdings mit einem Programm das ich früher in Bascom geschrieben hab).

    Das Problem in meinem Programm ist jetzt aber das das Programm nach beendigung meiner selbstgestrickten Wait Funktion nicht mehr ins Hauptprogramm sondern in die Interrupt Routine vom Timer0 springt (wird für die Waitfunktion verwendet).Hier Poste ich mal den Code damit ihr seht was das Programm die ganze Zeit so treibt



    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/pgmspace.h>
    #include <avr/interrupt.h>
    
    	#ifndef F_CPU
    	#define F_CPU 8000000UL /* Interner Oszillator mit 8Mhz */
    	#endif
    
    /* Variablen definieren */
    
        uint8_t Statusbyte = 0; /* Statusbyte für verschiedene Operationen */
    	volatile uint16_t Waittime = 0; /* Countvariable für Waitfunktion */
    	volatile uint16_t Waitcount = 0; /* Countvariable für Waitfunktion */	
    
    /* Variablen für Geschwindigkeitsmessung */
    
    	volatile uint8_t overflowcount = 0; /* Zähler für Timer Overflows */
    	uint16_t timer1counts = 0; /*Zählerstand von Timer1 */
    	float zeit = 0.0; /* Gemessene Timer1 Zeit */
    	float ov_summ_zeit = 0.0; 
    	float v_float =  0.0; /* Geschwindigkeit mit Kommastelle*/
    	uint16_t V = 0; /* Geschwindigkeit ohne Kommastelle */
    
    /* Variablen für Displayanzeige */
    	
    	char Display[5];
    
    /* Konstanten */
    
    	const float H0_10cm = 31.32;
    	const float N_10cm = 115.2;
    	const float overflowzeit = 2.097152;
    	const uint16_t cps = 31250;
    	const uint8_t disp_char0 = 0x00;
    	const uint8_t disp_char1 = 0x10;
    	const uint8_t disp_char2 = 0x20;
    	const uint8_t disp_char3 = 0x30;
    
    /* Konstanten für Displaychars */ 
    const uint8_t wertetabelle[] PROGMEM = {0x00 , 0x08 , 0x04 , 0x0C , 0x02 , 0x0A , 0x06 , 0x0E , 0x01 , 0x09 , 0x05 , 0x0D , 0x03 , 0x0B , 0x07 , 0x0F };
    
    
    
    /* ++++++++++++++++++++++++++++++++++++INTERRUPTS++++++++++++++++++++++++++++++*/
    
    	ISR(TIM0_OVF_vect)
    	{ Waitcount ++;
    	}
    
    	ISR(TIM1_OVF_vect)
    	{ overflowcount ++;
    	}
    
    
    /* Prototypen */
    	
    	void init_io();
    	void timer_init();
    	void wait(uint16_t zeit, uint8_t faktor);
    	
    
    /* ++++++++++++++++++++++++++++++++++++FUNKTIONEN++++++++++++++++++++++++++++++*/
    /* IOs initialisieren */ 
    void init_io()
    { 
    	DDRA |= 0xff;
    	PORTA |= 0xC0;
    
    	DDRB |= 0x0C;
    	PORTB |= 0x07;
    
    	#define disp_blank PA7
     	#define disp_write PA6
     	#define disp_clear PB2
     
     return;
     }
    
    /* Timer initialisieren und Interrupts einrichten*/
    
    void timer_init() /* Timer1 wird initialisiert aber nicht gestartet */
    	{
    	/* Timer0 */
    	TCCR0A = 0;
    	TCCR0B = 0;
    	TIMSK0 = (1<<TOIE0);
    
    	/* Timer1 */
    	/*TCNT1L = 0;
    	TCNT1H = 0;*/
    	TCNT1 = 0;	
    	TCCR1A = 0;
    	TCCR1B = 0;
    	TIMSK1 = (1<<TOIE1);
    
    	return;
    	}
    
    /*+++++++++++++++++++++++++++++++++++++WARTEFUNKTION+++++++++++++++++++++++++++*/
    	
    	void wait(uint16_t zeit, uint8_t faktor)
    	{
    	const float CPMS = 31.25; /* Counts pro Milisekunde */
    	Waitcount = 0;
        Waittime = (zeit * faktor)*CPMS;
    	TCNT0 = 0;
    	sei();
    	TCCR0B = (1 <<CS00);
    	while (Waitcount < Waittime)
    	{
    	};
    	
    
    	TCCR0B |= (1<< CS00);
    	cli();
    	return; /* <<<<<<<Da Hängt er sich auf */
    	}
    
    
    /*+++++++++++++++++++++++++++++++++++++HAUPTPROGRAMM+++++++++++++++++++++++++++*/
    int main(void)
    {
    	init_io();
    	timer_init();
    	wait(1, 1);
    	V = messung();
    	Anzeige(15,2);
    
    	return 0;
    }

    ich hoffe ihr könnt mir helfen damit mein erstes C Programm nicht gleich ein Desaster wird


    Gruß und Dank im Vorraus


    Wolfgang

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Eine sehr komische "Wartefunktion"
    Das hier hat keinen Sinn
    Code:
     TCCR0B |= (1<< CS00);
    Wenn Du den Timer stoppen willst muß es so heißen
    Code:
     TCCR0B &= ~(1<< CS00);
    und vielleicht noch den Interruptflag in TIFR löschen

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    10.06.2005
    Ort
    Buchbrunn
    Alter
    28
    Beiträge
    68
    Hallo izaseba,

    danke für deine Korrektur, das mit den Zuweisungen hab ich noch nicht so drauf, scheinbar funktionierts jetzt der Simulator vom AVR Studio springt aus der Funktion wieder einwandfrei raus .

    Die Waitfunktion ist eigentlich reine Timerverschwendung, da er aber (bis jetzt!!) noch nicht gebraucht wird hab ich mir damit eine eigene Wait Funktion gestrickt weil ich bei den Funktionen von der AVR Libc noch nicht so ganz durchsteige und irgendwie noch nicht so ganz kapiert hab wie man andere Libs in AVR Studio einbindet.

    P.S.: jetzt hängt der Simulator schon wieder allerdings im Interrupt vom Timer1

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Hallo Wolfgang,
    Es kann ja sein, daß ich mich vergucke, aber was macht das Programm im Interrupt von Timer1, wenn der Timer1 garnicht läuft
    Oder hast Du das Programm von oben irgendwie abgeändert ?
    Klar ist Deine Wartefunktion Timerverschwendung, sie tut aber Ihren Dienst
    Das ist immernoch besser, als eine delay Funktion, wozu brauchst Du überhaupt diese wait Funktion ?
    Vielleicht kann ich Die einen Tip geben, wie das eleganter zu lösen ist...

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    10.06.2005
    Ort
    Buchbrunn
    Alter
    28
    Beiträge
    68
    Hallo Sebastian,

    die Funktion wird nur gebraucht um die gemessenen Werte dann eine gewisse Zeit lang anzuzeigen und Delay Zeiten bei der Display initialisierung zu realisieren. Warum das Programm dann nach Beendigung der Funktion ausgerechnet in den Timer1 Interrupt springt obwohl sogar davor noch alle Interrupts deaktiviert werden versteh ich auch nicht, das werde ich dann halt irgendwie umschiffen müssen, die Frage ist nur wie? Ein sichern vom SREG hat keine änderung erbracht (warum auch) .


    Gute Nacht


    Wolfgang

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.186
    Wo springt das return0 am Ende von main hin?

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.12.2004
    Alter
    32
    Beiträge
    287
    Hallo,

    wieso schreibst du bei einem Normalen "void" Unterprogramm, welches überhaupt keinen Rückgabeparameter hat, am Ende "return"?

    Mfg
    The future is closer then you think!

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    45
    Beiträge
    2.236
    Hallo
    HubertG hat natürlich recht,
    irgendwie fehlt bei Dir die Endlosschleife ( bin ich ein Blindfisch )

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    10.06.2005
    Ort
    Buchbrunn
    Alter
    28
    Beiträge
    68
    Hallo,

    danke für die Tipps gebracht hats bis jetzt leider nichts. Das mit den Return Anweisungen wusste ich nich, das man die bei void funktionen nicht braucht, jetzt weis ichs. Das main keine Endlosschleife ist war auch mein Fehler (liegt warscheinlich an den alten Bascom gewohnheiten) jetzt hab ich mir ne Endlosschleife mit do-while gebastelt, hoffentlich funktioniert das.

    Leider springt das Programm immer noch in die Interruptfunktion vom Timer1 trotz eindeutig abgeschalteter Interrupts, hier nochmal der jetzige Code:

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/pgmspace.h>
    #include <avr/interrupt.h>
    
    	#ifndef F_CPU
    	#define F_CPU 8000000UL /* Interner Oszillator mit 8Mhz */
    	#endif
    
    
    /* Variablen definieren */
    
        uint8_t Statusbyte = 0; /* Statusbyte für verschiedene Operationen */
    	volatile uint16_t Waittime = 0; /* Countvariable für Waitfunktion */
    	volatile uint16_t Waitcount = 0; /* Countvariable für Waitfunktion */	
    
    /* Variablen für Geschwindigkeitsmessung */
    
    	volatile uint8_t overflowcount = 0; /* Zähler für Timer Overflows */
    	uint16_t timer1counts = 0; /*Zählerstand von Timer1 */
    	float zeit = 0.0; /* Gemessene Timer1 Zeit */
    	float ov_summ_zeit = 0.0; 
    	float v_float =  0.0; /* Geschwindigkeit mit Kommastelle*/
    	uint16_t V = 0; /* Geschwindigkeit ohne Kommastelle */
    
    /* Variablen für Displayanzeige */
    	
    	char Display[5];
    
    
    /* Konstanten */
    
    	const float H0_10cm = 31.32;
    	const float N_10cm = 115.2;
    	const float overflowzeit = 2.097152;
    	const uint16_t cps = 31250;
    	const uint8_t disp_char0 = 0x00;
    	const uint8_t disp_char1 = 0x10;
    	const uint8_t disp_char2 = 0x20;
    	const uint8_t disp_char3 = 0x30;
    
    /* Konstanten für Displaychars */ 
    const uint8_t wertetabelle[] PROGMEM = {0x00 , 0x08 , 0x04 , 0x0C , 0x02 , 0x0A , 0x06 , 0x0E , 0x01 , 0x09 , 0x05 , 0x0D , 0x03 , 0x0B , 0x07 , 0x0F };
    
    
    
    /* ++++++++++++++++++++++++++++++++++++INTERRUPTS++++++++++++++++++++++++++++++*/
    
    	ISR(TIM0_OVF_vect)
    	{ Waitcount ++;
    	}
    
    	ISR(TIM1_OVF_vect)
    	{ overflowcount ++;
    	}
    
    
    /* Prototypen */
    	
    	void init_io();
    	void timer_init();
    	void wait(uint16_t zeit, uint8_t faktor);
    	uint16_t messung();
    	void Anzeige(uint8_t zeichen, uint8_t place); 
    
    /* ++++++++++++++++++++++++++++++++++++FUNKTIONEN++++++++++++++++++++++++++++++*/
    /* IOs initialisieren */ 
    void init_io()
    { 
    	DDRA |= 0xff;
    	PORTA |= 0xC0;
    
    	DDRB |= 0x0C;
    	PORTB |= 0x07;
    
    	#define disp_blank PA7
     	#define disp_write PA6
     	#define disp_clear PB2
     
     }
    
    /* Timer initialisieren und Interrupts einrichten*/
    
    void timer_init() /* Timer1 wird initialisiert aber nicht gestartet */
    	{
    	/* Timer0 */
    	TCCR0A = 0;
    	TCCR0B = 0;
    	TIMSK0 |= (1<<TOIE0);
    
    
    	TCNT1 = 0;	
    	TCCR1A = 0;
    	TCCR1B = 0;
    	TIMSK1 |= (1<<TOIE1);
    
    	}
    
    /*+++++++++++++++++++++++++++++++++++++WARTEFUNKTION+++++++++++++++++++++++++++*/
    	
    	void wait(uint16_t zeit, uint8_t faktor)
    	{
    	const float CPMS = 5; /*31.25;  Counts pro Milisekunde */
    	uint8_t temp;
    	temp = SREG;
    	Waitcount = 0;
        Waittime = (zeit * faktor)*CPMS;
    	TCNT0 = 0;
    	sei();
    	TCCR0B |= (1 <<CS00);
    	while (Waitcount < Waittime)
    	{
    	};	
    
    	TCCR0B &=~ (1<< CS00);
    	cli();
    	SREG = temp;
    
    	}
    
    /*+++++++++++++++++++++++++++++++++++++Messfunktion++++++++++++++++++++++++++++*/
    
    	uint16_t messung()
    	{
    	/* MESSUNG */
    	while (PINB0 == 1){}
    	TCNT1 = 0;
    	TCCR1B |= (1<<CS12);
    	sei();
    
    	while (PINB1 == 1) {}
    	TCCR1B &=~ (1<<CS12);
    	cli();
    
    	timer1counts = TCNT1;
    
    /*+++++++++++++++++RECHNUNG++++++++++++*/
    
    	zeit = timer1counts / cps;
    	ov_summ_zeit = overflowzeit * overflowcount;
    	zeit = zeit + ov_summ_zeit;
    	v_float = H0_10cm/zeit;
    	V = v_float;
    
    	/*itoa(V,Display,10);*/   /* Integer Wert in ASCII String umwandeln */
    	return(V);
    	}
    
    /* ANZEIGE */
    
    	void Anzeige(uint8_t zeichen, uint8_t place) 
    	{
    
    	/* ANZEIGE */	
    	}
    
    /*+++++++++++++++++++++++++++++++++++++HAUPTPROGRAMM+++++++++++++++++++++++++++*/
    int main(void)
    {
    	init_io();
    	timer_init();
    	wait(1, 1);
    	do
    	{
    	V = messung();
    	Anzeige(15,2);
    
     }while(1);	
    }
    Hier mal der ganze Code damit ihr seht was bis jetzt so geschrieben steht.


    Danke für eure Hilfe und noch einen schönen Bastel-Samstag


    Wolfgang

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    10.06.2005
    Ort
    Buchbrunn
    Alter
    28
    Beiträge
    68
    Hallo ich bins wieder ,


    hab heute nochmal alle möglichkeiten ausprobiert. Der Simulator hängt sich immer wieder an der selben stelle auf, immer wenn ich versuche entweder nur den Timer0 Overflow Interrupt oder alle Interrupts abzuschalten. Jetzt Frage ich mich warum, allerdings kann ich mir diese Frage mit meinen bis jetzt noch sehr bescheidenen C Kenntnissen nicht beantworten, wäre froh wenn ihr mir helfen könntet.


    Schönen Sonntag noch

    Gruß

    Wolfgang

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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