- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 5 von 5

Thema: Probleme mit while(1)

  1. #1

    Probleme mit while(1)

    Anzeige

    E-Bike
    Hi Leute,

    endlich habe ich mal Zeit an meinem Robot zu bauen und zu programmieren.
    Leider habe ich beim Programmieren das Problem, dass immer wieder aus der eigentlich unendlichen while(1)-Schleife rausgesprungen wird. Und ich finde keine Erkärung warum. Dadurch wird die controll_LED_green immer wieder abgeschaltet, was ja eigentlich theoretisch nicht passieren sollte.

    Der Zweite Fehler ist, dass er immer wieder in die if (FWD_OnOff == false)-Abfrage reinspringt, obwohl der Wert auf true gesetzt werden müsste.
    Hier erst mal der bisherige komplette Code:

    Code:
    #define F_CPU 16000000UL	// ohne CKDIV8_Fuse = 16 MHz --> auf 16MHz eingestellt
    #include <avr/io.h>			// Standard Portfunktionen einbinden
    #include <util/delay.h>		//verzögerungs_lib einbinden
    #include <avr/interrupt.h>	// sei() setzt I-Bit, cli() löscht I-Bit, ISR()
    #include "own_Port_define.h"	//eigene Portdefinierung
    
    bool FWD_OnOff;
    
    void init_all (void)
    {		
    	//################    Ports   #########
    	// Output Port B: Motor Enable, Left_Direction, Right_Direction,
    	DDRB |= (1<<motor_enable_DDR) | (1<<left_direction_DDR) | (1<<right_direction_DDR);
    	motor_Off;			// High = Motor off  ==> PORTB |= (1<<motor_enable_PORT);	
    	//Output Port D: Left_PWM, Right_PWM
    	DDRD |= (1<<left_PWM_DDR) | (1<<right_PWM_DDR); 
    	
    	//############### Controll ############
    	DDRB |= (1<controll_LED_Yellow_DDR) | (1<<controll_LED_Green_DDR) | (1<<start_Taster_DDR);		//Ausgang
    	//DDRB &= ~(1<<start_Taster_DDR);											//Eingang
    	PORTB &= ~(1<<controll_LED_Green_PORT);			//Interner Pull Up disable
    	PORTB &= ~(1<<controll_LED_Yellow_PORT);		//Interner Pull Up disable
    	PORTB |= (1<<start_Taster_PORT);				//Interner Pull Up enable
    		
    	//################    Timer   #########
    	//Data sheet age 98 "Normal Mode"
    	TCCR0A &= ~(1<<COM0A1) & ~(1<<COM0A0) & ~(1<<WGM01) & ~(1<<WGM00);	// OCR0A disconnect, normal Port Function
    	TCCR0B &= ~(1<<WGM02);	// WGM0:2 = 0 --> Normal Mode
    	TCCR0B |=	(1<<CS01) | (1<<CS00);	// prescaler 64 --> (16MHz / 64) / 256 = 976,5625 --> ~977 IRQ pro Sekunde
    	TIMSK0 |= (1<<TOIE0);	// Overflow IRQ Enable
    	sei();
    		
    	//################    PWM     #########
    	//COM2x1 = HIGH ==> non-inverting-mode, set OC2x at bottom and clear on compare match; 
    	//WGM01 = HIGH und WGM00 = HIGH ==> Fast PWM, TOP = 0xFF, Update of OCRn at bottom, TOV-Flag set on MAX;
    	TCCR2A |= (1<<COM2A1) | (1<<COM2B1) | (1<<WGM21) | (1<<WGM20);
    	//CS22 = HIGH ==> clk/64 (from prescaler)
    	TCCR2B |= (1<<CS22);	// hier => 976,6Hz
    }
    
    void adjust_all (void)
    {
    	FWD_OnOff = false;
    }
    
    bool Abfrage_PB7 (void)
    {
    	if ( (PINB & (1<<start_Taster_PIN) ) == 0 )		//Prüft, ob auf PD5 ein LOW anliegt. Wenn ja, dann...
    	{
    		//_delay_ms(50);				//...warte kurz (enprellung) und...
    		if ( (PINB & (1<<start_Taster_PIN) ) == 0)	//...prüfe noch einmal. Wenn immer noch,dann...
    		{
    			PORTB |=(1<<controll_LED_Green_PIN);		//...setze PB6 auf HIGH.
    			return false;
    		}
    	}
    	return true;					//Sonst gib ein True zurück.
    }
    
    void Start_Impulse (void)
    {
    	while(Abfrage_PB7());	//Solange kein False zurückgegeben wird, bleibe in der Schleife
    	//_delay_ms(1000);		//Warte, bis mit der weiteren Ausführung gestartet wird
    }
    
    void Engine_off (void)
    {
    	motor_Off;
    	pwm_Value_left = 0;
    	pwm_Value_right = 0;
    }
    
    void FWD_direction (void)
    {
    		
    	left_FWD_direction;
    	right_FWD_direction;
    	pwm_Value_left = 190;
    	pwm_Value_right = 80;
    	FWD_OnOff = true;
    	
    }
    void BWD_direction (void)
    {
    	left_BWD_direction;
    	right_BWD_direction;
    }
    
    void easy_drive (void)
    {
    	if (FWD_OnOff == false)
    	{
    		FWD_direction();
    	}
    	motor_On;
    	
    }
    
    int main(void)
    {
    	init_all();
    	adjust_all();
    	
    	Start_Impulse();
    	
        while(1)
        {
           easy_drive();   
        }
    }
    Eventuell sieht ja jemand den Fehler und könnte diesen mir mitteilen. Danke!
    Geändert von radbruch (16.03.2014 um 17:55 Uhr)

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied Avatar von derNeue
    Registriert seit
    01.01.2011
    Ort
    Bierstadt Radeberg
    Alter
    38
    Beiträge
    101
    Hallo!


    Du gibst einen Überlauf Interrupt vom Timer0 frei. Aber nirgends sehe ich den Code für die ISR. Sowas kann ganz lustige Folgen haben.

    Auch ist deine scheinbare Tastenentprellung irgendwie seltsam.


    Dennis
    Ich studiere die Wirkung der Sonnenstrahlen auf das Liebesleben der Pflastersteine

  3. #3
    Danke, jetzt geht alles wie es soll.

    Mir hat die Zeile: TIFR0 &= ~(1<<TOV0) in der ISR(TIMER0_OVF_vect) gefehlt.

    Das mit der entprellung (Abfrage, Warten und nochmalige Abfrage) habe ich so irgendwo mal im Netz gefunden.
    Der Zusatz ist nur dazu da um in der endlosschleife drinnen zu bleiben, bis halt die Start-Taste gedrückt ist.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied Avatar von derNeue
    Registriert seit
    01.01.2011
    Ort
    Bierstadt Radeberg
    Alter
    38
    Beiträge
    101
    Zitat Zitat von NewBot Beitrag anzeigen
    Mir hat die Zeile: TIFR0 &= ~(1<<TOV0) in der ISR(TIMER0_OVF_vect) gefehlt.
    Das glaube ich nicht. Mit diesem Befehl löscht du das Interrupt Flag. Das wird aber automatisch gelöscht, sobald du in die ISR reinspringst. Nach wie vor fehlt in deinem "kompletten" Code die ISR ganz.

    Das mit der entprellung (Abfrage, Warten und nochmalige Abfrage) habe ich so irgendwo mal im Netz gefunden.
    Der Zusatz ist nur dazu da um in der endlosschleife drinnen zu bleiben, bis halt die Start-Taste gedrückt ist.
    Das ist aber eine schlechte Art einer Entprellung. Für dein jetziges Vorhaben vielleicht ausreichend, aber trotzdem ein ganz schlechter Stil. Für gewöhnlich macht man sowas mit einem Timer-Interrupt.
    http://www.mikrocontroller.net/artic...areentprellung


    Dennis
    Ich studiere die Wirkung der Sonnenstrahlen auf das Liebesleben der Pflastersteine

  5. #5
    Stange, dass es trotzdem funktioniert. Heißt also noch mal das Datenblatt und das Web wälzen.
    Na gut.

    Mit dem Entprellen hast du recht. per Timer ist besser. Wird beim nächsten Projekt beachtet.
    Hier brauche ich nur einen Taster und einmal drücken zum start (damit mir der Robot nicht ungewolt vom Tisch springt).

Ähnliche Themen

  1. probleme mit led-cube-programm, und mit uint8_t
    Von Franky55555 im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 06.01.2011, 18:09
  2. Uhr mit 32768Khz mit der Zeit ungenau - Code Probleme?
    Von MelMan im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 01.03.2010, 11:28
  3. SMD RGB LED´s mit PWM; ATmega168 / Probleme mit dem EEprom
    Von Klingon77 im Forum Software, Algorithmen und KI
    Antworten: 78
    Letzter Beitrag: 26.05.2009, 19:54
  4. STK200 mit ATMega85535? Probleme mit RS232 und Bascom?
    Von Hans55 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 23.12.2007, 10:10
  5. Probleme mit Grafikdisplay mit KS0108-Controller und Mega32
    Von Alex20q90 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 21.05.2005, 17:03

Berechtigungen

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

12V Akku bauen