www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik Timer ATtiny 13 Fehler im Code


Autor: Oliver Henrichsen (olli_henri)
Datum:
Angehängte Dateien:

Hallo,

Ich habe eine STK500, der Tiny läst sich ansprechen und programieren

nur leider funzt mein Code nicht.

Die LEDs blinken aber die LED an PB0 wird nicht durchgeschaltet auch
wenn S1 mehrmals gedrückt wurde.

Der TimerA/Counter ist auf Vergleich eingestellt und soll nach 5 mal S1
drücken T0A/PB0 durchschalten.

Die LED soll dann 0,5 sec brennen und dan zurückgesetzt werden.

Wo liegt der Fehler, kann mir einer freundlicherweise weiter helfen?

Gruß Olli
Autor: Stefan B. (Gast)
Datum:

Musst du Kulitinte sparen? Die Pins hättest du doch angeben können,
oder?

http://www.atmel.com/dyn/resources/prod_documents/...

Schalter ist active-high an PB2 (T0).
LEDs sind active-high an PB0, PB1 und PB4

>  PORTB |= (1 << PB3);  // LED an PB3 einschalten
>   if (PB0 == 1)        // wenn der Counter PB0 eingeschaltet hat

Passt nicht zu Schaltplan/Datenblatt
Autor: Stefan B. (Gast)
Datum:

>   if (PB0 == 1)        // wenn der Counter PB0 eingeschaltet hat

Ist auch unsinnig. Nach dem C-Präprozessor steht da: if (0 == 1). Da
sollte eine Warnung beim Kompilieren kommen.
Autor: Mark .. (mork)
Datum:

@Oliver
PB0 einfach nur als Zahl 0 definiert und nicht an einen Pin gebunden. Um
zu prüfen, ob ein Bit 1 ist, muss man diesen ausmaskieren und den
Ausdruck nach einem Wert ungleich 0 überprüfen.
 
if (PINB & (1<<PB0))        // wenn der Counter PB0 eingeschaltet hat
     // dann nach 500ms zur�cksetzen
{ 
    _delay_ms (500);    // 500 ms warten
    PORTB &= ~(1 << PB0);  // PB0 aus, ist OC0A
}
Siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

MfG Mark
Autor: Oliver Henrichsen (olli_henri)
Datum:
Angehängte Dateien:

Hier noch das Layout mit den zuordnungen der Pins beim ATtiny13.

Ich habe keine Warnungen.

Das erste Problem muß auch schon weiter oben liegen weil der
Timervergleich schon nicht funktioniert.

in der If Schleife wird ja nur das vom Timer gesetzet Bit am Ausgang
wieder gelöscht.

> if (PB0 == 1);

kann ich damit nicht auch den Zustand von PB0 abfragen und auswerten?

Gruß Olli
Autor: Stefan B. (Gast)
Datum:

>   TCCR0A |= (1 << CS00) | (1 << CS01) | (1 << CS02);

Falsches Register, müsste TCCR0B sein.
Autor: Stefan B. (Gast)
Datum:

Initialisierung von TCCR0A kommt mir auch Spanisch vor. Ich vermisse den
CTC Modus.
Autor: Stefan B. (Gast)
Datum:

> if (PB0 == 1);
> kann ich damit nicht auch den Zustand von PB0 abfragen und auswerten?

Abfragen kannst du nur die Register PORTB oder PINB, PB0 ist bloß ein
#define für die Pinnummer in diesen Registern.
Autor: Oliver Henrichsen (olli_henri)
Datum:

Warum soll ich TCCR0B nehmen? Sind A und B nicht gleichwertige 8-Bit
Timer?

Wenn ich mich für Timer A entscheide muss ich doch alle Register für A
benutzen?

  > OCR0A = 4;  // Vergleichswert (-1) einstellen, 5xTaster dr�cken

das dürfte doch richtig sein, im Output Compare Register eine vier
eintragen, dann wird beim darauffolgenden Takt der Signalzustand
geändert.

  > TCCR0A |= (1 << COM0A0) | (1 << COM0A1); // OC0A ein bei
Vergleichswert

Im Datenblatt steht das COM0A0 und COM0A1 auf 1 gesetzt im
Vergleichsmodus bedeutet.

  > TCCR0A |= (1 << CS00) | (1 << CS01) | (1 << CS02);
                    // Externe Clock an T0, steigende Flanke

CS00, CS01, CS02 auf 1 bedeutet steigende Flanke auswerten.

Was ist denn jetzt noch falsch bei der Ini des Timers?

Die If Bedingung habe ich jetzt so wie von Mark vorgeschagen geändert:

if (PINB & (1<<PB0))        // wenn der Counter PB0 eingeschaltet hat
     // dann nach 500ms zur�cksetzen
{
    _delay_ms (500);    // 500 ms warten
    PORTB &= ~(1 << PB0);  // PB0 aus, ist OC0A
}
Autor: Spezi (Gast)
Datum:

Hallo.

>Warum soll ich TCCR0B nehmen? Sind A und B nicht gleichwertige 8-Bit
>Timer?
>Wenn ich mich für Timer A entscheide muss ich doch alle Register für A
>benutzen?

Es gibt keine Timer A oder B; es gibt nur einen Timer0. Und die Register
TCCR0A und TCCR0B gehören beide zum Timer0 und haben verschiedene
Funktionen.

Was du meinst, sind die Compare-Einheiten mit Registern "OCR0A" und
"OCR0B" sowie den Ausgängen OC0A und OC0B. Das sind aber keine Timer ...
Autor: Oliver Henrichsen (olli_henri)
Datum:

Aha! ist denn die Ini des TCCR0A richtig? wo steckt der Fehler?
Autor: Stefan B. (Gast)
Datum:

