Hi Community. Mit einem AVR, z.B. Mega16 bei 16 MHz Takt, muss ich ein serielles Datensignal ausgeben mit eigentlich 1,33 Mbaud, d.h. 750 ns breiten Bits. Ich könnte aber vermutlich auch mit 1 Mbaud leben. Die Ausgabe soll kontinuierlich Byte für Byte erfolgen, ohne irgendein Protokoll oder Pausen dazwischen. UART kommt also nicht in Frage. Nun habe ich mir überlegt, den SPI zu vergewaltigen, denn der ist auch eigentlich nicht für kontinuierliches Senden ausgelegt. Mit etwas Trixerei ist es mir fast gelungen, aber so ganz hab ich den Durchbruch noch nicht. Ihr werdet mich schlagen... Also: Ich hab den SPI als Slave laufen, denn erstens kann man den Slave mit beliebigen krummen Taktraten takten und zweitens kann der SPI Slave über den !SS-Pin in Hardware resettet werden. Also hab ich mit nem Timer einen 1,33 MHz Takt gemacht und auf einen Timer-Pin gelegt und diesen außenrum wieder in den SCK-Pin vom SPI geführt. Dann bleibt noch das Verhängnis, dass der SPI single buffered ist, ich also eigentlich warten muss, bis eine Übertragung beendet ist und dann erst das neue Byte ins SPDR legen kann, wodurch eine Pause entstünde. Wenn ich aber den Timer nutze (CTC-Mode, auch auf externen Pin und wieder rein in den !SS-Pin) und kurz vor Beendigung der Byteausgabe den SPI über den !SS-Pin abschieße, dann kann ich pünktlich im Zeitfenster des nächsten Bytes mit der Ausgabe beginnen und bin sogesehen kontinuierlich. Das Abschießen des SPI Slave muss dann passieren, wenn gerade das letzte Bit am MISO gesetzt wurde. Laut Datenblatt und Praxis bleibt der MISO im letzten Zustand, wenn !SS auf high geht. Soweit die Theorie und bei etwas langsameren Taktraten klappt das auch, z.B. mit 0,5 MHz. Leider kommt der SPI bei höheren Frequenzen nicht mehr klar und das Abschalten per !SS muss früher als beim letzten Bit passieren. Hat vielleicht jemand eine Idee dazu oder eine ganz andere Lösung für die Aufgabe? Im Prinzip muss ich halt Bytes aus dem RAM (liegen in einem Feld) über nen Pin raustickern. Danke für Tipps!
spi nehmen daten in SPDR schreiben dann pollen auf SPIF im SPSR register dann neue daten in SPDR schreiben usw
Hi Nido, Wenn du in Assambler programmierst, kannst du die Takte zählen die dein Prozesser benötig um irgendwelche Befehle zu erledigen. Wenn du jetzt alle 17 Takte ein Datenbyte in das SPDR-Register schreibst, hast du maximal Datenrate erreicht. Wenn du vorher noch Abfragst ob das SPIF-Bit gesetzt ist dauert das zu lange. In C oder Bascom wird das Vorhaben meiner Meinung nach nicht funktionieren. Die nächste wichtige Frage ist ob der AVR es schafft in den 17 Takten die neue Daten zu erzeugen. Ich hoffe das ich dir helfen konnte bei deinem Problem
Marco S. schrieb: > alle 17 Takte ein Datenbyte in das SPDR-Register schreibst Naja, ein Byte hat aber 8 bit, somit erhöht sich der Zeitraum um den Faktor 8. Trotzdem dürfte es knapp werden, die Sendedaten zu berechnen und rechtzeitig bereitzustellen. Btw: Ein Mega16 kann pro Takt einen Befehl abarbeiten? Da bin ich etwas erstaunt. Ein PIC brauch dafür 4 takte und ich kann mir nicht vorstellen, dass Microchip da soweit zurück ist...
Hi, > Naja, ein Byte hat aber 8 bit, somit erhöht sich der Zeitraum um den > Faktor 8. Trotzdem dürfte es knapp werden, die Sendedaten zu berechnen > und rechtzeitig bereitzustellen. Die SPI braucht mindesten 2 Takte um 1 Bit rauszuschieben. Da sie maximal fosc/2 als Arbeitstakt erhält. Des wegen braucht die SPI-Schnittstelle 16 Takte um 8 Bit (1Byte) heraus zuschieben. > Btw: Ein Mega16 kann pro Takt einen Befehl abarbeiten? Da bin ich etwas > erstaunt. Ein PIC brauch dafür 4 takte und ich kann mir nicht > vorstellen, dass Microchip da soweit zurück ist... Das mit dem 4 Takten pro Befehl stimmt. Du darfst nicht vergessen dass der erste PIC ist von 1975. Wass mir gerade noch ein gefallen ist, dass wenn man die UART in den synchronen Übertragungsmodus schaltet. Hast du eine Schnittstelle die ein zusätzliches Datenregister hat als Buffer, da durch ist das nicht mehr so zeitkritisch. Gruß Marco
Jens schrieb: > Ein Mega16 kann pro Takt einen Befehl abarbeiten? Da bin ich etwas > erstaunt. Ein PIC brauch dafür 4 takte und ich kann mir nicht > vorstellen, dass Microchip da soweit zurück ist Der Takt wird im ATmega intern auf das vierfache, den Core-Takt hochmultipliziert. Ein Befehl braucht also wie beim PIC immer noch 4 Takte: Befehl einlesen und Daten#1 holen - Daten#2 holen - Verwursten - Zieldaten Schreiben. Das geht aber nur mit einfachen Befehlen: In jedem ATmega-Datenblatt gibt es eine Liste, wieviele Zyklen ein befehl braucht. Diese Zyklen sind synchron zum Core-Takt, externe Daten von Portpins usw. müssen aber wegen der Takt-Multipliziererei erst einsynchronisiert werden. Eine Ausnahme sind hier die ATmegas, die ein Interface für externe Speicher(zusätzlicher SRAM) besitzen. Dieser muss nicht erst einsynchronisiert werden. mfg mf
Das Problem läßt sich meines wissens umgehen wenn man nicht die Standart SPI Schnittstelle benutzt sondern den USART im syncronen Modus Damit kann man einen Master Slave Betrieb erreichen aber mit Sende und Empfangsbuffer zum senden wird also nur nachgeschaut ob der sendepuffer leer ist und man kann diesen währen das vorherige Byte noch sendet schon wieder füllen Es funtionieren sogar die Interrupts.
Sind 17 Portpins frei? Dann kannst du vielleicht das hier versuchen: Der ATmega wird von einem Quarzoszillator versorgt oder gibt den Haupttakt auf einem Pin aus(kann man bei den kleinen 168/88/48ern so Konfigurieren). Den teilst du mit einem Taktteiler-IC(4020?) auf 1MHz runter. Dieser Takt wird an den Shiftclock von zwei parallel-load serial-out Schieberegistern gelegt. Deren Dateneingänge kommen an zwei komplette Ports. Der Load-Pin muss dann vom 17.Portpin bedient werden. Nun hast du 252 Zyklen Zeit, in denen deine Daten aus dem RAM geholt und vorbereitet werden müssen. Die Fehlenden 4 Zyklen sind der PORT-Out von Data-Lo, Data-Hi und Load-Pin toggeln. mfg mf
@ Mini Float (minifloat) >Der Takt wird im ATmega intern auf das vierfache, den Core-Takt >hochmultipliziert. Ein Befehl braucht also wie beim PIC immer noch 4 >Takte: So ein Quark. Der AVR ist ein RISC Prozessor, der KANN pro Takt einen Befehl abarbeiten. Stichwort Pipeline. Die PICs sind vom Design aus den 70ern des etzten Jahrhunderts, dort hat man das mit dem /4 Taktteiler so gemacht. Das spart u.a. Logikgatter, die damals noch teuer waren. "Wenn man keine Ahnung hat, einfach mal Fresse halten." >ATmega-Datenblatt gibt es eine Liste, wieviele Zyklen ein befehl >braucht. Eben, und das sind Oszillatortakte, keine Maschinentakte! > Diese Zyklen sind synchron zum Core-Takt, Das Wort Core-Takt, abgesehen vom schwachsinnnigen Denglisch, tausch NIRGENDS in einem Atmel-Dokument auf. Komisch, nicht? @ Nido (Gast) >Mit einem AVR, z.B. Mega16 bei 16 MHz Takt, muss ich ein serielles >Datensignal ausgeben mit eigentlich 1,33 Mbaud, kann man machen, UART auf High Speed Modus stellen, dann braucht ein Bit = 8 Takte. BRauchst du also einen 10,64 MHz Quarz. >Bits. Ich könnte aber vermutlich auch mit 1 Mbaud leben. Die Ausgabe >soll kontinuierlich Byte für Byte erfolgen, ohne irgendein Protokoll >oder Pausen dazwischen. UART kommt also nicht in Frage. Unsinn. Das kann der SEHR gut, der hat nämlich einen Sendepuffer! >Nun habe ich mir überlegt, den SPI zu vergewaltigen, denn der ist auch >eigentlich nicht für kontinuierliches Senden ausgelegt. Jain. Aber de Jungs aus der Videoecke Erzeugen per SPI wunderschöne PAL-Signale, kann also so schlecht nicht sein. Allerdings haben die Bytes immer eine "Lücke" von zwei CPU-Takten beim AVR. http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister#Bekannte_Probleme >Ihr werdet mich schlagen... Also: Ich hab den SPI als Slave laufen, denn >erstens kann man den Slave mit beliebigen krummen Taktraten takten und >zweitens kann der SPI Slave über den !SS-Pin in Hardware resettet >werden. Also hab ich mit nem Timer einen 1,33 MHz Takt gemacht und auf >einen Timer-Pin gelegt und diesen außenrum wieder in den SCK-Pin vom SPI >geführt. Käse. >die Aufgabe? Im Prinzip muss ich halt Bytes aus dem RAM (liegen in einem >Feld) über nen Pin raustickern. Trivial. Geht selbst in C. Beitrag "Optimierung SPI Ausgabe" MFG Falk
Danke für eure ganzen Kommentare. Jens schrieb: > Trotzdem dürfte es knapp werden, die Sendedaten zu berechnen > und rechtzeitig bereitzustellen. Nö, die Daten müssen nicht berechnet werden, die liegen im RAM bereit und es muss nichts weiter gemacht werden, als einen Pointer durchzuschieben. Ingesamt geht es um 120 Bit = 15 Byte Daten, die zyklisch ausgegeben werden. Eine weitere Anwendung nimmt gelegentlich Änderungen an den RAM-Daten vor, die aber nicht zeitkritisch sind. Marco S. schrieb: > Die SPI braucht mindesten 2 Takte um 1 Bit rauszuschieben. > Da sie maximal fosc/2 als Arbeitstakt erhält. > > Des wegen braucht die SPI-Schnittstelle 16 Takte um 8 Bit (1Byte) heraus > zuschieben. Ich hab auch immer im Datenblatt gelesen, dass der SPI bis zu fosc/4 Taktrate arbeiten kann. Bei sind es gerade mal fosc/16, d.h. die Lage müsste doch sehr entschärft sein. Marco S. schrieb: > Wass mir gerade noch ein gefallen ist, dass wenn man die UART in den > synchronen Übertragungsmodus schaltet. Hast du eine Schnittstelle die > ein zusätzliches Datenregister hat als Buffer, da durch ist das nicht > mehr so zeitkritisch. baldo_der_baer schrieb: > Das Problem läßt sich meines wissens umgehen wenn man nicht die Standart > SPI Schnittstelle benutzt sondern den USART im syncronen Modus Falk Brunner schrieb: > kann man machen, UART auf High Speed Modus stellen, dann braucht ein Bit > = 8 Takte. BRauchst du also einen 10,64 MHz Quarz. Hier sagen viele, dass UART doch geht. Jetzt bin ich verwirrt oder auch nur zu doof. Wie kann ich dem UART denn Start- und Stopp-Bits abgewöhnen? Ich will doch nur Daten senden. Mini Float schrieb: > Dieser > Takt wird an den Shiftclock von zwei parallel-load serial-out > Schieberegistern gelegt. In die Richtung habe ich auch schon gedacht. Sollte gehen, ist aber nicht so elegant. Gute Idee aber trotzdem. Falk Brunner schrieb: > Jain. Aber de Jungs aus der Videoecke Erzeugen per SPI wunderschöne > PAL-Signale, kann also so schlecht nicht sein. Allerdings haben die > Bytes immer eine "Lücke" von zwei CPU-Takten beim AVR. Die Lücke tut weh, zumindest wenn sie zur Bytedauer hinzukommt. Wenn ich es so erreichen könnte, dass die zwei Takte dem letzten Bit im Byte fehlen, dann wärs super, aber ich weiß nicht wie. Falk Brunner schrieb: >>die Aufgabe? Im Prinzip muss ich halt Bytes aus dem RAM (liegen in einem >>Feld) über nen Pin raustickern. > > Trivial. Geht selbst in C. > > Beitrag "Optimierung SPI Ausgabe" Naja, der Beitrag findet eigentlich keine funktionierende Lösung für das Problem und hat auch nur am Rande etwas damit zu tun.
Die moderneren AVRs (ATmega164) können die UART als SPI-Master konfigurieren. Damit hast Du einen Sendepuffer und die Daten können lückenlos gesendet werden mit max 8MBit bei 16MHz CPU-Takt. Peter
Nido schrieb: > Hier sagen viele, dass UART doch geht. Jetzt bin ich verwirrt oder auch > nur zu doof. Wie kann ich dem UART denn Start- und Stopp-Bits > abgewöhnen? Ich will doch nur Daten senden. Du kannst bei einigen AVRs(bspw.164P) den USART im SPI-Master-Modus (ohne Start/Stop) betreiben und dort dann die Doppelpufferung verwenden, damit fällt auch die Lücke weg (zumindest habe ich keine am Fernseher sehen können). Mark
Falk Brunner schrieb: > schwachsinnnig Danke, die Freude ist ganz meinerseits. Schön, dass du dir auch mal die Aggression des heutigen Tages von der Seele schreiben konntest. Aber mal zurück zum Thema: Du glaubst doch selber nicht, dass die dir im Datenblatt genau erklären, wie der Aufbau ist. Es muss mindestens einen doppelphasigen oder schnelleren Takt geben, anders kann die Befehls-/Ablaufsteuerung, welche auf steigende und fallende Flanke kommt(so die schönen Diagramme), nicht realisiert werden. Es sei denn, man setzt hier auf eine nichtsynchrone Verzögerung aus Dreckeffekten und Gatterlaufzeiten. Davon gehe ich nicht aus. Das muss ein deterministischer Automat sein. mfg mf PS: Ich habe gerade einen ATmega mit dem Seitenschneider aufgemacht. Nun nach deiner Art eine Beschreibung von dem, was ich wirklich sehen konnte. Falk Brunner schrieb: > Stichwort Pipeline Mir sind keine Ölfelder, Punpen und auch keine dicken Rohre aufgefallen. Von Pipelining kann also niemals die Rede sein. ;)
@ Nido (Gast) >Hier sagen viele, dass UART doch geht. Jetzt bin ich verwirrt oder auch >nur zu doof. Wie kann ich dem UART denn Start- und Stopp-Bits >abgewöhnen? Gar nicht. >Die Lücke tut weh, zumindest wenn sie zur Bytedauer hinzukommt. Wenn ich >es so erreichen könnte, dass die zwei Takte dem letzten Bit im Byte >fehlen, dann wärs super, aber ich weiß nicht wie. Geht nicht. MFG Falk
@Mini Float (minifloat) >> schwachsinnnig >Du glaubst doch selber nicht, dass die dir im Datenblatt genau erklären, >wie der Aufbau ist. Müssen sie gar nicht. >Es muss mindestens einen doppelphasigen oder schnelleren Takt geben, Es muss gar nicht. Nur weil DU es nicht kennst bzw. weißt, haißt das noch lange nix. >anders kann die Befehls-/Ablaufsteuerung, welche auf steigende und >fallende Flanke kommt(so die schönen Diagramme), nicht realisiert >werden. Unsinn. [ ] Du hast Ahnung von CPUs. Schau dir mal den Picoblaze von Xilinx an, dort ist recht detailiert der innere Aufbau beschrieben. Und dann wird dir klar, wie sowas funktioniert. > Es sei denn, man setzt hier auf eine nichtsynchrone Verzögerung >aus Dreckeffekten und Gatterlaufzeiten. Tut man nicht, aus gutem Grund. > Davon gehe ich nicht aus. Das >muss ein deterministischer Automat sein. Ist er auch ;-)
Peter Dannegger schrieb: > Die moderneren AVRs (ATmega164) können die UART als SPI-Master > konfigurieren. > Damit hast Du einen Sendepuffer und die Daten können lückenlos gesendet > werden mit max 8MBit bei 16MHz CPU-Takt. Das ist ja klasse und war mir bisher unbekannt. Damit komme ich auf einen grünen Zweig. Vielen Dank! Falk Brunner schrieb: > @ Nido (Gast) > >>Hier sagen viele, dass UART doch geht. Jetzt bin ich verwirrt oder auch >>nur zu doof. Wie kann ich dem UART denn Start- und Stopp-Bits >>abgewöhnen? > > Gar nicht. > >>Die Lücke tut weh, zumindest wenn sie zur Bytedauer hinzukommt. Wenn ich >>es so erreichen könnte, dass die zwei Takte dem letzten Bit im Byte >>fehlen, dann wärs super, aber ich weiß nicht wie. > > Geht nicht. Entschuldigung, Falk, aber deine Posts sind destruktiv und inhaltlich ja teils nichtmal korrekt. Bitte nicht persönlich nehmen, aber das ist nunmal nicht hilfreich. Die erste abschmetternde "Gar nicht"-Aussage im zitierten Post wurde ja von Mark L. und Peter Dannegger schon wiederlegt. UART ohne Start und Stop geht doch: AVR Typ wechseln und UART in den SPI-Mode schalten. Laut Datenblatt geht damit ein kontinuierlicher Datenstrom. Praxistest folgt, wenn ich das IC hab. Das zweite "Geht nicht" hab ich ja selbst schon widerlegt: Mit dem rechtzeitigen Abschalten des SPI per Hardware (!SS-Pin im Slave-Mode) während das Byte noch nicht ganz raus ist, und Wiedereinschalten des SPI fürs nächste Byte kann ich auch mit dem standard SPI einen Datenstrom ohne Lücke ausgebenen. Das steht hier vor mir und bei Bedarf könnte ich ein Bild vom Oszi machen. Läuft derzeit auf einem Mega16, habs auch mit dem Mega8 schon gemacht. Hier ist das Aber, dass ich damit nicht viel mehr als 0,5 MBaud schaffe, aber man kann nicht sagen, dass es prinzipiell nicht geht.
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.