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?
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?
Auch wenn ich den Vorteiler weg mache, beträgt die minimal einstellbare Impulsdauer 14,3µs. Warum das so ist verstehe ich auch nicht!
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);}
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ß
> 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.