PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SHIFTOUT mit AVR-Clock



hardware.bas
18.05.2018, 11:15
Für ein Anzeigeprojekt besteht die Forderung, ein
längeres Bitmuster auf einen Ausgangsport zu legen.
Es handelt sich um 600 bits mit einer Breite von 50ns.
Um dieses Bitmuster zu berechnen, ist ausreichend
Zeit vorhanden, während des Sendevorganges jedoch
auf Grund der hohen Taktrate jedoch nicht mehr.
Wir reden hier um 20MHz, so dass sich jetzt die Frage
stellt; lassen sich mit SHIFTOUT diese Datenmengen
im "AVR-Speed" ausgeben? Leider weiss ich nicht,
wieviel Takte die entsprechende Shiftoperation
benötigt. Vielleicht weiss da jemand Bescheid?
Vielen Dank Micha

wkrug
19.05.2018, 07:58
Per Software SPI ist das sicher nicht möglich.
Der Controller muss dazu auch mit 20MHz laufen
Es muss das zu übertragende Bit auf einen Port gelegt werden und auf einem anderen Port muss der Shift Impuls genertiert werden = H,L,H.
Jede Operation benötigt mindestens einen Prozessor Clock, auch wenn man das in Assembler macht.
Auch die Hardware SPI kommt hier an Ihre Grenzen.
Man müsste mal im Datenblatt des entsprechenden Controller gucken, ob sie sich überhaupt so hoch takten lässt.
Ausserdem hat man somit auch nur maximal 8 Takte Zeit das SPI Daten Register neu zu beschreiben, sonst gibts Pausen im Signal.
Das ist zwar im Prinzip nicht schlimm, aber die angestrebte Taktrate ist so nicht erreichbar.

Das Ganze läuft auf jeden Fall an den hardwaretechnischen Grenzen eines AVR.

EDIT:
Hab mal im Datenblatt eines ATMEGA 8 nachgesehen.
Für SCK ist eine maximale Taktrate von Fosz/2 möglich.
Bei diesem Controller ist also eine SPI Taktfrequenz von 20MHz nicht möglich.

hardware.bas
19.05.2018, 15:35
Die Idee war, eine Auflösung von 50ns zu erreichen, obwohl nur 24 BIT
bei 800kHz übertragen werden sollen. Glücklich wäre ich also mit meiner
ersten Idee damit auch nicht. Mit PWM und Timer zu arbeiten, würde
das Problem auch nicht lösen. Dazu müsste der Prozessor während
dieser Zeit zusätzlich noch rechnen.
Immer mehr liebäugele ich daher mit einer Hardwarelösung, indem die
H-Impulse als Spike auf einen eigenen MMV gegeben werden, ein 2ter
Portausgang gibt das Datenpaket negiert aus, so dass die Ls eben-
falls als H-Spikes wiederum einen eigenen MMV ansteuern.
Die Ausgänge der MMVs werden dann zusammengeodert.
Jetzt kann ich mit 4 MHz im AVR arbeiten, aus denen dann problemlos
800 kHz Taktimpulse erzeugt werden können. Der AVR muss nicht
alles alleine machen. Es geht um die Ansteuerung von RGBDIGITs.
VG Micha

shedepe
19.05.2018, 16:05
Hallo,
warum brauchst du denn so eine hohe Auflösung von 50ns ? Wenn ich mir die RGBDigit Seite so anschaue würde ich darauf tippen, dass das defintiv nicht notwendig ist, sonst wäre das ganze ja nicht Arduino kompatibel.
Wenn es dir im mehrere Anzeigen geht könntest du dir einen Atmega oder Atxmega mit mehreren SPI Controllern suchen und damit parallel die Daten raushauen.

Wenn du wirklich 50ns haben willst, könntest du ja auch gleich einen ARM Controller nehmen. Damit kannst du dann locker 50 MHz Toggle Rate an einem IO Pin erreichen.

EDIT: Ich nehme mal an du redest über diese Dinger hier: http://rgbdigit.com/Documents/RGBDigit_datasheet_V4.pdf

Dann kannst du Seite 4 sehen: Deine Data transfer time ist mindestens 1,25 us. Wenn du da 50ns Pulse generierst wird das Anzeige Modul vermutlich nicht das anzeigen was du erwartest.

