- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 7 von 7

Thema: TIMER1 CAPTURE INPUT

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86

    TIMER1 CAPTURE INPUT

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    ich habe jetzt schon X mal das Datenblatt vom Atmega644 durchgeblättert, und habe auch mein Programm im AVR studio Simuliert.

    Ich versuche den Caputre In Interrupt anszusprechen, ohne Erfolg.
    Wenn ich im AVR Modus PD6 (ICP) auf High setze passiert nichts, wenn ich aber PD4 auf High setze springt er zum Interrupt TIMER1_CAPT_vect.
    Wenn ich im Register per Mausklick das Flag ICF1 setze, springt er auch??
    Sollte ICF1 nicht mit dem PD6 verbunden sein??? Habe ich ein Register übersehen?

    Bitte helft mir


    Code:
    #include <avr/io.h>
    #define F_CPU 20000000
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #define TICIE 4
    
    // Umdrehung durch Hallsensor messen
    
    uint8_t softtimer = 0, LB =0, HB = 0,Spalte=0;
    double TIME=0, OLDTIME = 0, Overflow = 0;
    
    ISR(TIMER1_OVF_vect)   	   // Timer1 Überlauf
    { 
      softtimer++; 		   // zählen der Überläufe
    } 
    
    ISR(TIMER1_CAPT_vect)      //  Flanke an ICP pin
    { 
            // Variablendeklaration
      
      LB = ICR1L;         // low Byte zuerst, high Byte wird gepuffert
      HB = ICR1H;  
     
      TIME = (HB<<8)| LB;
     
    OCR2A = TIME/5;
    //TCNT1 =0;
    TCNT2 =0;
    if(Overflow)
      Spalte--;
      
    }
    
    
    
    SIGNAL (TIMER2_COMPA_vect)
    {Overflow = 0xFF;
      sei();
    if(Overflow)
     Spalte++;
    
     
     cli();
    Overflow = 0;
    }
    
    int main(void) {
      TCCR1A = 0; // kein PWM, kein INPUT bei OC1...
      TCCR1B |= (1<<ICES1); // reagiert bei steigender Flanke
      TCCR1B |= (1<<CS11) | (1<<CS10); // TAKT /64
      TIMSK1 |= (1<<ICIE1)| (1<<TOIE1);  // ICP steigende Flanke und overflow
      TIFR1  |= (1<<TOV1) | (1<<ICF1);
      
      TCCR2A |= (1<<WGM21);// CTC Modus: Wenn der Timer OCR2B erreicht löst er ein Interrupt aus und beginnt von 0
    //OCR2B = 0x02; // Gibt vergleichswert des TIMER 2 an
      TCCR2B  |= (1<<CS11) | (1<<CS10);
    // Compare Interrupt erlauben
      TIMSK2 |= (1<<OCIE2A);
      TIFR2  |= (1<<OCIE2A);  // Interrupt freischalten
    
     DDRC = 0xff;
     PORTC =0;
    
    long int Zahl =0;
    
    while(1){
      sei();
      Zahl = TIME;
    
      cli();
      PORTC = Zahl;
      sei();
    }
    return 0;
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    In einer ISR haben sei() und cli() nichts zu suchen. Das macht der Compiler selbst. (Ausser die damit verbundenen Auswirkungen sind beabsichtigt, was ich hier aber nicht glaub)

    Die Interrupts 1x in der main VOR der while(1) freigeben und gut is.
    Nicht ständig an und abschalten.
    #ifndef MfG
    #define MfG

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Ich habe das gemacht, dass der Timer 1 immer die höhere priorität hat, also auch wenn der Interrupt von Timer 2 ausgelöst hat soll immer noch Timer1 die höhere Priorität haben und eventuell einspringen.
    Komischerweise, wenn ich sei() und cli() in der while(1) lösche und ein sei() vor die while(1) setze, dann geht der Simulator einmal die while schleife durch und hängt von da an im Timer2 interrupt.

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das Sei / CLI in der einen ISR kann man tatsächlich so machen. Es dauert hier doch relativ lange bis der Interupt ein zweites mal auftritt. Generell sollte man damit aber vorsichtig sein, denn verschachtelte Interrupts sind Fehleranfällig, und man sollte es nur tun, wenn man genau weiss was man tut und es auch nötig ist. Lohnen tut es sich hier eigentlich nicht, die ISR ist auch so sehr schnell fertig.

    Die SEI / CLI Befehle in der While Schleife haben schon eine gewisse Berechtigung, wegen des Zugriffs auf die 16 Bit Variabel die in der ISR verändert wird. Das eine SEI sollte aber vor die Schleife, also nur das eine CLI-SEI paar in der Schleife. In diesem speziellen Fall ist es allerdings nicht nötig den Interrupt zu sperren - später werden (bis jetzt) ohnehin nur die unteren 8 Bits benutzt - das würde auch ohne das sperren des Interrupts gehen.

    Es fehlt noch einige Male ein Volatile bei der Variablen deklaration - so wird der Compiler vermutlich etwas zu viel optimieren, weil er nicht weiss das da Werte in einer ISR verändert werden.




    p.s.: Noch 2 Tipps:
    1) ähnlich wie beim AD- kann man auch auf die ICP Register als 16 Bit Wert zugreifen. Man kann also gleich Time = ICP1 schreiben.

    2) lokale Variabeln (hier HB und LB) für die ISR sollte man auch wirklich als soche deklarieren und keine globalen Variablen nutzen. Der Compiler kann dann besser optimieren, und außerhalb der ISR sind die Variabeln ohnehin nicht zu gebrauchen. Mit globalen Variabeln sollte man ohnehin sparsam sein.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Zitat Zitat von Besserwessi

    Es fehlt noch einige Male ein Volatile bei der Variablen deklaration - so wird der Compiler vermutlich etwas zu viel optimieren, weil er nicht weiss das da Werte in einer ISR verändert werden.

    p.s.: Noch 2 Tipps:
    1) ähnlich wie beim AD- kann man auch auf die ICP Register als 16 Bit Wert zugreifen. Man kann also gleich Time = ICP1 schreiben.
    Danke das wusste ich nicht

    Zitat Zitat von Besserwessi
    2) lokale Variabeln (hier HB und LB) für die ISR sollte man auch wirklich als soche deklarieren und keine globalen Variablen nutzen. Der Compiler kann dann besser optimieren, und außerhalb der ISR sind die Variabeln ohnehin nicht zu gebrauchen. Mit globalen Variabeln sollte man ohnehin sparsam sein.
    Wie deklariere ich Variablen für die ISR? Volatile benutzen?

    und ich habe noch eine Frage:
    Ich habe jetzt im Datenblatt nochmal alles durchgelesen bezüglich Timer2 CTC modus(der jetzt super funktioniert) und Timer1 Capture In modus. Aber einen Punkt finde ich nicht, wie verbinde ich den ICP Pin mit ICF flag? (Also wenn ICP(PD6) =high-> ICF = high-> Interrupt.

    Zitat Zitat von Datenblatt Atmega644 Seite: 133
    This flag is set when a capture event occurs on the ICP1 pin. When the Input Capture Register
    (ICR1) is set by the WGMn3:0 to be used as the TOP value, the ICF1 Flag is set when the
    counter reaches the TOP value.
    ICF1 is automatically cleared when the Input Capture Interrupt Vector is executed. Alternatively,
    ICF1 can be cleared by writing a logic one to its bit location.
    Genau das muss ich machen, aber ich habe keinen Plan wie????

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die lokalen Variablen in der ISR deklariert man gang normal (ohne Volatile), einfach innerhalt der ISR.

    Die globalen Variablen die in der ISR verändert werden, und im Hauptprogramm (oder ggf. auch in einer anderen ISR) ausgelsen werden müssen als Volatile gekennzeichnet werden. Ähnliches gilt auch für Variablen die in der ISR gelesen werden und im Haptprogramm verändert werden. Die Deklaration also etwa so:

    volatile unsigned int time ;


    Die "Verbindug" vom ICP Eingang zum Inputcaptureflag (ICF1) ist immer da, außer bei einigen PWM modi die das ICP Register für was anderes nutzen. Man kann noch im Resgister TCCR1B einstellen, welche Flanke benutzt wird, hier soll das wohl die Steigende werden. Daszu muß man ggf. noch den Interrupt zum Input capture freigeben, üblicherweise in TIMSK1.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    20.12.2009
    Beiträge
    86
    Ich habe jetzt im AVR-Studio den Controll von Simulator-> Atmega644 auf Simulator2-> Atmega644 umgestellt. Und jetzt funktionierts.

    2 Tage lang den Kopf zerprechen für so ein s*****....

    Danke für eure Hilfe

Berechtigungen

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

LiFePO4 Speicher Test