-
        

Ergebnis 1 bis 10 von 10

Thema: Timer2 init am Mega644 klappt einfach nicht

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    07.03.2013
    Ort
    Berlin
    Alter
    37
    Beiträge
    6

    Timer2 init am Mega644 klappt einfach nicht

    Anzeige

    Hallo alle zusammen,

    schön dass es dieses Forum gibt. Also schnell angemeldet und mal Hallo an alle gesagt. Ich bin ja neu hier und hoffe auf Euren großen Erfahrungsschatz. Ich selbst scheine an sowas wie Betriebsblindheit zu leiden
    Folgendes ist mein Vorhaben:

    Ich benötige für eine Fahrradlampen Schaltung ein PWM Signal um eine LED zu dimmen. Gleichzeitig möchte über den selben Timer den Kontrast für ein LCD einstellen können. Ist ja an und für sich kein Problem. Timer2 hat zwei Compare Register (OCR2A&B), die an OC2x ausgegeben werden können. Eigentlich bin ich auch recht fit im Umgang mit Timern. Timer0 und 1 laufen in demselben Programm ja einwandfrei. Allerdings nicht als PWM. Der eine liefert eine Zeitreferenz, der andere wertet Dynamo-Impulse aus. Schön über ISR's und läuft. Aber das führt vorerst zu weit. Beim initialisieren vom Timer2 komme ich allerdings ins Straucheln. Kann einer von Euch mal eben über den Code schauen und mir sagen wo sich der Fehlerteufel eingeschlichen hat?
    Code:
    	TCCR2A |= (1<<COM2A0) | (1<<COM2A1);	// Setze OC2A bei Compare, reset@bottom, inverted Mode
    	TCCR2A |= (1<<COM2B1); 				// Lösche OC2B bei Compare, set@bottom
    	TCCR2A |= (1<<WGM20) | (1<<WGM21);		// WaveFormGenerator --> fast PWM Mode
    	OCR2A = 128;
    	DDRD   |= (1<<PD6) | (1<<PD7);			// PD6&7 als Ausgang um PWM-Signal sichtbar zu machen
    	TCCR2B |= (1<<CS22);					// Prescaler auf 64 (PWM-Freq=1,125kHz) und start Counter2
    OCR2B wird später gesetzt und ist bei Start=0. Am OCR2B soll also erstmal ein High-Signal anliegen, das ich mit nem Oszi mal eben darstellen wollte. Nix da. ich bekomme weder an OC2A noch an OC2B ein Signal. Kein High, kein PWM. An OC2A liegt evtl. sowas wie ein rauschen (+-0.2V) an??? Wenn ich OCR2A=128 setze sollte ich ja eher ein "50% Signal" meiner Grundfrequenz erhalten, also ca 562Hz, oder?
    Hab ich das Datenblatt richtig verstanden, dass ein Update der OCR2x erst bei Bottom stattfindet? Ich kann demzufolge also in der Main die Compare-Register ändern und muss das nicht über ISR machen? Vielen Dank für Eure Hilfe und genießt die sich langsam zeigende Sonne!!!

    Grüße
    Eddy
    Hab ich irgendwas vergessen beim init? Ich hofffe mein Problem ist klar geworden. Wenn nicht liefer ich natürlich (Code-)nachschub.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Zitat Zitat von ad°FX Beitrag anzeigen
    Hab ich das Datenblatt richtig verstanden, dass ein Update der OCR2x erst bei Bottom stattfindet? Ich kann demzufolge also in der Main die Compare-Register ändern und muss das nicht über ISR machen?
    Richtig, die sind gepuffert.

    Zu deinem Problem: Ich finde keinen Fehler im Code, im Simulator (AVR Simulator 2, der andere setzt beim Timer keine Pins) funktioniert er problemlos.
    Ach ja, ein Systemtakt von 72kHz ist sehr wenig ...

    Testcode:
    PHP-Code:
    #include <avr/io.h>

    int main(void) {
        
    TCCR2A |= (1<<COM2A0) | (1<<COM2A1);    // Setze OC2A bei Compare, reset@bottom, inverted Mode
        
    TCCR2A |= (1<<COM2B1);                 // Lösche OC2B bei Compare, set@bottom
        
    TCCR2A |= (1<<WGM20) | (1<<WGM21);        // WaveFormGenerator --> fast PWM Mode
        
    OCR2A 128;
        
    DDRD   |= (1<<PD6) | (1<<PD7);            // PD6&7 als Ausgang um PWM-Signal sichtbar zu machen
        
    TCCR2B |= (1<<CS22);                    // Prescaler auf 64 (PWM-Freq=1,125kHz) und start Counter2

        
    char last PIND;
        for(;;) {
            
    char in PIND;

            if (
    last != in) {
                
    last in;
                
    GPIOR0 last// set breakpoint here
            
    }
        }

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

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    07.03.2013
    Ort
    Berlin
    Alter
    37
    Beiträge
    6
    Vielen Dank für die schnelle Antwort. So was ähnliches hatte ich ja befürchtet. Bei den zwei Registern kann man ja auch eigentlich nicht viel falsch machen...

    @Markus: wie kommst du auf 72kHz? Der Mega rennt mit 18,432Mhz und der PWM soll mit 1,125kHz laufen.

    Also tiefer ins Detail: Am PortD wo die OC2A&B Pin's sitzen habe ich noch den INT0 beschaltet. Der zündet den INT0_vect:
    Code:
    ISR( INT0_vect )					// Int2 liest DynamoImpulse ein
    {
    
    	if (ImpulsCheck == 0)				// kein DynamoImpuls vorweg
    	{
    		TCCR1B |= (1<<CS12) | (1<<CS10);	// Prescaler für Timer1 auf 1024 setzen,
    									// dadurch 'füllt' sich TCNT1 mit 18kHz bei 18,432Mhz Fcpu
    		ImpulsCheck=1;
    	}
    	else								// DynamoImpuls vorher kam, also Timer auswerten für Frequenzmessung
    	{
    		Timer1Register = TCNT1;			// Übergabe des Timer1 Registers an globale Var zur Verrechnung in main
    		TCNT1=1;						// Register Nullen um Messung neu zu beginnen
    	}
    	Impulse++;							// Impulse um eins erhöhen um DynamoImpulse zu zählen, daraus Strecke
    }
    Hier wird aber meiner Meinung nach nichts am PortD geändert was die beiden OC2A&B "verwirren" könnte.

    An die Variable ImpulsCheck ist eine (andere) LED gekoppelt, die bei ImpulsCheck=1 an ist, sonst eben aus. Eine einfache visuelle Kontrolle für mich:
    Code:
    	if (ImpulsCheck == 1)
    	{
    		PORTD= (1<<PD3);
    	}
    	else
    	{
    		PORTD &= ~(1<<PD3);
    	}
    So das war's was ich an PortD veranstalte. Vllt ist hier ja was bei, was den Timer nicht starten lässt. Ich komme dem Problem einfach nicht auf die Schliche
    Vielen Dank für Eure Hilfe

    MfG
    Eddy

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    ... Ich komme dem Problem einfach nicht auf die Schliche ...
    Muss für den Timerstart nicht irgendwann der Timerinterrupt enabled werden ( TIMSK2 |= (1<<OCIE2A) ...) ? Die dümmste Frage will ich ja eigentlich nicht stellen: sind Interrupts global erlaubt ( sei(); ). Nix für ungut.
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Zitat Zitat von ad°FX Beitrag anzeigen
    @Markus: wie kommst du auf 72kHz? Der Mega rennt mit 18,432Mhz und der PWM soll mit 1,125kHz laufen.
    Rechenfehler meinerseits. Ich hatte nur 1,125kHz * 64 gerechnet und den Faktor von 2^8 Bit vergessen.

    Zitat Zitat von ad°FX Beitrag anzeigen
    Code:
    	if (ImpulsCheck == 1)
    	{
    		PORTD= (1<<PD3); // !!! Überschreibt PORTD komplett
    	}
    	else
    	{
    		PORTD &= ~(1<<PD3);
    	}
    Ich glaube da haben wir den Schuldigen. Du bügelst einen eigenen Wert über das vom Timer erzeugte Signal. "|=" wäre wohl eher das Mittel der Wahl.
    Edit: Der Zugriff auf PORTD kannn nicht schuld sein, der Timer hat Vorrang. Entweder du misst falsch oder der Fehler liegt an anderer Stelle.

    Zitat Zitat von oberallgeier Beitrag anzeigen
    Muss für den Timerstart nicht irgendwann der Timerinterrupt enabled werden
    Nein, der Timer läuft auch ohne Interrupts. Die sind nur Bonusprogramm.

    mfG
    Markus
    Geändert von markusj (07.03.2013 um 14:22 Uhr) Grund: Korrektur
    Tiny ASURO Library: Thread und sf.net Seite

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    07.03.2013
    Ort
    Berlin
    Alter
    37
    Beiträge
    6
    Jip und danke Markus, hab's noch nicht getestet, aber mit sowas hatte ich fast gerechnet. Ganz klarer Fall von ODER vergessen. Daher nämlich auch das Rauschen auf PD7. Ich teste das mal eben!!!

    EDIT: Hast Recht. Das war's nicht.

    Was meinst du mit falsch messen? Oszi? Ist auszuschließen. Ich kann mir die Pegel am TWI wunderbar anschauen.

    - - - Aktualisiert - - -

    Folgendes: ich habe die "Test" LED mal spaßenshalber angehen lassen wenn das OCR2x == 128 ist. funktioniert, d.h. das Compare-Register wird in seinem Zustand verändert. Dann dachte ich mir die Test LED als abfrage für TCNT2 zu benutzen a la:
    Code:
    	if (TCNT2 == 128 )
    	{
    		PORTD |= (1<<PD3);
    	}
    	else
    	{
    		PORTD &= ~(1<<PD3);
    	}
    Die LED sollt ja dann erwartungsgemäß gleichmäßig blinken. Tut sie aber nicht. Leider blinkt die LED auch ohne jegliches Muster das man irgendeiner funktion zu ordnen kann. Auf jedenfall ist der Fehler schonmal eingegrenzt. Aus irgendwelchen Gründen läuft der Timer bzw das Register TCNT2 nicht sauber hoch. Hat vllt einer von Euch eine Idee woran das liegen kann?

    Vielen Dank für Eure Hilfe.
    MfG
    Eddy
    Geändert von ad°FX (07.03.2013 um 14:25 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Ich kann auch keinen Fehler in der Timerkonfiguration feststellen.
    Markus hat sein Testprogramm gepostet. Hast du genau das mal laufen lassen?
    Gibt es eine äußere Beschaltung von PD6, PD7?

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

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    07.03.2013
    Ort
    Berlin
    Alter
    37
    Beiträge
    6
    Guten Abend zusammen und vielen Dank für Eure schnellen Antworten und Lösungsvorschläge.

    Ich habe den Code von Markus mal in ein neues Projekt kopiert und der läuft so geschrieben einwandfrei. Habe also auf dem Oszi genau den 50% Cycle auf OC2A und 0V auf OC2B. So soll es ja auch vorerst sein.
    Um Searchers Frage vorweg zu beantworten PD6&7 sind im Moment nicht beschaltet. Findet alles auf nem Test-Board statt. Daran liegt es wohl leider auch nicht, da der Code in einem seperaten Programm ja läuft.
    Das heißt für mich allerdings Sysiphos arbeit, da sich ganz offensichtlich irgendetwas mit dem schon bestehenden Programm beißt. Ich werde also mal alle PortD betreffenden Code Segmente prüfen (müssen) und halte Euch auf dem laufenden. Falls ich nichts finde muss ich noch mal auf Eure Hilfe zurückgreifen und evtl. das ganze Programm posten. Das wird dann wohl etwas umfangreicher. Aber ich habe ja noch ein paar Ansatzmöglichkeiten. Bis dahin wünsche ich Euch einen schönen Abend.

    Gruß
    Eddy

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Zitat Zitat von ad°FX Beitrag anzeigen
    Die LED sollt ja dann erwartungsgemäß gleichmäßig blinken. Tut sie aber nicht. Leider blinkt die LED auch ohne jegliches Muster das man irgendeiner funktion zu ordnen kann. Auf jedenfall ist der Fehler schonmal eingegrenzt. Aus irgendwelchen Gründen läuft der Timer bzw das Register TCNT2 nicht sauber hoch. Hat vllt einer von Euch eine Idee woran das liegen kann?
    Sollte sie nur genau dann, wenn die Aufruffrequenz des Codeschnipsels hoch genug ist. Ein Vergleich >= 128 wäre zuverlässiger.

    Ggf. ist es langsam Mal an der Zeit, den ganzen Code zu zeigen.

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

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    07.03.2013
    Ort
    Berlin
    Alter
    37
    Beiträge
    6
    Das mit der LED ist tatsächlich immernoch nicht so wie ich mir das dachte. Macht aber nix, WEIL: ich habe den Fehler gefunden. "Schuld" (bin natürlich ich) ist die Test-LED. Ich habe mal wieder ein ODER in der Zuweisung des PORTD vergessen, so dass als letzte Zuweisung
    Code:
    DDRD = 1<<PD3;
    stand. Das hat natürlich zur Folge das PD6&7 nicht mehr als Ausgang definiert sind und somit das Signal am Ausgang nicht sichtbar ist. Es muss natürlich
    Code:
    DDRD |= 1<<PD3;
    heißen und siehe da alles läuft einwandfrei. Man man man ist mir ja peinlich. Werde mir n großes Plakat an die Wand tackern und das mit "|" voll malen

    Vielen Dank für Eure Hilfe. Ich glaube nicht dass ich von alleine so schnell zur Lösung gelangt wäre. Dieser Fred kann als gelöst angesehen werden.

    Grüße aus Berlin
    Eddy

Ähnliche Themen

  1. Antworten: 5
    Letzter Beitrag: 25.02.2014, 13:37
  2. SD-Karte: Init + FAT-Infos geht, Sektoren auslesen nicht.
    Von Jaecko im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 30.07.2008, 20:42
  3. Displaytech 161A, beim Init geht das Display nicht aus.
    Von Sonic111 im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 1
    Letzter Beitrag: 04.11.2007, 16:53
  4. PWM funktioniert nicht in Verbindung mit Timer2
    Von IE04 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 12
    Letzter Beitrag: 02.11.2006, 21:01
  5. Timer2 overflow Interrupt will nicht
    Von BomberD im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 30.01.2006, 17:37

Berechtigungen

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