- Labornetzteil AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 22

Thema: Timer verwenden als Wait Funktion

  1. #11
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Anzeige

    E-Bike
    Hallo,

    schau dir bitte einmal folgenden Link zur Gültigkeit von Variablen an Link
    Sowohl 11.6, 11.7 und wenn du schon dabei bist passt 11.8 zum Thema.

    Du hast Izeit_1 lokal definiert. Es muss aber global definiert sein, um in allen Funktionen gültig zu sein. Für die Mikrocontroller Welt ist dann noch in deinem Fall das Schlüsselwort volatile wichtig. Der Compiler kann aus dem Code nicht Feststellen, dass die ISR ja jederzeit aufgerufen werden kann. Daher kann es durch Optimierungen zu Fehlern kommen. Volatile sagt einfach aus, dass die Variable zur Verwendung immer aus dem Speicher geladen werden muss und nicht in einem Register bevorratet werden darf.
    Wenn du es genauer wissen möchtest, im Wissenbereich gibt es einen Artikel zu Interrupts und deren Fallstricke.


    Gruß

    Jens

  2. #12
    Hallo Jens,

    danke für deine Info. Hab die Bariable jetzt global deklariert.

    Es kommen zwar keine Fehlermeldungen mehr, aber das Programm funktioniert trotzdem nicht

    Gruß Anna

  3. #13
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Hallo Anna,

    könntest Du mal bitte Deinen Code posten? Dazu natürlich Controllertyp, Quarzfrequenz, halt das ganze Drumrum. Wenns geht weniger als 100 Seiten (ich bin total lese+sonst-faul und verliere schnell die Übersicht) - aber vielleicht können wir zusammen was rausfinden.
    Ciao sagt der JoeamBerg

  4. #14
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    setzt du Izeit_1 noch in der while auf 0? Das gehört wohl in die main aber nicht in die while. Sonst poste bitte noch einmal den aktuellen Code.

    Gruß

    Jens

  5. #15
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Zitat Zitat von oberallgeier
    ... total lese+sonst-faul und verliere schnell die Übersicht ...
    Schlimm schlimm, ich hatte es ja gesagt. Und nun - hab Deinen Code nicht beachtet, entschuldige. Sind ja auch nicht mal 100 Seiten.

    Jens hat ja schon dieses "Iz... = 0" im main angemerkt. Warum machst Du das?

    PS: Für so Chaotenleser wie mich sieht der code viel besser/lesbarer aus (wenn ich den mal lese), wenn Du ihn mit gestuften Einrückungen versiehst.
    Ciao sagt der JoeamBerg

  6. #16
    Hallo ihr beiden,

    also ich hab noch ein bißchen was geändert... (wie Izeit_1 nicht in der while schleife auf 0 setzen ) Ich habe auch noch ne else schleife dazugefügt.
    Das komische ist er geht anscheinend nur in die Else-Schleife, da die LED3 (PC2) immer wieder toggelt. Also funktioniert es irgendwie schon aber nicht wirklich befriedigend Die Bedingung in der IF schleife führt er nicht aus....

    Rahmenbedingungen: Atmega16 16 MHz
    am PortC sind LEDs angeschlossen

    Code:
    #include <stdlib.h>
    #include <avr/pgmspace.h>
    #include <stdio.h>
    #include <util/delay.h>
    
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    uint16_t Izeit_1=0;
    
    void Timer0_init(void)                  // Init Tmr/Cntr 0, 8-Bit auf 20 kHz = 50 µs
    {        
        TCCR0 |= (1<<WGM01) | (1<<CS01);               // Timer im CTC-Mode, Top=OCR2A   Prescaler 1/8 / Clock <- CPU     
        OCR0 = 49;                        // Preset 48 für 50µs bei 16Mhz 
        TIMSK |= (1<<OCIE0);      // Tmr/Cntr CompareA interrupt enabled
    }     
    
    /* Routine zählt hoch im Takt 20 kHz = 50 µs.                                     */
    ISR(TIMER0_COMP_vect)          // Vektor 7
    {
        if (Izeit_1 <= 60000)        //Timer bis 60 000 - 3 sec Datenerfassung möglich
          Izeit_1 ++;               //  war: alle drei Sekunden wird 60000 erreicht
                      //  und Izeit_1 bleibt in der uint16-Grenze
        else
        {   
            Izeit_1 = 0;      // ansonsten: Rückstellen auf Null
            PORTC ^= (1<<PC5);      // Zur Anzeige gLED am PC5/SCL toggeln
        }     
             
    }         
    
    
    
    int main(void)
    {
    	Izeit_1=0;
    	Timer0_init();
    	DDRC |= 0xff; 
    	PORTC=0x00;
    
    	while(1)
    	{
    		cli();
    		sei();
    		if (Izeit_1>2)
    		{
    			PORTC ^= (1<<PC0);
    		}
    		else
    		{
    			PORTC ^= (1<<PC2);
    		}
    		cli(); 
    	}
    }
    Danke schon mal im vorraus für die Mühe........

    Gruß Anna[/code]

  7. #17
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Hi, Anna,

    möglicherweise geht es so, ich habe das aber (noch) nicht getestet - muss jetzt essen gehen.

    Code:
    #include <stdlib.h> 
    #include <avr/pgmspace.h> 
    #include <stdio.h> 
    #include <util/delay.h> 
    
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    
    /* ============================================================================== */ 
    void Timer0_init(void)                  
    {        
        TCCR0 |= (1<<WGM01) | (1<<CS01);              
        OCR0   = 124;                        
        TIMSK |= (1<<OCIE0);      
    }      
    /* ============================================================================== */ 
    
    
    /* ============================================================================== */ 
    /* ===  Nicht unterbrechbare ISR für timer2 ===================================== */ 
                            
    ISR(TIMER0_COMP_vect)          // Vektor 7 
    { 
        if (Izeit_1 <= 60000)        //Timer bis 60 000 - 3 sec Datenerfassung möglich 
          Izeit_1 ++;               //  war: alle drei Sekunden wird 60000 erreicht 
                      //  und Izeit_1 bleibt in der uint16-Grenze 
        else 
        {    
            Izeit_1 = 0;      // ansonsten: Rückstellen auf Null 
    //      PORTC ^= (1<<PC5);      // Zur Anzeige gLED am PC5/SCL toggeln 
    // Hallo Anna: das Toggeln hier würde Deinen Schaltvorgang im main
    //   stören - daher wurde es "auskommentiert".
        }      
              
    }          
    /* ============================================================================== */ 
    
    int main(void) 
    { 
      uint16 Izeit_1=0; 
      Timer0_init(); 
      DDRC |= 0xff; 
      PORTC=0x00; 
    
    
    
    
    //####### Grundlegende Initialisierungen der Hardware, Portdefinition -------------
    //Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
                             
      DDRC  = 0b00000001;   // PC0 .. 6, (kein PC7 bei m168), NUR Ausgang PC1 aktiv
      PORTC = 0b00000000;   // Anmerkung: die binäre Codierung der Ports hat den
                            //   Vorteil, dass man/ich gleich sehe, "was los ist".
                            //   So kann ich es mir eben besser vorstellen als in hex.
    
    
    
    
    
      cli(); 
      Izeit_1=0; 
      sei(); 
    
      while(1) 
      { 
        if (Izeit>5000) 
        { 
          PORTC ^= (1<<PC1);        
        }  
      } 
    }
    Wenn Du das in der Zwischenzeit testen kannst wär schön, ansonsten hol ich nachher meine RNControl, dafür habe ich auch einen m16. Es sei denn, wir können uns vorerst mit Tests auf (m)einem m168/20MHz begnügen.

    Viel Glück
    Ciao sagt der JoeamBerg

  8. #18
    Hallo Oberallgaier,

    danke für den Code. Ich habe ihn getestet. Er funktioniert bei mir leider nicht.
    Ich habe Izeit_1 ausserhalb der main routine deklariert und in der while-Schleife Izeit auf Izeit_1 geändert. Es compiliert zwar ohne Fehler, aber es ist nur dauerhaft LED1 an. Sonst passiert nichts.......

    Ich muß jetzt leider auch essen gehen. Weiß deshalb nicht ob ich heute noch weiter probieren kann. Aber morgen bin ich wieder online ......

    Bis dann Gruß Anna

  9. #19
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    es fehlen bei euch beiden noch die geschweiften Klammern bei

    Code:
                    if (Izeit_1 <= 60000) {<- fehlt
                        Izeit_1 ++;               //  war: alle drei Sekunden wird 60000 erreicht
                      //  und Izeit_1 bleibt in der uint16-Grenze
    fehlt ->    } else
    und benutzt bitte als globale Definition

    volatile uint16 Izeit_1;

    @beginner1101 falls das noch nicht zum gewünschten Ergebnis führt, beschreibe vielleicht noch einmal kurz, was du erreichen möchtest. Sorry das steht bestimmt irgendwo, aber ich finde da jetzt nicht durch.

    Gruß

    Jens

  10. #20
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Hi Anna,

    tut mir leid - nun artet das bei mir in experimenteller Softwareentwicklung aus (kann meinen m16 nicht finden *grrrrrrrr* - und der m168 hat andere Registernamen, dann hätten wir hier noch mehr Konfusion). Daher - nochmal ungetestet, aber ohne Fehler compiliert. Ausserdem hat Jens recht - was wollen wir machen? Ich verstehe das so, es soll in einem bestimmbaren, zeitlichen Abstand einfach die LED auf PC1 getoggelt werden.

    Hier der code:
    Code:
    #include <stdlib.h> 
                                     
    #include <avr/interrupt.h> 
                                     
    #define MCU = AVR_ATmega16
    // #define F_CPU  20000000         // Quarz 20 Mhz-CPU
    #define F_CPU  16000000         // Quarz 16 Mhz-CPU
                                     
    volatile uint16_t Izeit_1;			// Timervariable
    
    // ================================================================================
    void Timer0_init(void)                  
    {        
        TCCR0 |= (1<<WGM01) | (1<<CS01);              
        OCR0   = 125;                        
        TIMSK |= (1<<OCIE0);      
    }      
    // ================================================================================
    
    
    // ================================================================================
    // ================================================================================
                            
    ISR(TIMER0_COMP_vect)           // Vektor 7 
    { 
        if (Izeit_1 <= 60000)       //Timer bis 60 000 - 3 sec Datenerfassung möglich 
          Izeit_1 ++;               //  war: alle drei Sekunden wird 60000 erreicht 
                                    //  und Izeit_1 bleibt in der uint16-Grenze 
        else 
        {    
            Izeit_1 = 0;            // ansonsten: Rückstellen auf Null 
            PORTC &= ~(1<<PC1);     // Port PC1 ausschalten
    // Hallo Anna: der Port wird hier bei Izeit_1 = 0 ausgeschaltet
        }      
              
    }          
    // ================================================================================
    
    int main(void) 
    { 
    //uint16 Izeit_1   = 0; 
      Timer0_init(); 
      DDRC |= 0xff; 
      PORTC=0x00; 
    
    
    
    
    //####### Grundlegende Initialisierungen der Hardware, Portdefinition -------------
    //Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
                             
      DDRC  = 0b00000010;   // PC0 .. 7, NUR Ausgang PC1 aktiv
      PORTC = 0b00000000;   // Anmerkung: die binäre Codierung der Ports hat den
                            //   Vorteil, dass man/ich gleich sehe, "was los ist".
                            //   So kann ich es mir eben besser vorstellen als in hex.
    //####### So werden Ausgänge geschaltet -------------------------------------------
    //  PORTC |=  (1<<PC1);         // Port PC1 einschalten
    //  PORTC &= ~(1<<PC1);         // Port PC1 ausschalten
    //  PORTC ^=  (1<<PC1);         // Port PC1 toggeln
    // ###>>> BEACHTE: die Pins zählen von 0 bis 7, PC1 ist also der ZWEITE PortPin
    
    
    
      cli(); 
      Izeit_1 = 0; 
      sei(); 
    
      while(1) 
      { 
        if (Izeit_1 == 5000) 
        { 
          PORTC |=  (1<<PC1);       // Port PC1 einschalten
    // Hallo Anna: der Port wird hier bei Izeit_1 = 5000 eingeschaltet
        }  
      } 
    }
    Zitat Zitat von McJenso
    ... es fehlen bei euch beiden noch die geschweiften Klammern ...
    Ohhh - das ist - bei einem einzigen Statement nach dem "if" soweit ich weiß ANSI-konform.

    Edit 23:20: Mein verlorener mega16 ließ mir keine Ruhe. Und als ich ihn gefunden hatte ist mir auch der Fehler aufgefallen. Nun ist der Code ok - und auf meinem fabrikfrischen mega16 läuft er mit 16MHz-Quark auf der RNControl: die LED auf PC1 blinkt.
    ###>>> Code korrigiert!
    Sorry für die ungenaue Bearbeitung.
    Ciao sagt der JoeamBerg

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests