- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 28

Thema: TTL-Signal am ATmega8

  1. #11
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Anzeige

    Powerstation Test
    Guten Abend Markus - ersteinmal danke für die Rückmeldung.
    Zu den paar Dingern:
    1. Das war mir nicht völlig bewusst, deshalb mal nach dem Motto " vorsichthalber, man weiß ja nie" vorgegangen
    2. Eigentlich war mein Ziel den Ansatz zu vereinfachen - meine erste Version benötigt zwei Timer zur Zeitmessung und einen für Multiplexing. Damit hätte ich keine Timer mehr zur Verügung
    Diese Version funktioniert auch wirklich gut - benötigt wird der Ganzzahlenbereich von 1-9999 Hz. Wurde alles perfekt angezeigt. Verbessern wollte ich das wegen des Offsets von einer Sekunde, die mit einem Timer gemessen wurde, während mit dem anderen Timer Flanken registriert wurden.
    3. Du hast Recht, diese Optimierungen kommen nur nicht sofort in den Sinn, da braucht man die Erfahrung
    4. Da ich keine Nachkommastellen brauche, gehe ich von aus, dass es mit einem Zyklus geht. Wenn nicht, habe ich da diese Option des Noise Canceler gefunden...
    5. Falls eine lineare Abweichung aufgrund des Quarzes eintritt brauche ich da nur einen korrekturfaktor einzusetzen und nicht mit datentypen spielen - so der Gedanke

    Danke für die Tipps - die Sache mit überflüssigen Variablen werde ich so weit es geht zu klären versuchen.
    Anbei mein "Fortschritt" (mit noch nicht optimierten Variablen)

    MfG Nik

    Code:
    #define F_CPU 16000000 // uC läuft mit 16MHz
    
    #ifndef TRUE
    #define TRUE 1
    #define FALSE 0
    #endif
    
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    volatile unsigned short z=0;
    volatile unsigned short UpdateDisplay;   // Verzögerung
    volatile unsigned int  Startzeit = 0;   // ICR-Wert bei 1. steigender Flanke sichern
    volatile unsigned int  Endzeit = 0;     // ICR-Wert bei 2. steigenden Flanke sichern
    volatile unsigned int LowByte = 0;
    volatile unsigned int HighByte = 0;
    
    int zaehler1_ovf = 0;		// Anzahl der Überläufe des Timer1
    
    uint16_t freq = 0;
    unsigned long zaehlschritte = 0;
    
    
    ISR(TIMER1_OVF_vect) 
    {
    	z++;
    	//TIFR = (1<<TOV1); //Beim Überlauf von Timer1 und dem anschließenden Interrupt erfolgt eine Zurücksetzung auf Null
    }
    
    
    ISR(TIMER1_CAPT_vect)
    {
      static unsigned short ErsteFlanke = TRUE;
    
      if(UpdateDisplay)          // Das Display wurde mit den Ergebnissen der vorhergehenden
        {						 // Messung noch nicht aktualisiert. Die nächste Messung
    		return;				 // verzögern, bis die Start- und EndTime-Variablen wieder
    	}               		 // gefahrlos beschrieben werden können
    	
    	
    	LowByte = ICR1L;         // low Byte zuerst, high Byte wird gepuffert
    	HighByte = ICR1H;  
    	
    	// overflow verpasst, wenn ICR1H klein und wartender Overflow Interrupt
    	
    	if ((HighByte < 128) && (TIFR & (1<<TOV1)))
    		{   // wartenden timer overflow Interrupt vorziehen
    			++z;         
    			TIFR = (1<<TOV1);    // timer overflow int. löschen, da schon hier ausgeführt
    		}
    
      
      // Bei der ersten Flanke beginnt die Messung, es wird der momentane
      // Timer beim Input Capture als Startwert gesichert
      
      if(ErsteFlanke)
      {
        Startzeit = ICR1;
        z = 0;
        ErsteFlanke = FALSE;       // Nach der nächsten Flanke beginnt die Ausgabe
      }
      
      // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
      
      else
      {
        Endzeit = ICR1;
        UpdateDisplay = TRUE;      // Eine vollständige Messung. Sie kann ausgewertet werden
        ErsteFlanke = TRUE;        // Bei der nächsten Flanke beginnt der nächste Messzyklus
      }	
    
    }
    
    
    
    int main(void)
    {
    	// Definition von Ein- und Ausgängen des uC Boards
    	DDRB = 0xFE;	// Mit Ausnahme des ICP1-Pins alles als Ausgang
    	DDRC = 0xFF;	// PORTC als Ausgang - über PORTC werden die jeweiligen Segmente einer 7-Seg. Anzeige gesteuert
    	DDRD = 0xFF;	// PORTD als Ausgang
    	PORTC = 0b00000000;
    	
    	
    	TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture und Overflow
    	TCCR1B = (1<<ICES1)  | (1<<CS10); // Input Capture Edge, kein Prescaler
    	
    
    	sei();					// Interruptbehandlung ein
    	
    
    	
    	while(1)	// unendliche Schleife
    	{
    		 if(UpdateDisplay)		// Erst nach zweiter Flanke ausführen
    			{
    				zaehler1_ovf = z;		// Anzahl der Überläufe wird in zaehler1_ovf kopiert
    				z= 0;
    				
    				
    				zaehlschritte = (unsigned long)(0.5+(65536.0*zaehler1_ovf) + Endzeit - Startzeit);
    				
    			
    				if (zaehlschritte==0)
    					{
    						freq = 0;
    					}
    				else
    					{
    						// Die abschließende Summierung aller Anteile samt Kompensation von Abweichungen
    						freq = (uint16_t) (F_CPU/(zaehlschritte)); 
    					}
    			
    				zahl_ausgeben(freq);
    				
    				UpdateDisplay = FALSE;
    			}
    			
    			
    	}
    
    return 0;
    }
    EDIT: Wieso ich keinen Prescaler verwende? Der Gedanke war, dass je mehr Signale pro Zeiteinheit gemessen werden können, desto genauer auch die Anzeige sein wird.


    EDIT 2:

    Änderungen:
    Code:
    volatile unsigned long Zeitdifferenz = 0;   
    
    ISR(TIMER1_CAPT_vect)
    {
    	
      static unsigned short ErsteFlanke = TRUE;
      static unsigned long Startzeit = 0;     // Startzeit als static deklariert
    ...
     {
        Zeitdifferenz = ICR1 - Startzeit;    // Jetzt wird 
        UpdateDisplay = TRUE;      // Eine vollständige Messung. Sie kann ausgewertet werden
        ErsteFlanke = TRUE;        // Bei der nächsten Flanke beginnt der nächste Messzyklus
      }
    }
    ...
    int main(void)
    {
    ...
    
    zaehlschritte = (unsigned long)(0.5+(65536.0*zaehler1_ovf) + Zeitdifferenz);
    ...
    }
    Geändert von Liquidator (21.03.2013 um 20:57 Uhr)

  2. #12
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Auswertung der Zahl der Überläufe muss man schon in der ICP ISR machen. Im Hauptprogramm kann man da schon um 1 oder gar mehr zu hoch liegen.

    Bei 10 kHz als maximale Frequenz hat man nur 1600 Zyklen - das gibt mit nur einer Periode noch keine gute Auflösung. Das reicht noch nicht ganz für 1 Hz Auflösung. Für genaue Werte wäre es da schon gut die Zeit über mehr Perioden zu messen. Für 1 Hz Auflösung auch bei der oberen Frequenzgrenze sollten es schon wenigstens 10000 Timerschritte sein. Das macht auch nur eine Messzeit von etwa 1/1000 Sekunde als Minimum.

    Das Zusammenfügen der Zahlen geht wirklich einfacher mit ganzen Zahlen. Da braucht man keine Fließkommazahlen. Wenn man dann für die genaue Quarzfrequenz noch einen krummen Faktor rein bekommt, kann man das danach machen.

    Der Noise Cancler Modus dient zum Abfangen von ganz kurzen Glitches, also Störungen die 1-3 Zyklen lang sind, z.B. durch Reflexion in einem Kabel oder Überschwinger an der Eingangsstufe. Das wird in den meisten Fällen keinen Unterschied machen.

  3. #13
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Zitat Zitat von Liquidator Beitrag anzeigen
    EDIT: Wieso ich keinen Prescaler verwende? Der Gedanke war, dass je mehr Signale pro Zeiteinheit gemessen werden können, desto genauer auch die Anzeige sein wird.
    Du misst aber nicht Signale je Zeiteinheit sondern Zeiteinheiten (Ticks) je Signal/Ereignis.

    @Frequenzbereich: Das ist etwas unangenehm. Für niedrige Frequenzen brauchst du tatsächlich einen zusätzlichen Zähler, da du ja für 1 Hz die Ticks einer ganzen Sekunde zählen musst. Die 10kHz schöpfen den Wertebereich dagegen nicht Mal ansatzweise aus. Eine clevere/faule Lösung wäre eine Bereichsumschaltung die je nach Eingangssignal den günstigsten Prescaler wählt. Einfacher ist vermutlich die Erweiterung des Zählbereichs auf 32 Bit

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Jetzt wird's wirklich interessant

    Ich befürchte es auch, dass es bei kleineren Frequenzen nicht ausreichen wird. Nach dem Fertigstellen der ersten Version hatte ich bereits einen ähnlichen Gedanken wie eben Markus. Auch eine Bereichsumschaltung, aber nicht unter Verwendung des Vorteilers, sondern der zwei Modi - einmal der alten Version und der aktuellen.
    Die alte Version startet gleichzeitig zwei Timer, lässt einen genau eine Sekunde zählen und sichert sofort den Stand des zweiten Counters. Auf diese Weise wird die völlig richtige Frequenz gemessen - nur eben mit einem Offset von einer Sekunde.
    Und die eigentliche Idee ist jetzt - rauszufinden bis welcher Frequenz meine aktuelle Methode ungenau ist. Und den Bereich mit meiner alten Programmversion abdecken.

    @Markus: Da ich ja alle Überläufe in einer Zählvariable sichere, hoffe ich ohne 32 Bit-Erweiterungen auszukommen (wenigstens noch). Meine Sorge ist wirklich nur die Ungenauigkeit, die eintreffen könnte...

    @Besserwessi: Mit den Gleitkommazahlen steht noch die alte Version - die Überreste des Codes lassen sich ohne Probleme beseitigen
    Zu dem Noise Canceler habe ich mich wohl geirrt, da ich dachte, dass ich mit seiner Hilfe feststellen kann, dass die nächsten HIGH-Pegel identisch sind und man diesen Wert auch verwerten kann. (bzw. Mittelwert bilden)

    MfG Nik

    EDIT: Wenn ich es mir so recht überlege, reichen mir für beide Modi nicht die 3 Timer Also doch über mehrere Takte zu messen versuchen
    Geändert von Liquidator (21.03.2013 um 22:51 Uhr)

  5. #15
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Solange man nur 1 Periode vermisst, gibt es einen Punkt wo man mit dem vermessen einer Periode gleich gute Ergebnisse wie dem Zählen für 1 Sekunde bekommt. Das sollte bei etwa 4000 Hz liegen. Der Übergang zur "alten" Variante mit dem Zählen der Impulse in 1 Sekunde wird nur für hohe Frequenzen gebraucht, so ab etwa 200 kHz - dann wird es irgendwann zu schnell für das Auswerten der ICP Interrupts.

    Darunter ist die Methode der Wahl einfach mehr als eine Periode zu messen: also mit dem Messen der "Endzeit" so lange zu warten bis die gewünschte Mindestzeit und damit Auflösung erreicht ist, also z.B. 160000 Counts = 1/100 s oder auch einfach 3-10 Überläufe des Timers. In der Zeit zählt man einfach in Software die Pulse und misst dann die Endzeit und die Zahl der Perioden.

    Für eine besonders hohe Auflösung bei Signalen wie etwa der Netzfrequenz gibt es dann noch ein paar andere Tricks für weniger Störungen und mehr Auflösung.

  6. #16
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Ich sehe gerade nicht ganz wie ihr auf Probleme bei den 10kHz kommt? Die Zeitbasis ist bei T_CLK = F_CPU gleich 1/16 µs. Du misst also jede Periodendauer mit (um konservativ zu rechnen) 1/4µs Ungenauigkeit. Was dann 10kHz +-25Hz ergeben würde, und das sind nur die Rohwerte. Wenn du darüber einen Mittelwert bildest, werden die Ergebnisse ähnlich genau werden wie die Messung der Impulsanzahl.

    Ach ja, tatsächlich liegt der Fehler vermutlich eher bei +- 3,125Hz. Ich würde das Jammern auf höchstem Niveau nennen ...

    Und drei Timer? Nik, du kannst die Timer recyclen. Mit etwas Kreativität bleiben sogar noch Ressourcen für andere Programmteile frei ... (und die Timer 0 und 2 sowieso).

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Vielen Dank Besserwessi

    Wäre es zu fehleranfällig, wenn ich nach 3 Perioden (6 Flanken) die Endvariable (zaehlschritte) einfach durch drei teilen würde?
    Ein Problem hätte ich mit 1Hz - bei Messung von mehreren Perioden könnte ich >1sek warten oO

    Markus, solange ich kein totales Differential bilden muss, um die Ungenauigkeiten zu glätten...
    Bei geringen Frequenzen sind 3 Hz ziemlich viel - oder meintest du das nur auf den 10 KHz bezogen?
    3 Timer... Einen bräuchte ich für die genaue Sekunde, somit unberührbar, was Vergleichswert und Prescaler betrifft. (Timer2)
    Multiplex muss ich nicht sehr genau sein, daher kein CTC Mode benötigt (also Timer0)
    Timer1 wäre für die Taktanzahlen zuständig, da 16 Bit - müsste sowohl nach einer Sekunde als auch vom ICR abhängig funktionieren...
    Bisschen Kreativität erlangt man, wenn man sich im Stoff frei fühlt

    MfG Nik
    Geändert von Liquidator (21.03.2013 um 23:41 Uhr)

  8. #18
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Größte Unsicherheit hätte man schon bei der hohen Frequenz, also etwa +- 7 Hz bei 10 kHz, +-1 Hz bei 4 kHz oder +-0,1 Hz bei 400 Hz.

    Einfach nach 3 Periode durch 3 zu teilen geht. Das kommt auf das gleiche hinaus, als würde man 3 Periode hintereinander mitteln.
    Mit der ICP Funktion erkennt man aber immer nur Flanken der einen Polarität, also entweder H->L oder L -> H. Für 3 Perioden braucht man da nur 4 Flanken: eine erste und dann 3 weitere.

    Wie schon erkannt, sind aber fest immer 3 Periode keine gute Lösung für sehr niedrige Frequenzen.
    Bei dem großen Frequenzbereich muss die Zahl der Perioden nicht fest sein: bei sehr niedriger Frequenz (z.B. unter 100 Hz) reicht eine Periode, darüber nimmt man dann halt mehr Perioden, so das die Messzeit z.B. mindestens 1/100s beträgt. Das macht nur die Abfrage der "Endzeit" etwas komplizierter:
    - ist die Zeit seit dem Start unter etwa z.B. 10 ms zählt man die Periodenzahl hoch
    - ist die Zeit über 10 ms, hat man die "Endzeit" und ist fertig mit der Messung.
    Je nach Frequenz ist die Zahl der Perioden dann halt 1 (bei weniger als 100 Hz) oder auch mal 100 bei 10 kHz.

    Zu den Timern: den Timer für die genaue Sekunde könnte man z.B. auch für das Multiplexing nutzen. alternativ gibt es für weniger hohe Anforderungen auch noch eine Timing über z.B. USI, den Watchdogtimer, oder den Ad Wandler. Außerdem gibt es für einen nicht genutzten Timer kein Geld zurück.

  9. #19
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Damit kann ich leben

    Dann werde ich das nun wie geplant basteln und mal berichten, wie gut die Messung war. Ein Paar Tücken sind vorhanden - beispielsweise eben dieses gleichzeitiges Auslösen von Ereignissen verschiedener Prioritäten...
    Man lernt auf alle Fälle ordentlich dazu. Wie kann man eigentlich den 1-Sekunde-Vergleichstimer für Multiplexing nutzen, ohne Vergleichswert oder Prescaler zu ändern?

    MfG Nik

  10. #20
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn man das Multiplexing über einen Timer im CTC Mode macht, kann man den Timer auch für das 1 s Signal nutzen. Es muss nur der Takt des Timers eine genau passende Frequenz (z.B.100 Hz) haben. Die genaue Sekunde ergibt sich dann als die Zeit für 100 der Interrupts. Das Problem mit einer kleinen Unsicherheit durch die Laufzeit bis der Timer aktiviert oder gestoppt wird hat man ja in fast jedem Fall, es ist aber auch ohne ASM weitgehend lösbar, wenn auch nicht so einfach.

    Das größere Problem ist eher, wenn noch andere Interrupts aktiv sind, denn die können eine schwer zu berechnende Verzögerung bringen. Von daher ist es sogar ein Vorteil, wenn man so etwas wie das Multiplexing nicht mit einem anderen Interrupts macht.

    Mit dem Zählen der ICP Ereignisse erübrigt sich die Methode mit der festen 1 s Torzeit aber ohnehin weitgehend, bis zu einer Frequenz von etwa 200 kHz.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Ähnliche Themen

  1. TTL Signal Verarbeitung
    Von GDIViperM im Forum Elektronik
    Antworten: 14
    Letzter Beitrag: 03.05.2011, 10:29
  2. TTL-Signal auswerten
    Von mudi007 im Forum Elektronik
    Antworten: 10
    Letzter Beitrag: 05.05.2009, 22:52
  3. Drehzahl signal in TTL umwandeln
    Von EISMAN im Forum Elektronik
    Antworten: 6
    Letzter Beitrag: 19.10.2006, 11:35
  4. TTL-Signal Umschalter
    Von noxon im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 24.03.2006, 09:19
  5. 230V in TTL Signal umwandeln ( IC?)
    Von Lektor im Forum Elektronik
    Antworten: 26
    Letzter Beitrag: 19.11.2005, 12:55

Berechtigungen

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

12V Akku bauen