Hi Leute, habe mal wieder ein seltsames Problem und zwar nutze ich den Atmega32U4 um ein On-Screen-Display zu realisieren. Ich schreibe also ein BAS Signal. Dazu verwende ich die Funktion des U4´s die USART Schnittstelle als SPI Master zu verwenden (Ich brauch die andere zur Kommunikation mit anderen Geräten) In der while Schleife des Programms wird ein Flag abgefragt. Ist dieses 1 wird angefangen eine Zeile zu schreiben. Das heißt einlesen eines Bytes und senden per SPI und das ganze 40 mal hintereinander (per while Schleife). Das einlesen des Bytes aus einem bestimmten Speicher dauert ungefähr 19 Takte, so, dass ich Lese und sofort danach schreibe ohne darauf zu Achten ob SPI fertig ist. Da ich jedoch mit 16MHz und SPI Clock auf fclock/2 gestellt habe sollte SPI spätestens nach 2*8 + 2 = 18 Takten fertig sein. Dies funktioniert auch super es wird kein Byte ausgelassen. Vor dieser Prozedur werden per cli() alle Interrupts abgeschalten und im nachhinein per sei() wieder eingeschalten. Dieser Programmabschnitt wird also durch ein Flag eingeleitet. Dieses Flag wird entweder durch einen Timer Interrupt oder einen externen Interrupt gesetzt. Nun zum Problem: In dem Modus indem dieses Flag vom externen Interrupt gesetzt wird scheint es als würden die Bytes aus dem SPI nicht mit dem gleichen Abstand herauskommen. Das heißt ich schreibe immer nach genau 19 Takten (Taktanzahl ermittelt durch zählen von Takten die jeder Assemblerbefehl braucht) ins SPI-USART Register jedoch kommen zwei aufeinanderfolgend Bytes manchmal um 2 Takte verschoben raus. (Messung per Oszi). Dies geschieht aber wie gesagt nur in dem einen Modus obwohl bei beiden das gleiche Programm abgearbeitet wird. Was könnte der Fehler sein? Ist es möglich, dass der Controller zwischendrin einfach 2 Takte lang was anderes macht? Beim einlesen des Bytes verwende ich folgende Assembler Befehle: ADD ADC SUBI SBCI CPC CPI BRNE MOVW LD STS LPM nach instruction Set Liste brauchen diese Befehle immer eine konstante Anzahl an Takten (BRNE in der Schleife wohl immer 2.) Gibt es doch den Fall, das ein Befehl mehr Takte benötigt?
Hat jemand zumindest irgendwelche Anregungen was ich noch testen könnte? Bin mit meinem Latein am Ende. Vielleicht bringt mich das ja auf andere Ideen!! Wäre super!
Wie ich sehe misst du die Zeit der Impulse die der LM rausgibt. Das machst du aber nur um zwischen Zeilen und VSyncs zu unterscheiden oder? Habe mir auch schon überlegt ob es daran liegt, dass der LM zu ungenau ist und je nach Eingangssignal seine Schwelle mal früher oder später überschritten wird und deshalb die Zeilen wackeln. Ist das Signal des LM's genau genug? Habe die Frage allerdings zurückgestellt, da es so aussieht als würde nicht eine komplette Zeile wackeln sondern die einzelnen Buchstaben je Spalte unabhängig voneinander. Es handelt sich bei mir um ein Projekt, dass leider schon am Ende steht. Hardware ist bereits vorgegeben, kann also nicht auf anderen Aufbau und Software switchen. Software funktioniert bisher auch sehr gut. Das bewegen der Buchstaben ist meine einzige Sorge. Nochmal die Frage: Können Befehle aus irgendwelchen Gründen mal einen Takt länger brauchen?
Thomas Frosch schrieb: > Wie ich sehe misst du die Zeit der Impulse die der LM rausgibt. Das > machst du aber nur um zwischen Zeilen und VSyncs zu unterscheiden oder? Ups, ich habe Dir versehentlich eine alte Version geschickt. Darin habe ich mir V-Sync selbst gebastelt, weil ich zu blöd war, Rset am richtigen Pin anzuschließen und daher kein V-Sync bekam. In der neueren Version wird V-Sync berücksichtigt, Foto und Skizze enthält diese Drahtbrücke aber noch nicht. Siehe neuen Quelltext. > Habe mir auch schon überlegt ob es daran liegt, dass der LM zu ungenau > ist und je nach Eingangssignal seine Schwelle mal früher oder später > überschritten wird und deshalb die Zeilen wackeln. Nein, der LM1881 ist da recht genau. Etwas Jitter kann es durch die unterschiedliche Interrupt-Response-Time geben, das habe ich aber dadurch verhindert, dass der Interrupt den AVR immer im Sleep überrascht. Die übrigen Arbeiten werden grundsätzlich nur außerhalb des Bildaufbaus erledigt, also immer nach der letzten Zeile, und auch nicht zuviel auf einmal. > > Ist das Signal des LM's genau genug? Ja, ist genau genug. > Habe die Frage allerdings > zurückgestellt, da es so aussieht als würde nicht eine komplette Zeile > wackeln sondern die einzelnen Buchstaben je Spalte unabhängig > voneinander. Naja, ich nutze die SPI-Einheit und nicht USART. Diese braucht 16 Takte zum Ausschieben, das SPDR ist aber erst nach 2 weiteren Takten wieder beschreibbar. Das war mir aber recht, denn ich habe zusätzliche Takte eingefügt, um den Zeichenabstand zu vergrößern. Mein OSD wird im Amateurfunk (ATV-Relais) eingesetzt, da wird große, gut lesbare Schrift gebraucht. Der Textbereich wurde bewusst auf 10 Zeilen je 32 Zeichen begrenzt. > > Es handelt sich bei mir um ein Projekt, dass leider schon am Ende steht. > Hardware ist bereits vorgegeben, kann also nicht auf anderen Aufbau und > Software switchen. Software funktioniert bisher auch sehr gut. Das > bewegen der Buchstaben ist meine einzige Sorge. Nunja, Du benutzt USART, ich benutze SPI. Inwieweit USART für SPI taugt, weiß ich nicht, hat mich noch nie interessiert. > > Nochmal die Frage: Können Befehle aus irgendwelchen Gründen mal einen > Takt länger brauchen? Da ist mir nichts bekannt, zumindest, was ASM betrifft. Die Interrupt-Response-Time ist aber variabel, wenn sich die CPU nicht im Sleep befindet. Du schreibst von Sperren des Interrupts durch cli() und sei(). Das mache ich nicht, Interrupt-Aufrufe sind immer erlaubt. ...
Also ich benutze nicht direkt USART. Der Atmega32U4 bietet die Möglichkeit den UART als zusätzlichen SPI Master zu verwenden. Ich benötige den normalen SPI noch damit ich das OSD als Slave ansprechen kann. Ich benutze auch den Sleep Modus! Nach langem rumprobieren scheint es, dass wenn man vor dem senden über die USART-SPI das TXFlag löscht es besser funktioniert! Die Buchstaben hibbeln nun nicht mehr aufeinander zu. Allerdings hibbelt es trotzdem weiter. Dies führe ich jedoch eher auf die Syncs einer Zeile zurück. Ganz sicher kann ich mir dabei aber auch nicht sein. Vorallem wenn du schreibst das Signal über den LM ist ziemlich genau. Die Frage ist wieviel Jitter ist für dich wenig? Ich sehe das Bild in meinem Grafikartenmodus (also nicht OSD sondern eigene Syncerzeugung) und das steht ohne kleinstes zittern und dann schalte ich um auf OSD und es jittert etwas. Das nächste ist auch, dass ich um das Flag zu löschen nun natürlich etwas länger brauche und dadurch der Abstand zwischen den Buchstaben größer wird. Zudem kann ich natürlich auch nicht mehr soviel Zeichen in eine Zeile bekommen (Anfangs 42 nun noch 32). Ich lese über einige Pointer aus dem Programmspeicher da dort das Charset liegt. Das SPI mehr als 16 Takte braucht ist klar + 2 für das "9te" Pseudo Bit Also TXC1 aus UCSR1A löschen dann gehts wesentlich besser. Seltsam ist nur, dass das nur was ausmacht, wenn der externe Interrupt an ist, ansonsten nicht???? Du hast nicht zufällig ein Video von deinem OSD Bild? mich würde mal interessieren wie gut dein Jitter ist. Vielleicht bin ich ja nur zu knausrig. Blöd ist halt der Vergleich zum Grakamodus. Da ists einfach perfekt.
Thomas Frosch schrieb: > Also ich benutze nicht direkt USART. Der Atmega32U4 bietet die > Möglichkeit den UART als zusätzlichen SPI Master zu verwenden. Das können die von mir verwendeten AVRs nicht, also kann ich dazu mangels Erfahrung nichts sagen. Ich werde mich auch nicht mit diesem U4 beschäftigen, da ich ihn nicht auf selbstgeätzte Platinen löten kann. Man kann eben nicht alles haben... > Ich > benötige den normalen SPI noch damit ich das OSD als Slave ansprechen > kann. > > Ich benutze auch den Sleep Modus! Hmmm, das hier liest sich aber anders:
1 | In der while Schleife des Programms wird ein Flag abgefragt. Ist dieses |
2 | 1 wird angefangen eine Zeile zu schreiben. Das heißt einlesen eines |
3 | Bytes und senden per SPI und das ganze 40 mal hintereinander (per while |
4 | Schleife). |
Das sieht bei mir anders aus. Der CPU-Takt ist aufgrund Sleep aus. Die Zeile wird per Interrupt vom H-Sync-Signal gestartet. Dadurch, dass die CPU im Sleep war, ist die Interrupt-Response-Time immer gleich. Würde der Interrupt während der Abarbeitung einer Endlosschleife auftreten, so wäre die Response-Time variabel, da ja die CPU erst ihren angefangenen Befehl fertig abarbeitet. > > Nach langem rumprobieren scheint es, dass wenn man vor dem senden über > die USART-SPI das TXFlag löscht es besser funktioniert! Die Buchstaben > hibbeln nun nicht mehr aufeinander zu. Allerdings hibbelt es trotzdem > weiter. Dies führe ich jedoch eher auf die Syncs einer Zeile zurück. > Ganz sicher kann ich mir dabei aber auch nicht sein. Vorallem wenn du > schreibst das Signal über den LM ist ziemlich genau. Die Frage ist > wieviel Jitter ist für dich wenig? Der LM1881 arbeitet vermutlich genauer, als es der AVR erfassen kann. Denn die I/Os und auch die externen Interruprs (zu denen auch ICP zählt) werden vom Takt gesteuert. Somit wird das Eingangssignal im Takt des AVRs gerastert. Ein AVR-Takt ist aber immerhin 1/16 der Zeichenbreite. Somit ist ein Jitter von 1/16 der Zeichenbreite hinzunehmen. Da H-Sync aber nicht auf das Zeichen wirkt, sondern auf die Pixelzeile, gibt es keinen Jitter zwischen den Zeichen, sondern zwischen den Zeilen der Zeichen. Mit meiner Interrupt-Methode rastere ich auf den Controllertakt, also 1/16 Zeichenbreite. In einer Warteschleife Label: sbis pin_x,bit_y ;2 Takte wenn Skip, sonst 1 Takt rjmp Label ;2 Takte ;Zeile ausgeben... kann das Signal nur in jedem dritten Takt erfasst werden. Somit erhöht sich der Jitter auf 3/16 der Zeichenbreite. > > Ich sehe das Bild in meinem Grafikartenmodus (also nicht OSD sondern > eigene Syncerzeugung) und das steht ohne kleinstes zittern und dann > schalte ich um auf OSD und es jittert etwas. Das nächste ist auch, dass > ich um das Flag zu löschen nun natürlich etwas länger brauche und > dadurch der Abstand zwischen den Buchstaben größer wird. Zudem kann ich > natürlich auch nicht mehr soviel Zeichen in eine Zeile bekommen (Anfangs > 42 nun noch 32). Ich lese über einige Pointer aus dem Programmspeicher > da dort das Charset liegt. Einige Pointer? Der AVR hat nur einen Pointer, der aus dem Flash lesen kann, nämlich den Z-Pointer. Das Charset umfasst 256 Zeichen, diese sind so angeordnet, dass in jeder 256-Byte-Page eine Pixelzeile aller Zeichen enthalten ist. Somit entscheidet ZH über die Pixelzeile und ZL über die (ASCII-)Zeichennummer. Beide Bytes des Pointers werden separat gesetzt, der Zugriff erfolgt (per LPM) über nur einen Pointer. Da ist nix mit "lese über einige Pointer aus dem Programmspeicher". > Das SPI mehr als 16 Takte braucht ist klar + 2 für das "9te" Pseudo Bit > > Also TXC1 aus UCSR1A löschen dann gehts wesentlich besser. > Seltsam ist nur, dass das nur was ausmacht, wenn der externe Interrupt > an ist, ansonsten nicht???? Bei mir ist während der Ausgabe einer Videozeile kein externer Interrupt an. Der ICP (auch nur ein externer Interrupt mit Zusatzfeatures) detektiert das H-Sync-Signal, die Ausgabe der gesamten Pixelzeile erfolgt in seiner ISR. Während der ISR ist der Aufruf weiterer Interrupts gesperrt, es ist alsi nichts da, was das Timing zwischen den Zeichen stören könnte. > > Du hast nicht zufällig ein Video von deinem OSD Bild? mich würde mal > interessieren wie gut dein Jitter ist. Nein, habe ich nicht. Werde ich auch nicht machen, weil ich keine Hardware mehr habe und deswegen auch keine neue Hardware aufbauen werde. Die Hardware habe ich dem Funkamateur übergeben, für den ich das Programm schrieb. Die Sache ist seit fast 3 Jahren für mich erledigt, ich brauche selbst weder ein OSD noch eine "Grafikkarte" für AVRs. Denn ich bastele nicht mit TV, Video und ähnlichen Dingen, das ist einfach nicht mein Gebiet. > Vielleicht bin ich ja nur zu > knausrig. Blöd ist halt der Vergleich zum Grakamodus. Da ists einfach > perfekt. Das ist ja kein Wunder. Da erzeugst Du ja das Timing selbst und musst kein externes Timing synchronisieren. Überprüfe doch bitte nochmal, ob (wie Du sagst) die ganzen Zeichen gegeneinander zittern, oder ob die ganzen Pixelzeilen gegeneinander zittern. Denn dass die ganzen Zeichen gegeneinander zittern, halte ich für sehr unwahrscheinlich. Es werden wohl die Pixelzeilen sein, die Ursache liegt vermutlich in der verschenkten Auflösung aufgrund der Abfrage in der While-Schleife. ...
Meiner ist auch im Sleep. Ansonsten bekommt man noch ein wesentlich schlimmeres zittern Ich konnte es noch nicht testen wie es sich auswirkt wenn ich das TX Flag lösche, aber davor (und das ist das seltsame) haben sich die Zeichen tatsächlich zueinander verschoben. Ich ließ mehrere kleine l´s schreiben und hab diese mit einem Oszi im Signal angesehen. Ab und zu sind diese um 2 Takte weiter auseinander. Du hast recht es sind nicht einige Pointer aber einige Pointeroperationen da ich aus einem Array den Ascii Code lese den ich anzeigen möchte und dementsprechend mir die Bytes aus dem Charset im Flash hole. Ich kann 40x33 Zeichen anzeigen. Und mit: >>In der while Schleife des Programms wird ein Flag abgefragt. Ist dieses >>1 wird angefangen eine Zeile zu schreiben. Das heißt einlesen eines >>Bytes und senden per SPI und das ganze 40 mal hintereinander (per while >>Schleife). meinte ich den USART SPI und 40 mal pro Linie dann geht er in den Sleep. ... Danke für die Antworten. Kann mir also sicher sein, dass es nicht am LM liegt. Werde nochmal per Oszi testen ob sich die Zeichen immer noch voneinander weg bewegen. Hab im moment nur keins hier. Wenn das so wäre, wäre es ganz schön seltsam, denn das würde bedeuten die USART-SPI Hardware braucht zwischen zwei Bytes ab und zu zwei Takte länger. Nach Assembler Code im Programm gibt es in diesem Abschnitt nichts wo er mal länger brauchen könnte...
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.