-         

Ergebnis 1 bis 9 von 9

Thema: For - Schleife (Zeitmessung)

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43

    For - Schleife (Zeitmessung)

    Anzeige

    Hi to @ll,

    ich habe folgendes for:

    Eine Led (PB1) geht über einen Taster (PB0) an und aus. Wenn ich jetzt aber den Taster (PB0) länger als z.B. 6sec gedrückt halte, soll die Led (PB1) auch aus gehen.

    Ich habe schon mal ein Programm geschrieben, aber ich weiß nicht wie ich die Zeitmessung (Zeit_Starten) machen? <.. Über eine For - Schleife?


    Hier meine Code:
    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #define F_CPU 8000000  // 8 MHz
    
    
    int Zeit_Starten(void) { //Hier Startet die Zeit, von 0sec bis 1 min
    for(i;1<60;i++){ 
    
     }
    }
    int main(void) { 
         DDRB  &= (~ (1<<PB0));  /* Pin PB0 als Eingang */
         PORTB |= (1<<PB0);    /* Pull Up von PIN B0 aktivieren */ 
         DDRB   = (1<<DDB1);  // PB1 Ausgänge
         int Zeit_Abfrage;
    	 int i;
    	 
    while(1){
      if (!( PINB & (1<<PINB0))) {    /* mache was wenn PinB0 low ist */
      
        Zeit_Starten();  // Wenn Taste gedrückt wird, dann Anfangen mit der Zeitmessung
      
        if(Zeit_Abfrage > 6){  /* Wenn länger als 6 sec Taster gedrückt, dann Led aus */
           PORTB|=(1<<PB1);    // high 
        	}
       else{ 
           PORTB&= ~(1<<PB1);  // low  
            }  
        }
    } 
    return 0;
    }

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Meine erste Idee wäre folgendes:
    - Du schaltest den Taster auf einen Interrupt.
    - Wird der Interrupt ausgelöst, schaust Du, wie der jetzige Status des PINs ist.
    - Ist er HIGH (damit meine ich gedrückt), dann hältst Du die aktuelle Zeit fest, d.h. liest eine Zählervariable aus, die in einem Timer hochgezählt wird.
    - Ist er aber LOW, so bildest Du die Differenz aus altem gespeichertem Zeitwert und dem jetzigen und hast die Drückdauer ermittelt.

    Nachteil: Das funktioniert erst, wenn man den Taster loslässt.
    Interessanter wäre es, wenn er nach 6 Sekunden gedrückthalten autom. anfängt, ohne dass man loslassen muss. Da fällt mir auch schon der passende Code für ein. Aber diese Ausarbeitung überlasse ich dem geneigten Leser.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43
    Hört sich irgendwie kompliziert an...

    Kann ich nicht einfach ein Timer wenn ich den Taster drücke zählen lassen, und wen nich den Taster los lasse Timer auf 0.

    Dann könnte ich doch mit der If Abfrage sagen, wenn Timer > 6 dann Led aus.

    Oder ist das so nicht machbar?

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43
    Ich dachte so in etwas könnte das aussehen:

    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <stdint.h>
    #define F_CPU 8000000  // 8 MHz
    
     
    	 
    void init_timer(void){
     for(;;){  //Endlosschleife
        TCCR0 |= (1<<CS00)|(1<<CS02); //Teilung 1024 des Taktes
     if(TCNT0==255){ // alle 255 soll i eine Zahl erhöt werden
        i=i++;} 
     }
    } 
    int main(void){ 
    	 DDRB  &= (~ (1<<PB0));  /* Pin PB0 als Eingang */
         PORTB |= (1<<PB0);    /* Pull Up von PIN B0 aktivieren */ 
         DDRB   = (1<<DDB1);  // PB1 Ausgänge
         int i;
    	 i=0;
    
     
    while(1){
      if (!( PINB & (1<<PINB0))) {    /* mache was wenn PinB0 low ist */
      
        init_timer(); // Timer starten
    	
      if (i < 6){  /* Wenn länger als ca.6 sec Taster gedrückt, dann aus */
           PORTB|=(1<<PB1);    // high 
        	}
       else{ 
           PORTB&= ~(1<<PB1);  // low  
    	TCNT0=0; // Timer zurück setzten   
            }  
        }
    } 
    return 0;
    }

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43
    Ich nochmals, ich habe mal soweit die hälte geschaft,

    die Led geht nach 6 sec aus, wenn ich den Taster dauert gedrückt halte.
    Aber wenn ich jetzt nur kurz den Taster betätige, leuchtet die Led dauern

    Hier der Code:

    Code:
    #include <avr/io.h>        
    #include <avr/interrupt.h>
    
    ISR(TIMER0_OVF_vect)
    {
      static int a = 0;
      a++; // Breakpoint #1 im Simulator
      
      
      
       if (!( PINB & (1<<PINB0))) /* mache was wenn PinB0 low ist */   
           { 
    
          
           if (a > 6)
    	   { 
             PORTB|=(1<<PB1);    // high
           }
          else
           {
             PORTB&= ~(1<<PB1);  // low
             a = 0;
    	   }
         }
     
       }
    
    void InitTimer(void)
    {
      TCCR0 = TCCR0 | (1<<CS00);  // Prescaler CK/8
      TCNT0 = 0;
      TIMSK = TIMSK | (1<<TOIE0);
    }
    
    int main(void)
    {
    
    	   InitTimer();
           sei();
        
    
      DDRB  &= (~ (1<<PB0));  /* Pin PB0 als Eingang */
      PORTB |= (1<<PB0);    /* Pull Up von PIN B0 aktivieren */
      DDRB   = (1<<DDB1);  // PB1 Ausgänge 
    
    
      while(1)
      {
      }
    }

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.186
    Wenn die Taste nicht mehr gedrückt ist, springt das Programm nicht mehr in die if-Schleife. Ein else anfügen zum Led löschen.
    Die gesamte if-Schleife aber in die Endlosschleife einfügen, den Code in der ISR so kurz wie möglich halten.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43
    Hi Hubert.G,

    wenn ich die gesamte if-Schleife aber in die Endlosschleife einfügen, habe ich Problem mit der Variable A. Muss ich die wieder in der Endlosaschleife deklarieren? Ich weiß jetzt nicht genau wie du es meinst... Könntest du mir es erklären?

    Wo muss ich das genau einbienden, hier der Code:

    Code:
    #include <avr/io.h>        
    #include <avr/interrupt.h>
    #include <stdint.h>
    
    
    ISR(TIMER0_OVF_vect)
    {
      static int a = 0;
      a++; // ca. 1 sec zahlt die Variable a
    } 
    
     void InitTimer(void)
    {
      TCCR0 = TCCR0 | (1<<CS00);  // Prescaler CK/8
      TCNT0 = 0;
      TIMSK = TIMSK | (1<<TOIE0);
    }
    
    
    int main(void)
    {
    
       InitTimer();
       sei();
        
    
      DDRB  &= (~ (1<<PB0));  /* Pin PB0 als Eingang */
      PORTB |= (1<<PB0);    /* Pull Up von PIN B0 aktivieren */
      DDRB   = (1<<DDB1);  // PB1 Ausgänge 
    
    
      while(1)
      {
           if (!( PINB & (1<<PINB0))) /* mache was wenn PinB0 low ist */  
           { 
            // Hier muss Variable a abgefragt werden
             PORTB|=(1<<PB1);    // high
           }
          else
           {
             PORTB&= ~(1<<PB1);  // low
    	   }
    	   
      }
    }

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.186
    So sollte es funktionieren, die Timerzeit stimmt nicht und wenn die Taste länger als 65535 gedrückt ist dann leuchtet die LED wieder, da es zu einem Zählerüberlauf kommt.
    Code:
    #include <avr/io.h>       
    #include <avr/interrupt.h>
    #include <stdint.h>
    
    volatile unsigned int a = 0;
    
    ISR(TIMER0_OVF_vect)
    {
      
      a++; // ca. 1 sec zahlt die Variable a
    }
    
     void InitTimer(void)
    {
      TCCR0 = TCCR0 | (1<<CS00);  // Prescaler CK/8
      TCNT0 = 0;
      TIMSK = TIMSK | (1<<TOIE0);
    }
    
    
    int main(void)
    {
    
       InitTimer();
       sei();
       
    
      DDRB  &= (~ (1<<PB0));  /* Pin PB0 als Eingang */
      PORTB |= (1<<PB0);    /* Pull Up von PIN B0 aktivieren */
      DDRB   = (1<<DDB1);  // PB1 Ausgänge
    
    
      while(1)
      {
           if (!( PINB & (1<<PINB0))) { 	/* mache was wenn PinB0 low ist */ 
            	if (a < 6){ 				 /* Wenn länger als ca.6 sec Taster gedrückt, dann aus */
           			PORTB|=(1<<PB1);    // high
          			 }
      		 	else {PORTB&= ~(1<<PB1);  // low  
    				}
           }			
          else
           {
             PORTB&= ~(1<<PB1);  // low
         		a=0;
    	  }    
      }
    }
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    19.09.2008
    Ort
    Kreis Olpe
    Alter
    40
    Beiträge
    43
    Danke für dein Code, aber so leutet die lampe sehr sehr schwach und nicht normal! Da ist irgendwo noch ein Denkfehler!

    jetzt gehts besser ich habe den Wert a>6 geändert und es klappt!

    Danke nochmals.

Berechtigungen

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