-         

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

Thema: Peinliches if else Problem bei Portabfrage

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    31
    Beiträge
    795

    Peinliches if else Problem bei Portabfrage

    Anzeige

    Hallo Leute,

    ich schäme mich, dieses Problem zu schildern... aber es geht nicht anders.
    Ich programmiere schon seit längerem mit AVRGCC (WINAVR),
    habe auch schon mehrere Projekte gemacht mit CAN, GrafikDisplays usw...

    Ich kann von mir sagen, dass ich es einigermaßen drauf hab.


    Nun wollte ich heute mal meinen Bruder ein bisschen anlernen.
    Angebangen haben wir mit Ausgänge setzen.
    Haben ne simple funktion geschrieben, die ne LED setzt oder löscht.
    Dann wollten wir als nächsten schritt nen Schalter anschließen.

    Wir benutzen einen ATMega32, DIL40 am Steckbrett. Wir benutzen nur
    Drahtbrücken, da die kabel ja nicht 100Pro leiten...

    An PB0 schließen wir also unseren Schalter gegen Masse.
    Wir initialisieren:
    Code:
    DDRB &= ~(1<<PB0);    // PB0 als Eingang
    PORTB |=  (1<<PB0);   // Pullup an PB0 aktivieren
    Dann zum Problem:
    Ich schreibe folgendes in die Hauptschleife:


    Code:
    if( PINB & (1<<PB0) ){
        LED1(1);
    }else{
        LED1(0);
    }

    Ist die Bedingung erfüllt, ist alles OK.
    Wird die Bedingung nicht erfüllt, also Schalter gedrückt,
    dann hängt sich der Controller auf. Bleibt einfach stehen!

    Wenn ich es aber so schreibe, funktioniert es:
    Code:
    if( PINB & (1<<PB0) ){
        LED1(1);
    }
    if( !(PINB & (1<<PB0)) ){
        LED1(0);
    }

    Ich verstehe es nicht. Das ist ein typischer Vorführeffekt...
    Ich steig einfach nicht dahinter, warum er das else nicht mag.

    Ich habe schon bei vielen programmen die obige Schreibweise benutzt...
    Es gab nie ein Problem...

    Und jetzt das... ich verstehe es einfach nicht....

    Ich hoffe jemand von euch kann mir bei diesem lachhaften Problem helfen.

    Besten Dank!
    Gruß,
    Franz

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Very strange.
    Da ein Controller aber in diesem Sinne nicht "stehenbleiben" kann, treibt er sich offenbar woanders herum.
    kannst du nicht den kompletten Code reinstellen (möglichst uneditiert)
    so lange wird er ja wohl nicht sein.

    Wenn wir es dann wissen, ist es sicher ein Schwachsinn zum aufs-hirn-klatschen. Da freu ich mich schon drauf.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    31
    Beiträge
    795
    Hallo PicNick,

    ich bin gespannt...

    Es sind drei Dateien... Ein Winziges Programm:

    die main.c:
    Code:
    /************************************************************************************/
    /*	Projektname		-=>	ATMega32 Versuche      										*/
    /*	Programmversion	-=>	V0.1														*/
    /*	Mikrocontroller	-=>	ATMega32													*/
    /* 	Letzte Änderung	-=>	12.04.2008 													*/
    /************************************************************************************/
    
    
    
    //  -=> Defines & Includes <=-
    	
    	//  -=> Defines <=-
    		#define F_CPU 1000000
    		
    		
    	//  -=> AVR Includes <=-
    		#include <avr/io.h>
    		#include <util/delay.h>
    		
    	//  -=> Programmheaders <=-
    		
    		
    	//  -=> Programmfiles <=-
    		#include <led.c>
    		#include <dip.c>
    	
    	
    //  -=> Intrrupts <=-
    	
    	
    //  -=> Hauptfunktion <=-
    	
    	int main (void){
    		
    		//  -=> Initialisieren <=-
    			LED_INIT();
    			DIP_INIT();
    			
    		//  -=> Hauptschleife <=-
    		while(1){
    			
    			if( DIP1() ){ 
    				//Erster Wartezyklus
    				LED1(1);
    				LED2(0);
    				_delay_ms(500);
    				
    				//Zweiter Wartezyklus
    				LED1(0);
    				LED2(1);
    				_delay_ms(500);
    				
    			}else{
    				//Erster Wartezyklus
    				LED1(1);
    				LED2(0);
    				_delay_ms(50);
    				
    				//Zweiter Wartezyklus
    				LED1(0);
    				LED2(1);
    				_delay_ms(50);
    			}
    			
    		}
    		return 0;
    	}
    	
    	
    /************************************************************************************/
    Die led.c:
    Code:
    //LED-TREIBER
    
    
    //LED INIT
    void LED_INIT(void) {
    	DDRA = (1<<PA5) | (1<<PA0);
    }
    
    //LED1 - ON/OFF
    void LED1( unsigned int set ) {
    	
    	if(set) {
    		PORTA |=   (1<<PA0);
    	}else{
    		PORTA &= ~ (1<<PA0);
    	}	
    }
    
    //LED2 - ON/OFF
    void LED2( unsigned int set ) {
    	
    	if(set) {
    		PORTA |=   (1<<PA5);
    	}else{
    		PORTA &= ~ (1<<PA5);
    	}	
    }
    Die dip.c:
    Code:
    //DIP
    
    //INIT
    void DIP_INIT(void) {
    	DDRB  &= ~(1<<PB0);		//PINB0 als Eingang
    	PORTB |=  (1<<PB0);		//PINB0 10K PullUp aktivieren
    }
    
    uint8_t DIP1( void ) {
    	if( PINB & (1<<PB0) ){		//Wenn PINB0 = 1 (5V)
    		return 0;				//Verlasse Funktion mit 0 (AUS)
    	}else{						//Ansonsten 
    		return 1;				//Verlasse Funktion mit 1 (EIN)
    	}
    	
    }
    Gruß,
    Franz

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.01.2007
    Beiträge
    134
    Eins hab ich schonmal:

    _delay_ms(500) wird nicht funktionieren:

    "The maximal possible delay is 262.14 ms / F_CPU in MHz"

    Grüsse, Stefan

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    31
    Beiträge
    795
    Hallo Stefan,

    also bei mir hat das immer funktioniert...
    Das kann aber nicht der Grund sein, warum das Spinnt...
    Denn egal was ich in die if/else schleife schreibe, hängt er scheinbar.

    Ich versteh es einfach nicht... Ich habe in vielen Projekten diegleiche
    schreibweise... und da funktioniert es...

    Hab es auch schon auf anderen Pins und Ports probiert... auch schon nen frischen controller genommen... Hilft alles nix..

    UND DAS BEI SO EINEM WINDIGEN PROGRAMM...

    Ich hoffe bloß ich hab meinen Bruder durch diesen Vorführeffekt keine Angst eingejagt ^^
    Gruß,
    Franz

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.01.2005
    Ort
    Tokyo
    Alter
    59
    Beiträge
    242
    Hi,
    der delay funktioniert schon (auch wenn es hier im Board immer anders behauptet wird), weil:
    Function Documentation

    void _delay_ms ( double __ms )
    Perform a delay of __ms milliseconds, using _delay_loop_2().
    The macro F_CPU is supposed to be defined to a constant defining the CPU clock frequency (in Hertz).
    The maximal possible delay is 262.14 ms / F_CPU in MHz.
    When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.

    Aber warum das Programm nicht geht, kann ich add hoc auch nicht erklären. Es könnte sein, da dies mit den Prellen des Schalters zu tun hat. Es wäre vielleicht mal interessant zu sehen, wie die main.lst dazu aussieht.
    Gruß
    pctoaster

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    neulich hatte ich etwas ähnliches, da hatte ich mit avr-gcc und einem standard-makefile kompiliert, und irgendetwas haarsträubend einfaches ging nicht. bzw mit folgendem makefile dann doch.. kA wieso:
    Code:
    ## General Flags
    PROJECT = main
    MCU = atmega8
    TARGET = main
    CC = avr-gcc
    
    ## Options common to compile, link and assembly rules
    COMMON = -mmcu=$(MCU)
    
    ## Compile options common for all C compilation units.
    CFLAGS = $(COMMON)
    CFLAGS += -Wall -gdwarf-2 -O0
    CFLAGS += -Wp,-M,-MP,-MT,$(*F).o,-MF,dep/$(@F).d 
    
    ## Assembly specific flags
    ASMFLAGS = $(COMMON)
    ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
    
    ## Linker flags
    LDFLAGS = $(COMMON)
    LDFLAGS += 
    
    
    ## Intel Hex file production flags
    HEX_FLASH_FLAGS = -R .eeprom
    
    HEX_EEPROM_FLAGS = -j .eeprom
    HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
    HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0
    
    
    ## Objects that must be built in order to link
    OBJECTS = $(TARGET).o 
    
    ## Build
    all: $(TARGET) $(TARGET).hex $(TARGET).eep
    
    ## Compile
    $(TARGET).o: $(TARGET).c
    	$(CC) $(INCLUDES) $(CFLAGS) -c  $<
    
    ##Link
    $(TARGET): $(OBJECTS)
    	 $(CC) $(LDFLAGS) $(OBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
    
    %.hex: $(TARGET)
    	avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@
    
    %.eep: $(TARGET)
    	avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@
    
    %.lss: $(TARGET)
    	avr-objdump -h -S $< > $@
    
    ## Clean target
    .PHONY: clean
    clean:
    	-rm -rf $(OBJECTS) $(TARGET).elf $(TARGET).hex $(TARGET).eep
    
    ## Other dependencies
    -include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
    vielleicht mal testen wenn sonst niemand rat weiss.

    gruesse

    EDIT: lag also an irgendwelchen compiler-flags, nur welche habe ich auf die schnelle nicht rausgefunden.

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.01.2005
    Ort
    Bayern
    Alter
    31
    Beiträge
    795
    Der frisst das else{} nicht..
    sobald ein Befehl zwischen den klammern bei else steht,
    hängt er sich auf... (bzw. macht was anderes...

    Egal ob ich jetzt die dely mit dabei hab, oder im ganzen programm kein delay verwende...

    Ich verstehe es nicht!
    Gruß,
    Franz

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    21.10.2006
    Beiträge
    22
    Ich habe dein Programm mal mit dem AVRStudio kompiliert und auf dem Atmega8 ausgeführt. Die Lampe blinkt schnell und wenn der Taster gedrückt wird langsam. Also ist dein Code definitiv nicht falsch.

    Ich habe die Lampe an PC0 und den Taster auf PD4 geändert. Vielleicht ist bei deinem Atmega32 der Port irgendwie anders gefused? Vielleicht mal andere Ports probieren?

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Is ja wirklich verzwickt. @Michael-Hage hat ja schon gesagt, dass es bei ihm funzt. Ist ja wirklich so nix zu sehen
    Also,
    Mach bitte eine Version die HÄNGENBLEIBT, lass dir aber auch die .LSS files machen und stell die hier rein rein. (wäre ultimativ)

    Zwischenversuch, um einzukreisen, WO die Schweinebacke herumkurvt:
    dip.c
    Code:
    uint8_t DIP1( void ) 
    { 
       if( PINB & (1<<PB0) )
                         return 0;
        return 1;                           // also KEIN else
    }
    Alternative, aber sicherheitshalber getrennt probieren

    main.c
    Code:
    while (1)
    {
            if( DIP1() )
             { 
                LED1(1); 
                LED2(0); 
                _delay_ms(500); 
                LED1(0); 
                LED2(1); 
                _delay_ms(500); 
                continue;                   // auch kein else
             }
             LED1(1); 
             LED2(0); 
             _delay_ms(50); 
             LED1(0); 
             LED2(1); 
             _delay_ms(50); 
          }

    Spekulation: Einer der wenigen Möglichkeiten, im Nirwana zu verschwinden, ist die Dauerschleife am Ende des Programmes (vom C eingefügt).
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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