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

Thema: TTL-Signal am ATmega8

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78

    TTL-Signal am ATmega8

    Gute Tageszeit liebe Gemeinde,

    nach einer erfolgreichen Konstruktion eines Frequenzzählers, würde ich gern versuchen das Offset von einer Sekunde zu umgehen,
    indem ich bei bekannter uC-Frequenz die Impulsanzahl zwischen zwei steigenden Flanken messe. So die Theorie.
    Praktisch bin ich mir nicht sicher und wende mich deshalb an euch.

    Code:
    TCCR0 |= (1<<CS02) | (1<<CS01) | (1<<CS00);
    Diese Zeile bewirkt das Starten des Timer0 bei steigender Flanke am T0 Eingang. Beim Überlauf wird eine Zählvariable inkrementiert usw, die übliche Geschichte.

    Meine Frage wäre folgende: Ich starte zwar den Timer, aber wie soll ich ihm sagen, dass er auch bei der nächsten Flanke aufhören sollte?
    Denn so scheint mir das Ganze noch nicht vollständig zu sein

    Anbei die relevanten Codestellen:

    Ich bedanke mich im Voraus,
    Nik
    Code:
    ISR(TIMER0_OVF_vect) 
    {
    	z++;
    	TIFR = (1<<TOV0); //Beim Überlauf von Timer0 und dem anschließenden Interrupt erfolgt eine Zurücksetzung auf Null
    }
    
    int main(void)
    {
    	// Definition von Ein- und Ausgängen des uC Boards
    	DDRC = 0xFF;	// PORTC als Ausgang - über PORTC werden die jeweiligen Segmente einer 7-Seg. Anzeige gesteuert
    	DDRD = 0xEF;	// außer dem PD4 für den TTL-Pegel sind alle Pins als Ausgänge definiert
    	PORTC = 0b00000000;
    	
    	
    	TCCR0 |= (1<<CS02) | (1<<CS01) | (1<<CS00); //  Extern anliegendes Signal an T0, Interrupt bei steigender Flanke, Starten des Timer0
    
    	TIMSK |= (1<<TOIE0); // Aktiviere den Interrupt von Timer0 beim Überlauf
    	
    	
    	sei();										// Interruptbehandlung ein
    	
    
    	
    	while(1)	// unendliche Schleife
    	{
    	
    			zaehler0_aktuell = TCNT0; // der aktuelle Timer0 Wert wird in count kopiert
    			zaehler0_ovf = z;		// Anzahl der Überläufe wird in zaehler0_ovf kopiert
    			z= 0;
    			TCNT0 = 0;
    			
    			if ((zaehler0_ovf==0)&&(zaehler0_aktuell==0))
    				{
    					freq = 0;
    				}
    			else
    				{
    					// Die abschließende Summierung aller Anteile samt Kompensation von Abweichungen
    					freq = (uint16_t) (F_CPU/(0.5+((256.0*zaehler0_ovf + zaehler0_aktuell)*korrekturfaktor))); 
    				}
    			
    			zahl_ausgeben(freq);
    				
    	}
    return 0;
    }

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Gar nicht. Diese Betriebsart ist für den Betrieb mit einer externen Taktquelle, zum Zählen von Ereignissen oder zum Messen von Frequenzen mit niedriger Wiederholrate gedacht. Wenn du sehr schnelle Frequenzmessungen durchführen möchtest, hast du im wesentlichen zwei Möglichkeiten:
    1. Input Capture. Diese Funktion größerer Timer ist genau für den von dir genannten Zweck gedacht, sie erfasst die Zeit zwischen zwei Ereignissen.
    2. Manuelles Capture: Du pollst den Pin oder verwendest einen der Externen Interrupts um den Zeitstempel eines kontinuierlich laufenden (wie bei 1) Timers einzulesen.

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

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    16.04.2011
    Beiträge
    78
    Als Erstes vielen Dank für die Tipps markusj, eine Verständnisfrage hätte ich allerdings trotzdem. Den Code habe ich soweit auf den ICP1 abgestimmt (s.u.), doch verstehe ich nicht die Abfrage einzusetzen, wann denn
    nun die zweite Flanke eintraf.

    Code:
    TIMSK |= (1<<TICIE1);	// ICR1 aktiviert
    TCCR1B |= (1<<ICES1);	// Trigger bei steigender Flanke
    Der Codeausschnitt startet den Timer1 sobald eine steigende Flanke am ICR1-Pin eintrifft und ich kann wie gewöhnlich die Anzahl der Überläufe und aktuellen Zähler1-Stand kopieren und auswerten.
    Doch wann tritt die nächste Flanke ein?

    Code:
    if (ICF == 1) {};
    Das ist das Einzige, was ich als Option fand, doch steht in der Doku, dass das Bit bereits gesetzt ist, sobald das erste Ereignis,also die erste Flanke, stattfand.
    Ich hoffe, dass es verständlich war

    MfG Nik

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Gibt es einen speziellen Grund, warum du Interrupts vermeidest, Nik?

    Einfache Variante: Letzten Zählerstand in einer Variablen speichern, Interrupt anschalten und jedes Mal wenn der Input-Capture-Interrupt kommt, kannst du durch Neu-Alt die Periodendauer (in Zählerticks) ausrechnen.
    Umständliche Variante: Du pollst ICF (übrigens mit if (TIFR & (1 << ICF1), nicht mit deinem Codeschnipsel) und machst das was der Interrupt tun würde manuell. Und was das gesetzte Bit angeht:

    Zitat Zitat von ATMega8 Datasheet
    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.
    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

Ähnliche Themen

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

Berechtigungen

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

12V Akku bauen