-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: LED an und aus schalten

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.02.2010
    Ort
    Düsseldorf
    Beiträge
    24

    LED an und aus schalten

    Anzeige

    Hallo Zusammen,

    es geht um folgenden Code auf einem Olimex AVR-P28 mit einem ATMega8:

    /****************************
    Ein-/Ausgänge
    Zeitverzögerung
    Variablenlängen
    *****************************/
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdint.h>


    /****************************
    Anlegen der Funktionen
    *****************************/
    void initialize();
    void LEDschalten(int status);


    /****************************
    Globale Variable für Zähler der An-Aus-Schleife
    *****************************/
    uint8_t zaehler=0; //bis max 255 ansonsten uint16_t


    int main(void)
    {

    initialize();

    while(1)
    {
    if (PIND & (1<<2))
    {
    LEDschalten(1); //LED ein
    zaehler=0;
    }


    if (zaehler >= 1999)
    {
    LEDschalten(0); //LED aus nach 2sec
    zaehler=0;
    }
    else
    {
    zaehler++;
    _delay_ms(1);
    }
    }


    return 0;
    }


    void initialize()
    {
    DDRB = 0x00; //B als Eingang
    DDRC = (1<<5); //C5 als Ausgang
    DDRD = 0x00; //D als Eingang

    PORTB = 0x00; //B 00000000
    PORTC = (1<<5); //C 00100000
    PORTD = 0x00; //D 00000000

    LEDschalten(1); //LED ein
    _delay_ms(500); //0.5sec Leuchten
    LEDschalten(0); //LED aus

    }


    void LEDschalten(int status)
    {
    switch (status)
    {
    case 1: //LED ein??
    PORTC &= ~(1<<5);
    break;
    case 0: //LED aus??
    PORTC |= (1<<5);
    break;
    }
    }
    Leider geht der Code auf dem Bord nicht. Die LED geht an und es gibt keine weitere Reaktion auf den Schalter.
    Bei der Simulation in AVRStudio werden außerdem die _delay_ms übersprungen, ohne dass die Stoppuhr entsprechend weiter zählt.

    Könnt ihr mir sagen, wo ich meine(n) Fehler habe...

    Danke für die Hilfe...Grüße

    PS: Bei mir im Programm habe ich die einzelnen Blöcke eingerückt. Hier kommt das leider nicht an

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    23.02.2010
    Ort
    Düsseldorf
    Beiträge
    24
    Noch ein paar Worte zum Sinn und Zweck des Programms:

    Zuerst sollen die Ein-/Ausgänge gesetzt werden. Als Bestätigung dafür soll die LED für 0,5sec leuchten.

    Danach folgt eine Abfrage: Ist der Schalter gedrückt oder nicht.
    Wenn ja, wir die LED eingeschaltet durch LEDschalten(1). Danach folgt eine Schleife die entweder nur zaehler++ macht oder bei einer Dauer von 2sec die LED wieder aus schaltet und den zaehler wieder auf 0 setzt.

    Die Schleife mit dem zaehler habe ich eingefügt um so ne Art Multitasking zu realisieren (hier ohne effekt, es geht mehr ums angewöhnen).

    Ich hoffe das ist so verständlich...

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Das mit dem Einrücken haut deshalb nicht hin, da du das als "Zitat" und nicht als "Code" angegeben hast.
    Warum das delay nicht geht: Hast du ne Optimierung eingeschaltet? Ohne die arbeitet _delay_ms() nicht richtig.
    #ifndef MfG
    #define MfG

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    23.02.2010
    Ort
    Düsseldorf
    Beiträge
    24
    Hi Jaecko,

    ich hab bei mir die Optimierung auf -Os stehen. Das ist doch so der allgemeine Standard, oder?

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    35
    Beiträge
    1.987
    Einen Fehler seh ich grad auch noch (der sogar im Code richtig kommentiert ist): Die Zählervariable ist nur eine uint8_t. Die wird den Wert 1999 niemals erreichen.

    Und das mit dem Problem im Simulator: Es könnte sein, dass das Delay garnicht übersprungen wird sondern einfach so lange braucht. Der Simulator ist leider alles andere als Echtzeit.

    Und Os ist eigentlich das am häufigsten verwendete.
    Kenn eigentlich kaum was, wo man komplett ohne Optimierung arbeitet.
    #ifndef MfG
    #define MfG

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554
    Hi Lightstorm,

    mir ist unklar, warum Du auf den Ausgang für die LED den PullUp setzt: ... //C5 als Ausgang ... PORTC = (1<<5); //C 00100000 . Das ist doch eine Aktion die (eher) für Eingänge Sinn macht. Als nächstes schreibst Du nix dazu, wie der Eingang beschaltet ist: wird durch den Taster ein low oder ein high auf PIND2 gelegt? Bei (Taster legt gedrückt low auf PD2) sollte auf PD2 der PullUp aktiviert werden. Aus Deiner Abfrage if (PIND & (1<<2)) lese ich, dass Du ein high auf dem Taster abfragst. Hast Du dann einen Pulldown für den Eingang PD2 vorgesehen?

    Dein Dilemma mit uint8_t zaehler hat Jaecko ja schon erwähnt.
    Ciao sagt der JoeamBerg

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    23.02.2010
    Ort
    Düsseldorf
    Beiträge
    24
    Hi zusammen und lieben Dank für eure Hilfe.

    @Jaecko: Oops, ja das ist mir durch die Finger gelaufen, danke für den Hinweis.

    @oberallgeier: Also irgendwo steige ich bei deinem Kommentar aus, bin noch blutiger Anfänger. Die Initialisierung (außer dem Blinken) hab ich aus dem Programm Button auf der Olimex-Seite entnommen (http://olimex.com/dev/avr-p28.html). Wieso der PORTC gesetzt wird weiß ich ehrlich gesagt nicht. Ich selbst hätte nur die DDR gesetzt und die PORT erstmal unbeachtet gelassen. Was du aber jetzt mit "PullUp setzen" meinst, und wieso man das eher für Eingänge benutzt versteh ich nicht.

    Woran erkenne ich, ob ein Schalter ein low (eine null) oder ein High (eine 1) erzeugt?

    Bei (Taster legt gedrückt low auf PD2) sollte auf PD2 der PullUp aktiviert werden. Aus Deiner Abfrage if (PIND & (1<<2)) lese ich, dass Du ein high auf dem Taster abfragst. Hast Du dann einen Pulldown für den Eingang PD2 vorgesehen?
    Ja, und hier steige ich dann komplett aus. Da weiß ich gar nicht mehr was du von mir willst

    Wäre über Vokabeltrainung und Hilfestellung froh...Danke für eure Mühen.

    Georg

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    23.02.2010
    Ort
    Düsseldorf
    Beiträge
    24
    Hab mir das mit dem PullUp-Wiederständen nochmal angeschaut (http://www.mikrocontroller.net/artic...lup-Widerstand) und natürlich macht damit das setzen des PORT (und damit des PullUp-Wiederstands) nur beim Eingang Sinn.

    Hier nochmal die aktualisierte Version des Codes:
    Code:
    /****************************
    Ein-/Ausgänge
    Zeitverzögerung
    Variablenlängen
    *****************************/
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdint.h>
    
    
    /****************************
    Anlegen der Funktionen
    *****************************/
    void initialize();
    void LEDschalten(int status);
    
    
    /****************************
    Globale Variable für Zähler der An-Aus-Schleife
    *****************************/
    uint16_t zaehler=0;	//bis max 65536
    
    
    int main(void)
    {
    
    	initialize();
    
    	while(1)
    	{
    		if (PIND & (1<<2))
    		{
    			LEDschalten(1);		//LED ein
    			zaehler=0;
    		}
    
    	
    		if (zaehler >= 1999)
    		{
    			LEDschalten(0);		//LED aus nach 2sec
    			zaehler=0;
    		}
    		else
    		{
    			zaehler++;
    			_delay_ms(1);
    		}
    	}
    
    
    return 0;
    }
    
    
    void initialize()
    {
    	DDRB = 0x00;		//B als Eingang
    	DDRD = 0x00;		//D als Eingang
    	DDRC = (1<<5);		//C5 als Ausgang
    
    	PORTB = 0x00;		//B 00000000
    	PORTD = 0x00;		//D 00000000
    
    	LEDschalten(1);		//LED ein
    	_delay_ms(500);		//0.5sec Leuchten
    	LEDschalten(0);		//LED aus
    
    }
    
    
    void LEDschalten(int status)
    {
    	switch (status)
    	{
    		case 1:				//LED ein??
    			PORTC &= ~(1<<5);
    			break;
    		case 0:				//LED aus??
    			PORTC |= (1<<5);
    			break;
    	}
    }

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    @oberallgeier: Wenn ein Port als Ausgang definiert ist, wird er mit dem PORTx-Register an- oder ausgeschaltet. Mit PullUp hat das nix zu tun. Und das PORTC = (1<<5) macht an der Stelle durchaus Sinn, denn dadurch wird die LED, die offensichtlich (wie es sich gehört) Low-aktiv am Controller angeschlossen ist, erst mal ausgeschaltet.

    Zu den Eingängen: Da hast Du Recht.
    Zur Erklärung für Lightstorm: Du kannst einen Taster auf zwei Arten an den Controller anschließen.
    1) Du verbindest den einen Pin des Tasters mit dem Controller, den anderen mit GND. Das ist die übliche vorgehensweise. Damit der Controller bei offenem Taster einen definierten Zustand hat, benötigst Du einen Pull-Up Widerstand (~10k), der einfach zwischen den Eingang des Controllers und VCC geschaltet wird. Alternativ kannst Du auch den internen Pull-Up Widerstand des AVR anschalten, indem Du das entsprechende Bit im PORTx-Register setzt (was Sinn macht, so spart man ein Bauteil)
    2) Du verbindest den einen Pin des Tasters mit dem Controller, den anderen mit VCC. Hier gilt das gleiche wie bei 1), nur das Du nun keinen Pull-Up sondern einen Pull-Down brauchst - also einen Widerstand vom Controller-Pin nach Masse. Den musst Du extern beschalten, der AVR hat keinen internen Pull-Down.

    Gruß,
    askazo

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.554
    Zitat Zitat von Lightstorm
    ... steige ich bei deinem Kommentar aus ...
    Tut mir leid. Ich dachte, dass Du Dein Board wenigstens in den Grundzügen kennst - und ich mir diesen Schaltplan nicht erst von irgendwo herholen muss. Also - nach dem Schaltplan zieht der Taster den PD2 auf GND (sprich : auf etwa 0V bzw. low ). Und deshalb müsste Deine Abfrage entsprechend geändert werden.

    Zitat Zitat von askazo
    @oberallgeier: Wenn ein Port als Ausgang definiert ist, wird er mit dem PORTx-Register an- oder ausgeschaltet ...
    Na prima, dann weiß ich das jetzt auch. Hatte den Kommentar dummerweise gegeben, ohne das Board zu kennen - werde ich zukünftig bleiben lassen.
    Ciao sagt der JoeamBerg

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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