> TCCR0A |= (1 << COM0A0) | (1 << COM0A1); // OC0A ein bei
> Vergleichswert
> Im Datenblatt steht das COM0A0 und COM0A1 auf 1 gesetzt im
> Vergleichsmodus bedeutet.

Richtig, das definiert die Aktion, die bei zutreffendem Vergleich
durchzuführen ist.

Du brauchst noch die Definition dafrü, was verglichen wird, also TCNT0
gegen OCR0A, damit dann die Aktion durchgeführt wird. Ich halte den
CTC-Modus für geeignet, den man mit dem WGM00, WGM01, WGM02 Bits
einstellen kann.

Leider scheint mein AVR Simulator hier buggy zu sein, so dass ich deine
Source nicht im Simulator nachvollziehen kann. Daher auch kein
Codevorschlag.
Autor: Oliver Henrichsen (olli_henri)
Datum:

Im Datenblatt steht dass der Timer/Counter 0 TCNT0 ständig mit den
Output Compare Registern OCR0A und OCR0B verglichen wird. Das muss ich
also nicht extra einstellen, der Vergleich findet automatisch statt.

Bei Übereinstimmung wird dann das Output Compare Flag OCF0A oder OCF0B
gesetzt. Falls der Interrupt aktiv ist wird dieser ausgelöst und das
Flag gelöscht, sonst muß es per Software gelöscht werden.

Da ich mit:

> TCCR0A |= (1 << CS00) | (1 << CS01) | (1 << CS02);
                    // Externe Clock an T0, steigende Flanke

eingestellt habe dass ein externes clock Signal mit steigender Fanke
ausgewertet werden soll muß doch eigentlich bei Übereinstimmung Pin5 =
PB0 = OC0A gesetzt werden?

Ohne an WGM00 oder WGM01 etwas einzustellen?
Autor: Oliver Henrichsen (olli_henri)
Datum:

Gleichzeitig soll doch nach dem Tutorial mit

TCCR0A |= (1 << CS00) | (1 << CS01) | (1 << CS02);

auch der Timer gestartet werden?
Autor: Oliver Henrichsen (olli_henri)
Datum:
Angehängte Dateien:

Gibts hier denn heute keinen der mir mit dem Timer weiter helfen kann
und den Fehler in meinem Code findet?

Hier nochmal der aktuelle Code....
Autor: Peter Dannegger (peda)
Datum:

Oliver Henrichsen schrieb:
> Der TimerA/Counter ist auf Vergleich eingestellt und soll nach 5 mal S1
> drücken T0A/PB0 durchschalten.

Das wird so nicht klappen, Tasten müssen entprellt werden.
Du solltest den Timer besser dazu nehmen, die Tasten zu entprellen und
die Flanke zu erkennen.
Und dann zählst Du einfach ganz profan die Drücke mit einer Variable.


Peter
Autor: Stefan Ernst (sternst)
Datum:

Oliver Henrichsen schrieb:
> Gibts hier denn heute keinen der mir mit dem Timer weiter helfen kann
> und den Fehler in meinem Code findet?

Ein Fehler wurde schon klipp und klar benannt. Aber trotz einer kleinen
Diskussion darüber, hast du dich anscheinend entschlossen, einfach zu
ignorieren, dass TCCR0A das falsche Register ist.
Autor: MWS (Gast)
Datum:

Ich denke, daß die Kollegen hier die Lust verlieren, da Du nur wild
rumbastelst, Deine Sachen nicht lernst und die Hinweise ignorierst.

Spezi hat Dir geschrieben, Du sollst TCCR0B nehmen, das ist Dir aber
egal. Dem µC dagegen nicht, denn Dein Code:
TCCR0A |= (1 << CS00) | (1 << CS01) | (1 << CS02);
passt nicht, denn CS00..02 stehen nun mal im TCCR0B.

OC0A kann bei Dir gar nix schalten, da er nicht als Output Compare
Ausgang definiert ist, das dagegen würde man über COM00..01 auf TCCR0A
einstellen.

Wenn man den OC0A eingeschaltet hat, dann kann man den Portpin nicht
mehr selbst setzen oder löschen, das steht z.B. im ATT13 DB, hier
2535I–AVR–05/08, S.70

Weiter, obwohl Du weist, daß ein Compare Match das OCF0A setzt,
übersiehst Du das dies hier in Verbindung mit CTC die Lösung wäre.

Hier ignorierst Du noch den Rat von Stefan eben den CTC Modus zu nutzen,
das würde dafür sorgen, daß der Zähler bei 4 zurücksetzt und Du nicht
256 mal den Taster drücken musst, um wieder eine Reaktion zu erhalten.

Wenn Du fragst, aber dann die Antworten ignorierst, brauchst Du Dich
über mangelndes Feedback nicht zu beschweren.

Also die Antwort auf Deine Frage: diejenigen die helfen können, gibt's
hier schon, nur irgendwann wollen die nicht mehr.
Autor: Oliver Henrichsen (olli_henri)
Datum:

Sorry und Danke,

Leider versteht man als Anfänger bzw. gelegenheits Bastler manche
Hinweise nicht gleich, insbesondere wenn sie zu knapp formuliert sind
und für jemanden der in der Materie steckt alles enthalten was man zur
Lösung eines Problems braucht. Ich habe die Hinweise nicht ignoriert
sondern versucht nachzulesen und zu verstehen. Als Anfänger
experimentiere ich nun mal...zwischen Steckboard, Buch und Datenblatt

Wie auch immer, jedenfalls hat mir die ausführliche Hilfe von MWS
weitergeholfen und ich habe die richtigen Register gefunden, jetzt
entprelle ich noch den Schalter mittels flipflop.
Autor: Stefan B. (Gast)
Datum:

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net