hardware.bas
19.05.2018, 18:29
Das Timing ohne Toleranz basiert auf 50ns (20MHz), die volle Ausnutzung der
Toleranzen lässt eine Auflösung von 200ns (5MHz) zu. Es werden für den
Zusammenbau der Impule daher das Vielfache von Takten benötigt, als für
die eigentliche Datenübertragung notwendig sind. Das war mein ursprüng-
licher Gedankengang, um RC-Abgleicharbeiten von MMVs zu vermeiden.
Eine andere Möglichkeit, welche ich in Erwägung ziehe, ist ein kleines,
jedoch schnelles direkt adressierbares EEPROM zu nutzen, die Datenbits
als Adresse reinzusenden und dieses gibt die endgültigen Impukspakete
aus. Immer noch weniger Schaltaufwand als zig Decoder, LED-Begrenzer-
widerstände oder Multiplextreiber ohne Farbsteuerung und Erweiterbarkeit.
VG Micha

- - - Aktualisiert - - -

PS:
Der Link ist korrekt.
Sollten ARMs in BASIC programmierbar sein, könnte man drüber reden
VG Micha

Klebwax
19.05.2018, 21:41
Hallo,
warum brauchst du denn so eine hohe Auflösung von 50ns ? Wenn ich mir die RGBDigit Seite so anschaue würde ich darauf tippen, dass das defintiv nicht notwendig ist, sonst wäre das ganze ja nicht Arduino kompatibel.

Richtig. Man muß alle 1250ns einen Puls von entweder 400ns oder 850ns erzeugen. Die aufgeschriebenen Toleranzen von 150ns sind recht großzügig, Das mit Bitbanging zu erzeugen, ist aber sportlich. Man muß ja nicht nur das Timing erzeugen, sondern auch noch die Bits aus den Bilddaten extrahieren.

Da kommt die Idee ins Spiel, die SPI-Hardware zu benutzen, um die CPU zu entlasten. Wenn man als SPI-Clock 2,5 MHz benutzt, dauert ein Bit 400ns. 3 Bits sind dann 1200ns, gut in der Toleranz der 1250ns. Um ein Bit als 0 zu kodieren, schickt man binär 100, für eine 1 binär 110. Diese Bitfolgen muß man dann natürlich vorher berechnen und dabei 2 2/3 Farbbits in ein Byte packen. Das ganze macht aber nur dann Sinn, wenn man Hardware-SPI verwendet, besser ist es noch, wenn SPI über ein FIFO verfügt oder DMA verfügbar ist. Vom SPI wird hier nur MOSI benutzt.

Software SPI macht gar keinen Sinn, da kann man auch gleich das richtige Protokoll erzeugen.

