- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 19 von 19

Thema: TIMER,Interrupts und Pulse zählen

  1. #11
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.04.2010
    Beiträge
    1.249
    Anzeige

    Powerstation Test
    das habe ich mitten in die Main gepflanzt und habe gehofft das nun n von jeder Stelle im Programm gelesen werden könnte!
    Tja, und das ist absoluter Murks.
    Ja du hoffst...

    Vielleicht könnt ihr mir ja mal etwas tatkräftiger unter die Arme greifen anstatt dauernd auf die Tutorials zu verweisen!!!Das hilft mir auch nicht allzusehr weiter!
    Sag doch einfach das es jemand für dich machen soll.
    Es ist in den Tutorials so schön beschrieben... aber da du scheinbar keinerlei Grundkenntnisse hast, kann ich dir nur raten dir diese anzueignen.

    Und beklagt dich nicht über mangelnde Hilfe, solange von dir nur irgendein zusammengestückelter Code kommt, den du selbst nicht im Ansatz verstehst.

    Man lernt das ganze nicht in 2 Tagen.

  2. #12
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Werde mal probieren ob ich was zusammen bringe
    Code:
    #define Timer_1_wert 0xd800
    TIMSK=(1<<OCIE1A)|(1<<TOIE0);	/* timer0 für Messtart,timer1 für F-Messung aktiv */
    OCR1A=Timer_1_wert;
    
    TCCR1B=0;
    TCNT0=0;
    TCCR0=(1<<CS01)|(1<<CS02); /*Clock von T0 falling edge*/
    TCCR1B=(1<<CS10)|(1<<WGM12);
    Das #define kommt an den Anfang, der Rest ins main. Dann noch ISR
    Code:
    ISR(TIMER1_COMPA_vect){		/*Takt  Sek*/
    Timer_1z ++;
    }
    ISR(TIMER0_OVF_vect){		/*Überlauf timer 0*/
    Timer_0z++;
    und ins main weiter dann die Auswertung
    Code:
    for(;;){
    	if(Timer_1z>=200){	/*torzeit 1 Sekunde */
    	TCCR0=0;
    	TCCR1B=0;
    	Timer_1z=0;
    	T0_wert=(Timer_0z*256+TCNT0);/* Anzahl der Überläufe * 256 + Zählerstand */
    	TCNT0=0;
    	Timer_0z=0;
    	TCNT1=0;
    Die Deklaration der Variblen fehlt noch, Taktfrequenz ist 11,0592MHz
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #13
    Neuer Benutzer Öfters hier
    Registriert seit
    10.02.2011
    Beiträge
    26
    Moin!

    Folgendes habe ich bis jetzt erarbeitet aber es klappt immer noch nicht!
    .....


    int drehzahl_mot(void)
    {
    int n = 0;

    OCR1AH = 0x30; //TIMER1:COMPARE REGISTER HIGH-BIT
    OCR1AL = 0xd4; //TIMER1:COMPARE REGISTER LOW-BIT (COMPARE-WERT 12500 = 0,8 sec. bei 16 Mhz

    TCCR1A = 0x00; //TIMER1:CONTROL REGISTER, Output-Pin nicht aktiv, Normaler Timerbetrieb

    TCCR1B = 0x05; //TIMER1:Prescale 1024,START
    TCCR0 = 0x07; //Counter0, zählen

    do
    {

    n = TCNT0;

    }
    while(TIFR & (1<<OCF1A)); //!!!Und das funktioniert nicht ich weiß nicht wie ich das Register /speziell das FLAG- Bit abfrage???

    TCCR1B = 0x00; //TIMER1:STOP
    TCCR0 = 0x00; //TIMER0:STOP

    TCNT1H = 0x00;
    TCNT1L = 0x00;
    TCNT0 = 0x00;

    TIFR |= (1<<OCF1A); //Flag löschen


    return n;

    }

    Ich habe mir echt Mühe gegeben und ich hoffe es sieht nicht wieder so gestückelt aus!Habe es auch mit ISR probiert in den verschiedensten Versionen aber ich möchte es erstmal ohne machen damit es nicht zu kompliziert wird!

    Nochmal die Funktion:
    ATMEGA 32 16PU/16Mhz--> An PortB0 Rechteckimpulse zählen (TIMER0) für ca. 0.8 sec. (TIMER1)

    Vielen Dank nochmal für eure Hilfe wollte euch wirklich nicht verärgern!!!

    Viele Grüße Stephan

  4. #14
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    41
    Beiträge
    1.780
    while(TIFR & (1<<OCF1A)); //!!!Und das funktioniert nicht ich weiß nicht wie ich das Register /speziell das FLAG- Bit abfrage???
    Die Abfrage an sich sollte korrekt sein, und falls du das #include <avr/io.h> nicht vergessen hast sollte der Compiler nicht meckern...


    Aber was passieren könnte ist, daß er die Schleife komplett wegoptimiert weil er denkt "Da drin passiert nichts, also brauche ich das auch nicht kompilieren". Wenn das der Fall ist, könntest du dein Programm so anpassen:

    Code:
    while(TIFR & (1<<OCF1A))
       asm volatile("nop;");
    Dann denkt der Compiler es gäbe etwas wahnsinnig Wichtiges in der Schleife von dem er aber nichts weiß.


    PS.: Code ist hier im Forum besser lesbar, wenn du Code-Tags benutzt (also so: [code]Hier kommt dein Code rein[/code])

    edit:
    wo wir gerade bei besser lesbar sind... das do{ habe ich komplett übersehen.
    In diesem Fall könnte es helfen n als volatile zu deklarieren (aber auch so wie der Code jetzt ist dürfte der Compiler eigentlich nichts wegoptimieren)
    So viele Treppen und so wenig Zeit!

  5. #15
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Code:
    do
    {
        n = TCNT0;
    }
    while(TIFR & (1<<OCF1A)); //!!!Und das funktioniert nicht ich weiß nicht wie ich das Register /speziell das FLAG- Bit abfrage???
    Die Schleife soll doch sicher laufen, bis das Flag gesetzt ist, und nicht so lange es gestzt ist, oder? Und warum ist das Lesen des Zählers in der Schleife?
    Ich würde es eher so machen:
    Code:
    while(!(TIFR & (1<<OCF1A)));  // Warten, bis Zeitfenster abgelaufen
    n = TCNT0;                    // dann Ergebnis auslesen
    MfG
    Stefan

  6. #16
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.191
    Ich denk mal, Du hast ein grundsätzliches Problem im Verstehen der Interrupts.
    Ein Interrupt ist ein Programmteil, der Durch ein Hardware- ( manchmal auch Software- ) Ereignis ausgelöst wird.
    Der gerade laufende Programmabschnitt wird verlassen und die zu dem Interrupt gehörige Interruptroutine aufgerufen.
    Das verlassene Programm kriegt von dieser Aktion üblicherweise nichts mit!

    Ich würde dein Problem wie folgt angehen.

    1. Ein Timer wird auf externe Taktquelle umgeschaltet und der Overflowe Interrupt dieses Timers aktiviert.
    In diesem Overflow Interrupt wird dann eine Hilfsvariable hochgezählt, damit man auch über den Zählerstand des verwendeten Timers hinauszählen kann.

    2. Ein weiterer Timer wird so eingestellt, das alle 500ms ein Interrupt ausgelöst wird.
    Das geht am schönsten mit dem Comparematch Interupt und einem Timer der im CTC Modus läuft.
    Tritt dann dieser Interrupt nun auf wird der Zählerstand des "Zähler" Timers und der Hilfsvariable Ausgelesen und miteinander verrechnet.
    Die Werte werden dann in einer beliebigen Variable gespeichert und ein Flag ( Bit Variable ) als Marker füe die Hauptroutine gesetzt.
    Nun wird noch der TCNTx der Zähl Timers und die dazugehörige Hilfsvariable auf 0 gesetzt.

    3. In der Hauptschleife wird das Bit Flag abgefragt und wenn es auf 1 steht der Zählerstand aus der Hilfsvariable abgeholt.
    Das Bit Flag wird wieder auf 0 gesetzt, damit dieser Programmteil nur bei neuen Werten wieder durchgeführt wird. Voila - Fertig!

  7. #17
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo,

    ich hab meine Impulse folgendermaßen mit Pin Change Interrupt gezählt:

    Einfach den PCINT auf dem Port zulassen, an dem der Rechteckimpuls anliegt.
    Einen Timer auf Torzeit einstellen, so das er dann zB. alle 500ms einen Overflow Interrupt erzeugt.
    In der Interruproutine zum PCINT einfach eine Variable hochzählen (Bei jeden Ansprung eins addieren).
    In der Timerinterruptroutine die PCINT Variable zur weiteren Verwendung im Hauptprogramm auslesen und zurücksetzen.

    PCINT kann auf bestimmten PINs so konfiguriert werden, daß er nur bei einer Flanke ausgelöst wird. Sonst ausgelesenen Wert durch 2 teilen.

    EDIT: Zugegebenermaßen wird der Prozessor durch die vielen PCINTs belastet, aber wenn er sonst nicht viel zu tun hat...

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  8. #18
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.191
    Die Methode von searcher funktioniert auch, allerdings wird dabei bei jedem Taktipuls ein Interrupt ausgelöst.
    Man könnte das ebenso mit INT0, INT1 oder auch ICP machen.

    Die Methode mit dem Timer belastet den Controller nicht so stark, da ja nur bei jedem 256 bzw 65536 Eingangsimpuls ( je nach verwendetem Timer ) ein Interrupt ausgelöst wird.

    Es kommt auf die maximal zu erwartende Pulsanzahl / sek an, welche Methode man verwendet.

  9. #19
    Neuer Benutzer Öfters hier
    Registriert seit
    10.02.2011
    Beiträge
    26
    Endlich geschafft!!
    Moin zusammen, habe alles gelöscht und einfach den Timer 0 zum zählen aktiviert und nach einer wait(200ms) funktion dann den Timer/Counter ausgelesen und TCNT0 wieder gelöscht!Zum Schluß noch Ausgabe des Zählstandes und ich hatte das was ich brauchte!

    Ich habe es einfach nicht geschafft Overflows zu zählen oder mit den Flags die Do While Schleife zu bezwingen, interrupts einzubinden... !Aber ich habe echt viel gelernt und denke das ich darauf aufbauen kann!

    Ich glaube ich muß noch ein wenig üben bevor ich TImer und Interrupts in meine Projekte einbeziehe!

    Ich möchte mich an dieser Stelle bei euch allen bedanken und hoffe das ich vielleicht auch irgendwann mal Tipps geben kann!

    Hier der Code:

    Code:
    int drehzahl_Mot(void)                     
    {
    int n = 0;
    
    TCCR0   = 0x07;        //Counter0, zählen
    
    wait_ms(300);
    
    n = TCNT0;
    
    TCCR0  = 0x00;        //TIMER0:STOP
    TCNT0 = 0;            //TIMER0: DATA REGISTER = 0
    
    n = ((n * (1000/5) * 1 *2));    //1000/300*60 == 1000/5*1
    
    return n ;
    }

    Bis dahin alles Gute und viele Grüße Stephan

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad