Forum: Mikrocontroller und Digitale Elektronik Timer Problem


von Björn (Gast)


Angehängte Dateien:

Lesenswert?

Tag,

hab ein Signal gebastelt für den Atmega88 in C.

http://www.mikrocontroller.net/forum/read-1-381874.html#new

Dieses Signal besitzt einen dauerhaften Highpegel mit 9 unterschiedlich
langen Lowpegel Impulsen.

Die Lowpegel Impulse varieren zwischen 10 und 20µs. Zwischen diesen
Lowpegelimpulsen besitzt der Highpegelimpuls eine Länge von 160µs.
Nach diesem Signal kommt eine Pause von ca. 60ms bevor das Signal
wieder von vorn beginnt.

Das Signal wird mit einem Timer und dem Compare Interrupt erzeugt.
Dabei wird die entsprechende Länge des Impulses als Wert in ein Array
geschrieben, der OCRxA auf diesen Wert gesetzt und bei jedem Interrupt
der neue Wert übergeben. So enstehen die verschiedenen Impulslängen.
(Siehe Anhang und noch mal vielen Dank an Karl Heinz Buchegger für die
Hilfe)

Nun geht es darum, dass ich bei einem empfangenen Zeichen über UART
neue Werte ins Array schreiben will. Das klappt auch! Aber nur solange
die Werte für die hinteren Lowimpulse größer sind als der erste Wert
für den ersten Lowimpuls. Nur dann bekomm ich ein sauberes und
richtiges Signal.

Sobald irgendein mittlerer Wert kleiner ist, als der Wert für den
ersten Lowimpuls, bekommen ich ein verschobenes Signal, dass heißt die
Impulslängen paasen nicht mehr....

Hat jemand eine Idee woran dass liegen kann?

von Björn (Gast)


Lesenswert?

Nach dem messen am Oszi. hab ich nun festgestellt, das die minimale
Impulsdauer die ich einstellen kann 14,3µs beträgt. Also ist wohl der
Timer bzw. Controller zu langsam um auf die 10µs zu kommen.

Im Moment läuft er mit einem externen Quartz von 8MHz. Bringt es wohl
was einfach einen größeren Quartz zu verwenden?

Oder ist es eventuell sinvoller, das Signal ohne Interrupt zu erzeugen?

von Dominik F. (forlix) Benutzerseite


Lesenswert?

Mach doch den Vorteiler weg.

Gruß
Dominik

von Björn (Gast)


Lesenswert?

Auch wenn ich den Vorteiler weg mache, beträgt die minimal einstellbare
Impulsdauer 14,3µs.

Warum das so ist verstehe ich auch nicht!

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Du könntest auch Teile in Assembler schreiben...

Ich bin mir nicht ganz sicher, aber kostet
>sizeof(Preloads) / sizeof(unsigned char)
nicht einen Haufen Zeit, wenn es zur Laufzeit berechnet wird (oder
berechnet der Compiler/Preprozessor schon vorher?)

Ich würde die Zuweisungssachen, nicht alle in der ISR machen, sondern
nur das folgende Byte in OCR schreiben. Übrigens ist OCR 16-Bit lang
(oder?).
Sinnvoll wäre auch, die über das UART empfangenen und dann dekodierten
Daten in ein zweites Array zu schreiben, und zwischen beiden Arrays
dann umzuschalten.

Das einfachste sollte sein, die ISR auf das notwendigste zu kürzen:
Den neuen Wert ins OCR schreiben und noch einen Zähler zu
inkrementieren.
Dieser Zähler sorgt dann dafür, dass der nächste OCR-Wert in der
Hauptschleife in die "Zwischenvariable" geschrieben wird, die dann
beim nächsten Interrupt ins OCR geschrieben wird.


if(NrOverflow % 2 == 0)
    PORTC &= ~(1 << PC0);

  else
    {PORTC |= (1 << PC0);}
könnte man auch so machen:
if(NrOverflow & 0x01)
    PORTC |= (1 << PC0);

  else
    {PORTC &= ~(1 << PC0);}

von Björn (Gast)


Lesenswert?

Hi Rahul,

also ich bin mir auch nicht sicher ob sizeof viel mehr Zeit kostet wenn
es zur Laufzeit berechnet wird. Hab es ohne sizeof am laufen gehabt, war
kein Unterschied festzustellen.

Die OCR ist nur 8 Bit lang.

Hab den Controller nun anders getaktet, funktioniert einwandfrei. Läuft
jetzt mit 11,059 MHz.....

Aber vielen Dank für die Tipps....!!!

Gruß

von Karl heinz B. (kbucheg)


Lesenswert?

> also ich bin mir auch nicht sicher ob sizeof viel mehr Zeit kostet
> wenn es zur Laufzeit berechnet wird.

sizeof war bis C99 eine reine Compile-time-Berechnung.
Erst mit C99 sind dynamische Arrays in der Szene erschienen
und erzeugten die Notwendigkeit einen Teil der sizeof
Funktionalität in die Laufzeit zu verlagern.
Da Ausdrücke wird der in Frage stehende seit Urzeiten
verwendet werden, kann man davon ausgehen, dass auch
der schlechteste Compiler das zu einer Konstanten optimiert
(zumal sizeof(unsigned char) per Definition 1 ist)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.