Was man auch noch überlegen könnte, ist ein Protokollbit in 4 SPI-Bits zu kodieren. Wenn man die Erfahrungen von Siro (https://www.roboternetz.de/community/threads/72008-7-Segmentanzeige-mit-Farbsteuerung/page3?p=644673&viewfull=1#post644673) berücksichtigt, das eine Bitzeit auch größer als 1250ns funtioniert, sollten auch 1600ns passen. Eine 0 wäre dann 0b1000, eine 1 0b1100. Diese Kodierung könnte man möglicherweise live erzeugen, während die Hardware-SPI läuft.


Wenn es dir im mehrere Anzeigen geht könntest du dir einen Atmega oder Atxmega mit mehreren SPI Controllern suchen und damit parallel die Daten raushauen.

Das macht keinen wirklichen Sinn. Man hat schon Mühe genug, einen SPI-Controler mit Daten zu füttern. Da man die WS2812 hintereinander schalten kann, ist es auch nicht nötig. 100 Neopixel und mehr sind kein wirkliches Problem, wie andere Projekte zeigen. Das sind dann 12 und mehr Digits.

MfG Klebwax

wkrug
20.05.2018, 08:38
Jetzt kann ich mit 4 MHz im AVR (http://www.rn-wissen.de/index.php/AVR-Einstieg_leicht_gemacht) arbeiten, aus denen dann problemlos
800 kHz Taktimpulse erzeugt werden können.
Mein Vorschlag war ja mit der Hardware SPI zu arbeiten.
Da sind dann bei 20MHz Taktfrequenz 10MHz Clockrate bei SPI Master möglich.
Im SPI Slave Mode - den Du ja nicht brauchst - wären es dann immer noch 5MHz.
Das Ganze SPI Geschäft läuft rein in Hardware ohne zusätzliche Prozessorlast.
Lediglich das Abfragen ob das SPIDR leer ist und das Beschreiben des selben müsste man softwaretechnisch lösen.
Dazu würde ich aber bei dieser Geschwindigkeit Assembler verwenden und die Daten aus einer vorberechneten Tabelle holen.
Im entsprechenden AVR Datenblatt ist da sogar ein Programmbeispiel dafür drin.

hardware.bas
20.05.2018, 11:41
Zum Berechnen der Bitfolge ist ausreichend Zeit vorhanden. Um eine sichere Arbeitsweise zu erhalten, möchte ich (erstmal) keine Toleranzen einplanen und für ein wenig mehr Hardware hätte ich auch noch Platz. Um nun auch geringste Phasenverschiebungen zu vermeiden könnte man über ein PINOUT 24 Spices mit 1,25 ms Abstand auf 2 AND-Tore geben, dabei wird noch 1 PINOUT mit Negator gebraucht, welches ein Tor bei H und ein Tor bei L öffnet. dahinter können dann die Spices den entsprechenden Eingängen eines dopelten Monoflops zugeführt werden, welche dann jeweils Impulse von 400 ns und 850 ns erzeugen und die Ausgänge verodert werden. Mit einer 800kHz-Timerinterrupt- routine sollte die Spiceerzeugung und das Rausshiften der 24 BIT dann kein Problem mehr sein. Die Pausen von 50000 ns reichen aus, um ein neues Bitmuster für die nächste RGB-LED aus dem vorhandenen Anzeigespeicher zu holen. Die eigentliche Segment- und Ziffernzuordnung wird eh inner- halb der Hauptroutine von ca 0,8 Sekunden berechnet. VG Micha werden noch 2 zusätzliche

Klebwax
20.05.2018, 15:22
Mit einer 800kHz-Timerinterrupt- routine sollte die Spiceerzeugung und das Rausshiften der 24 BIT dann kein Problem mehr sein.

Ich komme nicht auf 24 Bit sondern auf 8*24, also 192 Bits pro Digit. Und da sehe ich in der Spec auch keine Pause. Ich glaube auch nicht, daß ein 800kHz Timmerinterrupt funktionieren wird. 1,2 µs werden nicht mal für einen leeren Interrupthandler reichen.

MfG Klebwax

hardware.bas
20.05.2018, 16:47
Der Datasheet der RGBDIGITs entspricht genau dem Datasheet der
offensichtlich dort verbauten hintereinandergeschalteten intelligenten
RGB-LEDs, darum ist korrekt, dass für die Ansteuerung eines Digits
8x24 BITs gebraucht werden. Das Protokoll für eine 8-stellige Anzeige
besteht also in 64 Datenpaketen - Dauer mit Pause knapp 100 Mikro-
sekunden - also insgesamt für die Komplette Anzeigenaktualisierung
weit weniger als 10 ms. Die Interuptroutine von 1250ns muss reichen,
einen einzigen Spike zu senden und Longvariable um eine Stelle in
einen Ausgangspin zu schieben. Die 50 Mikrosekunden-Pause dient
dazu, die Longvariable (obwohl nur 3 Byte benötigt werden) neu
zu beschreiben. und einen Zeiger zu incrementieren.
Alle anderen Berechnungen befinden sich in der Hauptroutine.
Als Chip ist ein ATMega162 vorgesehen, wo genügend Speicher-
arrays etabliert werden können.
VG Micha

- - - Aktualisiert - - -

PS. In die Interruptroutine muss natürlich die Timervoreinstellung
noch rein. Ansonsten kann ich natürlich die Taktfrequenz noch
erhöhen, der genaue Wert ist für die im Projekt genutzten 2 UARTs
jeweils nur 1200 BAUD für RS232 und RS485.
VG Micha

Klebwax
20.05.2018, 22:08
Der Datasheet der RGBDIGITs entspricht genau dem Datasheet der offensichtlich dort verbauten hintereinandergeschalteten intelligenten RGB-LEDs, darum ist korrekt, dass für die Ansteuerung eines Digits 8x24 BITs gebraucht werden.

Da gibt es aber keine Pause. Die 192 Bits müssen am Stück raus. Kommt da eine Pause drin vor, wird wieder die erste LED angesteuert.


Das Protokoll für eine 8-stellige Anzeige besteht also in 64 Datenpaketen

Wenn man die Digits einzeln ansteuert, sind es 8 Datenpakete, eins pro Digit, mit einer Länge von 192 Bits.

Eigentlich macht man das aber anders. Man schaltet die Digits einfach hintereinander. Es sind ja "nur" 64 LEDs für die 8 Digits. In anderen Projekten werden 100 oder auch 200 LEDs so gesteuert. Ich hab eine Matrix mit 144 (12*12) LEDs in Betrieb, aber mit einer fertigen Library, deren innere Funktion ich nicht kenne. Das entspricht einer Anzeige mit 18 Digits.


Die Interuptroutine von 1250ns muss reichen, einen einzigen Spike zu senden und Longvariable um eine Stelle in einen Ausgangspin zu schieben. Die 50 Mikrosekunden-Pause dient dazu, die Longvariable (obwohl nur 3 Byte benötigt werden) neu zu beschreiben. und einen Zeiger zu incrementieren.

Auf einem 8-Bitter werden aus einem Shift eines Longs 4 Shifts eines Bytes. Dazu braucht man noch einen Zähler, der die 24 Bit abzählt. Und da es diese "50 Mikrosekunden-Pause" nicht gibt, muß man sich in den 1250ns alle 24 Bits noch um das Nachladen kümmern. Dazu werden am Anfang des Interrupts noch einige Register gerettet, die am Ende wieder hergestellt werden müssen. Die Neopixel-Libraries schieben 1000 und mehr Bits in einem Rutsch raus.

MfG Klebwax

hardware.bas
21.05.2018, 09:57
Ich sehe - bis jetzt - im Datasheet immer noch die Pause
alle 24 BITs. Die einzelnen Segment-RGB-LEDs müsste
daher schaltungstechnisch als Einzelbauelemente
betrachtet werden. Also 64 Sendeprozeduren bei
8 DIGITs. Offensichtlich erfolgt die Adressierung so,
dass jede LED nur das erste 24 BIT-Datenpaket auswertet,
dann ausblendet und nur die restlichen weitersendet usw .
Meine neue Idee währe jetzt, während der Displayansteuerung
sämtliche Interrupts abzuschalten und wie folgt zu verfahren:
DIM IMPULS AS BIT(24)
.
FOR SEGMENT = 1 TO 24
PORTA.1 = BIT(SEGMENT) : Ausgabe der H/L-Torsteuerung
NOP : oder mehrere NOPs
TOGGLE PORTA.0 : Spike für die MMVs
TOGGLE PORTA.0 : gibt wohl dafür einen extra Befehl
NOP : oder mehrere NOPs
NEXT SEGMENT

VG Micha

werde

hardware.bas
23.05.2018, 19:16
Muss leider zugestehen, dass BIT-Arrays nicht compiliert werden.
Das variablenbezoge Auslesen von LONG-BIT akzeptiert jedoch
der Compiler. Um die die og FOR-NEXT-Schleife umzuschreiben,
wollte ich im Vorfeld mittels Bascom-Simulator, die notwendigen
Taktzeiten ermitteln. Leider weiss ich nicht, wie das dort lösbar
ist, irgendwelche "clocks" zeigen 0 an, laufen jedoch biem Bewegen
des Mauszeigers auch nach dem Ende der Simulatin weiter.
Gibts da einen Trick? Im BASCOM-Help wurde ich nicht fündig.
VG Micha

- - - Aktualisiert - - -

Hab jetzt versucht, die Realtimevorgänge im BASCOM-Simulator
mit Auslesen des TIMER1 in etwa rauszukriegen. Scheint für
Zeitsimulationen ungeeignet zu sein. Wird wohl für weitere
Aussagen hierzu die Hardware besser entscheiden, sprich,
das ATMega8-Experimentier-Board.
VG Micha

hardware.bas
24.05.2018, 18:48
Ohne Programmänderung hat bei meinem BASCOM-Simulator heute plötzlich
die Timerfunktion funktioniert. Leider war die Wiederholgenauigkeit teilweise
nicht akzeptabel. Heraugekommen sind jedenfalls Werte, welche eine viel
zu hohe Taktzahl für alle bisher avisierten Lösungen zur Ansteuerung der
RGB-DIGITs zur Folge haben (Jenseits von Gut und Böse). Ich verzichte aus
Zeigründen daher auf einen Hardwaretest und die Nutzung (trotz anfänglicher
Euphorie) der RGB-DGITs. Werde eine andere effektvolle Anzeigenform finden
VG Micha

for_ro
24.05.2018, 22:30
Wenn du selber mit dem Timing nicht zurechtkommst, dann würde ich mir mal die Rainbow-Lib (RB_...) ab Bascom Version 2.0.8.0 ansehen. Die ist von einem cleveren Programmierer genau für die WS2812 Chips gemacht worden.
Ist zwar eigentlich für RGB Stripes gedacht, wird aber mit deinen RGB Digits genau so funktionieren.

wkrug
24.05.2018, 23:16
Ich hab mir jetzt mal einen anderen Beitrag mit den Anzeigen von Dir angeschaut.
Hier geht es ja nicht um eine SPI, sondern um eine Codierung, bei denen ein 0 Bit und ein 1 Bit lediglich eine andere Pulsweite aufweisen.
Das würde ich versuchen mit einem Timer zu realisieren.
Bei einem 20MHz Prozessortakt würde ein Timer für ein Bit genau 25 Prozessortakte für ein komplettes Bit brauchen.
Wenn man jetzt einen Timer mit einem CTC und dem Compare A Timer mit 24 proggt und das Comparematch B mit dem Wert für die 1 oder 0 versieht ( z.B. 17 ),
werden gültige Pulslängen ausgegeben. Der Comparematch B müsste dazu im Fast PWM Modus arbeiten.
Der Comparematch B Wert müsste im Comparematch Interrupt A upgedatet werden.
Die Crux dabei ist, das die Updaterei innerhalb von ca. 7 Prozessortakten geschehen muss.
Das ist auch in Assembler keine leichte Aufgabe.
Alle Register sichern wie BASCOM das üblicherweise macht wird wohl nicht möglich sein.
Ich würde es mit einem inkrementierenden X Register und einer Tabelle mit einem Tabellenplatz ( = 8Bit ) pro auszugebenden Bit in Assembler probieren.
Die benutzten Register dürfen dann aber von BASCOM nicht mehr verwendet werden und exklusiv für die Biterzeugung des Displays arbeiten.

Alternativ könnte man das Gleiche auch im Comparematch B Interrupt versuchen.
Allerdings muss man dann peinlichst darauf achten, das das Comparematch B Register nicht zu früh geändert wird.
Dann hätte man für die Updaterei 16 Prozessortakte.

Die Aufgabe bleibt aber weiterhin sportlich.

hardware.bas
25.05.2018, 17:12
Danke erstmal für die vielen Hinweise. In der Tat, das Projekt
habe ich noch nicht ganz aufgegeben. Ich werde mich mal
"back to the roots" begeben und der AVR wird dann nur noch
für die Bereitstellung der für eine 8-stellige Anzeige notwendigen
24-Bit-Datenpakete für die Segmente sorgen müssen, neben
seiner egentlichen Aufgaben. Der Rest wird hardwaremässig
erledigt. Die Impulse (400nS für L und 850nS für H) werden dann
nicht mehr von 2 MMVs (RC-Abgleich entfällt) erledigt, sondern
mit einem synchronen Binärzahler mit umschaltbaren Datenmuster
erzeugt. Entweder durch unterschiedliche Voreinstellung oder
gesteuerte UND-Abgriffe mittels Gatter, beides durch Umschaltung
von H/L. Diese Impulse werden einem 24-Bit-Schieberegister, welches
mit dem 1/25 Takt des Binärzählers (50nS/1250nS) bedient wird
entnommen. Dieses Schieberegister wird während der 50000nS-Pause
parallel über 3-Byteports geladen. Anstelle des 20MHz-Oszillators
für die Anzeigehardware, kann dann auch problemlos ein entprellter
Handtaster für den Funktionstest genommen werden.
VG Micha