- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 28

Thema: atmega16 Füllstand

  1. #11
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hey Hannes,

    vielen Dank für den guten Link. Leider werd ich vor Montag nicht dazu kommen es auszutesten Aber dann gehts los
    Schaun mer mal

    Viele Grüße,

    Jimmy

  2. #12
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Hallo Hannes

    Also die Sachen die du mir da geschickt hast, passen ziemlich gut zu dem was ich auch machen will. Nur eines ist mir noch unklar...
    Mein Timer muss ja irgendwie starten..mache ich das über ne if Anweisung? Oder wie krieg ich den Timer dazu genau dann hochzulaufen wenn der obere Endschalter betätigt ist und dann zu stoppen wenn der untere betätigt ist?

    Viele Grüße

    Jimmy

  3. #13
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.089
    Zuerst stellst du den Timer ein (Prescaler,...). Danach gibst du den Timer frei, damit er auf Interrupts des Timers reagiert.
    Ich weiß zwar nicht wo du den Taster anschließt, aber hier ein kleines Beispiel.
    Code:
    if ( PINC & (1<<PINC1) ) sei();
    damit du den Interrupt stoppst musst du sei mit cli austauschen. Den Port und Pin musst du anpassen.
    http://www.mikrocontroller.net/artic...R-GCC-Tutorial

    MfG Hannes

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also mein erster Taster liegt am Port A Pin 7. Wenn der auf Masse gezogen wird, soll der Timer starten.

    Den stelle ich vorher entsprechend dem Datenblatt ein (Prescaler etc.)


    In meiner ISR soll nur eine Variable hochgezählt werden...entsprechend dem oberen Link, den du mir geschickt hast.

    Heisst das ich muss den Pin so anpassen wie dus da geschrieben hast und wenn er aufhören soll zu zählen einfach ein cli() mit entsprechendem PIN hin ? Und die Stoppuhr läuft dann schon!? Oder kommt in die if-Anweisung sonst noch etwas rein?

    Sorry, dass es bei mir so lange dauert Bin manchmal etwas schwer von Begriff

    Gruss

  5. #15
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.089
    Du musst oben das anpassen (Port und Pin). Bei deinem ersten Kontakt wäre das dann
    Code:
    if (PINA & (1<<PA7)) sei();
    Beim anderen Kontakt ersetzt du "PINA" mit dem Port, den du hast. PIN bleibt immer gleich. der letzte Buchstabe gibt den Port an. PINA wäre Port A, PINB wäre Port B,...
    "PA7" musst du mit dem Pin ersetzten. "P" bleibt immer gleich. Das "A" ist der Port und die Ziffer ist der Pin.

    Wenn du die Interrupts stoppst musst du "sei();" mit "cli();" austauschen. Die Pins und Ports musst du deinen Bedürfnissen anpassen.

    Ich würde den Timer einfach laufen lassen (mittels Kontakt starten). Bei jedem Overflow eine Variable um 1 erhöhen. Wenn der Timer gestoppt wird, ließt du die Variable und das Timerregister mit dem aktuellen Zählerstand. Entweder berechnest du die Zeit direkt und sendest es an den PC oder du sendest die Überläufe und den Zählerstand an den PC und berechnest es am PC.

    MfG Hannes

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also ich hab mir da jetzt mal was überlegt...bzw mit deinem Link da zusammengesucht und wollt fragen ob das prinzipiell laufen könnt.


    TIMER2_interrupt_init(void)
    {
    TCCR2 = (1<<WGM21) (0<<WGM20) (1<<CS22) (1<<CS21) (1<<CS20);
    TCNT2=0;
    OCR2=249;
    TIMSK = (1<<OCIE2);
    }

    int main(void)

    {
    if(PINA & (1<<PA7))
    {sei()
    TIMER2_interrupt_init
    }
    if(PINA & (1<<PA2)
    {cli();
    }
    while(1);
    }

    ISR(TIMER2_COMP_vect)
    {
    z++
    if(z==125){
    sekunde++;
    z=0;}
    if(sekunde==60){
    minute++;
    sekunde=0;
    if(minute==60){
    stunde++;
    minute = 0;
    }
    }


    Nun ist es ja so, dass ich mit dem oberen Sensor den Timer starten und den mit dem unteren den Timer stoppen und auslesen will...für die Übertragung an den PC hab ich mir noch wenig gedanken gemacht...zuerst sollte das hier funktionieren!?
    wenn ich mein Programm so laufen lass: Was passiert in dem Bereich in dem kein Sensor betätigt wird?Oder kann man das irgendwie machen, dass der nur auf steigende oder fallende Flanken reagiert?
    Ist mein Programm prinzipiell richtig?Oder hab ich cli() und sei() falsch eingesetzt?

    Vielen Dank und viele Grüße,

    Jimmy

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Hallo nochmal

    also einen fehler hab ich schon gefunden. da wo das while(1) muss ein return(0) hin und vor die if Anweisung in main das while(1). Aber prinzipiell müssts doch dann stimmen ???
    Und die Variablen sekunde, minute, stunde müssen doch dann als volatile deklariert werden. Würde mich über jede Antwort freuen.

    Viele Grüße,
    Jimmy

  8. #18
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.089
    Bin erst jetzt wieder online. Du hast einige Fehler drinnen.
    1.) Das "ISR(Timer2_COMP_vect){...} kommt vor main (wie timer init)
    2.) Den Timer nur einmal initialisieren
    Als Beispiel:
    Code:
    TIMER2_interrupt_init(void) 
    { 
      TCCR2 = (1<<WGM21) (0<<WGM20) (1<<CS22) (1<<CS21) (1<<CS20); 
      TCNT2=0; 
      OCR2=249; 
      TIMSK = (1<<OCIE2); 
    } 
    
    ISR(TIMER2_COMP_vect) 
    { 
      z++;
      if(z==125)
      { 
        sekunde++; 
        z=0;
      } 
    
      if(sekunde==60)
      { 
         minute++; 
         sekunde=0;
      }
    
      if(minute==60)
      { 
         stunde++; 
         minute = 0; 
      } 
    
    int main(void) 
    { 
      TIMER2_interrupt_init;
    
      if(PINA & (1<<PA7)) 
      {
         sei();
      } 
    
      if(PINA & (1<<PA2) 
      {
         cli(); 
      } 
    
      while(1); 
    }
    Statt
    Code:
      if(PINA & (1<<PA2) 
      {
         cli(); 
      }
    kannst du auch
    Code:
      if(PINA & (1<<PA2) cli();
    schreiben.

    Den Code solltest du kommentieren, damit du später auch noch weißt, warum was geschrieben wurde. (Andere finden sich im Code besser zurecht)

    MfG Hannes

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Hallo Hannes!

    Vielen Dank für die vielen Antworten! Ach so ja stimmt, solange mein Pin gesetzt ist, wird der Timer immer neu initialisiert. Das werd ich so übernehmen und dann weiterprobieren. Und der Timer startet dann immer wenn der obere Pin gesetzt wird bei 0?

    Viele Grüße, Jimmy

  10. #20
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    37
    Beiträge
    5.089
    Habe gerade einige Fehler gesehen, die mir vorher entgangen sind.
    1.) Je nachdem was du verwendest musst du if(PINA & (1<<PA2)) cli(); bzw if ( !(PINB & (1<<PINB2))) cli(); schreiben. Das Gleiche gilt für PA7. Wenn du den internen Pullupwiderstand nimmst musst du dieses Ändern.

    2.) Die Endschalterabfrage musst du in die While(1) Schleife setzten, sonnst wird das Programm nur einmal ausgeführt.

    Das Programm schaut so aus, wenn du den internen (oder externen) Pullupwiderstand nimmst.
    Code:
    int main(void) 
    { 
      TIMER2_interrupt_init; 
    
      while(1)
      {
        if(!(PINA & (1<<PA7))) sei(); 
    
        if(!(PINA & (1<<PA2))) cli(); 
      }
    }
    Habe nur main geschrieben. die ISR und Timer Init musst du natürlich auch schreiben.
    Damit du das Programm testen kannst würde ich noch eine Led anschließen. Bei jedem Timerüberlauf (in der ISR) änderst du den Zustand der Led (ein/aus). Bei der Led darfst du den Vorwiderstand nicht vergessen.

    Beim Timer init musst du noch die einzelnen Variablen mit | verknüpfen, sonst funktioniert es nicht. Außerdem musst du vor "TIMER2_interrupt_init(void)" noch ein void geben.

    Diesen Code habe ich gerade mit einem Atmega8 getestet, deswegen habe ich andere Pins.
    Code:
    void TIMER2_interrupt_init(void)
    {
      TCCR2 = (1<<WGM21)|(1<<CS22)| (1<<CS21) |(1<<CS20); 
      TCNT2=0; 
      OCR2=249; 
      TIMSK = (1<<OCIE2); 
      }
    
    ISR(TIMER2_COMP_vect) 
    {
    PORTB ^= (1<<PB0);
    }
    
    int main(void)
    {
    
    	DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2);		//Led und Summer als Ausgang
    	PORTD |= (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3);	//Pullup für Taster ein
    	PORTB |= (1<<PB2);							//Summer ausschalten
    
     TIMER2_interrupt_init();
    
      while(1) 
      { 
        if(!(PIND & (1<<PD0))) sei(); 
    
        if(!(PIND & (1<<PD1))) cli(); 
      } 	
    }
    Mit Taste1 aktiviert man den Timer, Taste 2 deaktiviert ihn. In der ISR wird eine Led invertiert. Ist der Timer aktiviert, blinkt die Led.

    Willst du den Timer jede Sekunde um 1 erhöhen oder soll der Timer so schnell wie möglich laufen und du errechnest dann die Zeit?

    MfG Hannes

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test