Hallo zusammen, für ein Testprojekt habe ich mir den Microchip 23LCV* (seriellen SDRAM) bestellt. Da ich über diese Bauteile im Forum null Einträge gefunden habe ein kurzes Intro: Die Chips gibt es u.a. im handlichen PDIP-8 Format und in verschiedenen Größen, ich habe die 512kbit (64kb) und 1Mbit (128kb) Varianten bestellt. Die CHIPS werden über SPI angesprochen: MODE 8bit ADRESSE 16/24bit DATEN 8bit (BYTE Operation Mode) Die Maximale Frequenz liegt bei 20MHz und die Spannungsversorgung 2,5 bis 5,5 Volt. Diese spezielle Ausführung unterstützt eine Backup-Stromversorgung um den Speicherinhalt zu erhalten. Obwohl ich für dieses Projekt die Backup-Versorgung nicht brauche, scheinen die Chips ohnehin eine bessere Lösung für Projekte, wo sonst der EEPROM alle paar Wochen kaputt geschrieben ist. Abgesehen davon waren die anderen Typen ohne Backup zum Teil nicht lieferbar und nur ein paar 10Cent billiger. Nun aber zum Thema: Die Speicher sollen als externer FIFO (Byte) herhalten. Die Taktfrequenz des Prozessors wird bei 18,432 MHz liegen und es sind, wer hätte es gedacht, 11520 Bytes/sec zu speichern (wird ggf. noch verdoppelt). Damit liegen zwischen den Schreibzyklen 1600 Systemtakte, innerhalb dieser Takte muss natürlich (mindestens) dieselbe Menge an Bytes auch wieder aus dem Speicher geholt werden. Obwohl mir der 128kb Speicher für die Anwendung besser gefällt sind pro Schreib-Lesezyklus 2 Bytes mehr zu übertragen (Adresslänge), hier ist der 64kb Speicher klar ökonomischer, da ich nur grob überschlagen habe, habe ich beide Tyoen bestellt, zur Not kommen 2 64er an den Bus. Das restliche Programm wird nur aus einfachen mathematischen Funktionen, Port-Ausgaben und der Kommunikation via. USART bestehen, beides können ATMEGA328 und der TINY2313 in derselben Geschwindigkeit. Jedoch bin ich mir aus mangelnder Erfahrung bzgl. des SPI unsicher. Der Mega hat hierfür eine vollwertige SPI-Schnittstelle, der Tiny "nur" das USI. Wie wirkt sich dies auf die Prozessorauslastung aus? Machen es beide in "Hardware" oder nur der Mega? Noch eine weitere Frage (eigentlich die gleiche): Beim 512 er muss ich pro Byte schreiben/lesen 64bit übertragen -> 11520x64 = 737280 bit/s -> 1/25 F_CPU (rechnerisch) Beim 1024 er muss ich pro Byte schreiben/lesen 80bit übertragen -> 11520x80 = 921600 bit/s -> 1/20 F_CPU (rechnerisch) also wir der SPI in jedem Falle mit 1/16 F_CPU arbeiten müssen. Ist es realistisch zu erwarten, das da noch ein "Echtzeit"-Programm parallel laufen kann? (Falls nicht hat der Chip ja noch 2 andere Modi ;-) ) Gruß Dominik
:
Bearbeitet durch User
Hilft dir das hier als Antwort? http://forum.arduino.cc/index.php?topic=225052.msg1658174#msg1658174 Ist gleich Sample-Code für ATmega328 mit bei, wie du den Speicher ansprichst. (Habe den 1MBit.) Geht ordentlich was durch, weit mehr als 11 kByte/s. Edit: Grade gesehen, du willst Byte für Byte schreiben/lesen und jedes mal mit Adresse ansprechen. Mit solch einem Setup und den Arduino-Libraries bin ich etwa auf 8 kByte/s gekommen. Vielleicht lässt sich da ein wenig durch direkte µC-Programmierung rausholen oder durch Gruppierung mit einem kleinen Puffer.
:
Bearbeitet durch User
Ich denke, Dein Systemdesign ist ziemlich auf Kante genäht. Ich empfehle Dir einen dsPIC33EP512GP502 oder einen PIC32MX250F128B, beides auch 28 Pinner, mit 16 Bit/70 MHz/48k bzw 32Bit/50MHz/32k RAM intern. Der große Vorteil ist, dass diese Prozessoren DMA-Controller eingebaut haben, die Daten von/zu einer Peripherieeinheit ohne Prozessorhilfe quasi im Hintergrund übertragen können. Das und der große interne Speicher vereinfachen vieles. Außerdem hast Du eine erheblich höhere Prozessorleistung, und das alles für nur 2€ mehr. fchk
Hi, Dirk K. schrieb: > Hilft dir das hier als Antwort? > http://forum.arduino.cc/index.php?topic=225052.msg1658174#msg1658174 ja, das sieht auf jeden Fall schon einmal vielversprechend aus, leider habe auf diesem Rechner keinen gescheiten Editor und habe die C-Datei nur als Zeichenwolke, scheint aber mit 16MHz zu laufen im sequential Mode, da ich im Atmega-Datenblatt nichts über DualSerialMode gefunden habe wohl in SPI. Aber der Datendurchsatz sieht in diesem Falle ja gar nicht so schlecht aus. Dirk K. schrieb: > Grade gesehen, du willst Byte für Byte schreiben/lesen und jedes > mal mit Adresse ansprechen. Mit solch einem Setup und den > Arduino-Libraries bin ich etwa auf 8 kByte/s gekommen. Vielleicht lässt > sich da ein wenig durch direkte µC-Programmierung rausholen oder durch > Gruppierung mit einem kleinen Puffer. Ja, "direkte" µC-Programmierung nicht ganz, ich nutze eigentlich lieber C wie Assembler, in letzteres müsste ich mich auch erst wieder reinarbeiten. Diese Gruppierung schwebte mir auch schon vor, ggf. im µC jeweils zwei Pages vorhalten, die könnte man dann schonmal in akzeptabler Geschwindigkeit lesen, allerdings müssen diese dann auch noch im Hintergrund mit den FIFO-Grenzen konsistet gehalten werden. Wenn ich die 456kbyte/s seq. bei 16MHz mal auf 18,432MHz byte umrechne komme ich auf etwas um die 105kB/s (456/16/18,432/5)? Frank K. schrieb: > Ich denke, Dein Systemdesign ist ziemlich auf Kante genäht. > > Ich empfehle Dir einen dsPIC33EP512GP502 oder einen PIC32MX250F128B, > beides auch 28 Pinner, mit 16 Bit/70 MHz/48k bzw 32Bit/50MHz/32k RAM > intern. Der große Vorteil ist, dass diese Prozessoren DMA-Controller > eingebaut haben, die Daten von/zu einer Peripherieeinheit ohne > Prozessorhilfe quasi im Hintergrund übertragen können. Das und der große > interne Speicher vereinfachen vieles. Außerdem hast Du eine erheblich > höhere Prozessorleistung, und das alles für nur 2€ mehr. Ich habe sowohl einen 32MX150F128B-ISP als auch einen 32MX210F016B-ISP hier liegen, kam mir aber, außer in Anbetracht des großen Speichers, etwas wie mit Kanonen auf Spatzen schießen vor und zudem konnte ich mich mit dem MPLAB noch nicht so ganz anfreunden ;-) Gruß Dominik
Vorsicht mit den MHz/SPI auf dem Arduino-Krempel. Der ATmega328 wird mit 16MHz extern auf Trab gebracht. SPI ist damit erstmal 4 MHz maximal (F_CLK/4 laut Datenblatt), in einem zweiten Register kann man aber SPIx2 setzen und somit auf 8 MHz "aufrüsten". Da deine Rechnung aber relativ ist, kommt das mit dem Verhältnis hin ;) Außer natürlich - wo kommt die 5 her? ich schreibe ganz normal seriell in ein SPI-Modul. Ist eines voll, schalte ich einfach auf das nächste. Oder willst du einen 5-Byte-Puffer nutzen?
:
Bearbeitet durch User
Hallo Dirk, Dirk K. schrieb: > Vorsicht mit den MHz/SPI auf dem Arduino-Krempel. Nein, einen Ardudingsbums habe ich nicht ;-) Dirk K. schrieb: > er ATmega328 wird mit > 16MHz extern auf Trab gebracht. SPI ist damit erstmal 4 MHz maximal > (F_CLK/4 laut Datenblatt), in einem zweiten Register kann man aber SPIx2 > setzen und somit auf 8 MHz "aufrüsten". Da deine Rechnung aber relativ > ist, kommt das mit dem Verhältnis hin ;) Sowohl ATmega328 als auch ATiny2313 laufen mit Grundtonquarz auf 18,432 MHz stabil in den jetzt wieder vor mir stehenden Steckbrettern. Meine ursprüngliche Sorge galt eigentlich den Prozessortakten, die dem SPI zum Opfer fallen, bei dem ATmega scheinen dies in der Tat nur die Registerabfragen und Schreiben/Lesen des Datenregisters zu sein, beim ATTiny hatte ich Zweifel, jedoch scheint dort zwar der TIMER0 geopfert werden zu müssen, aber das Byte wandert dann ja wohl doch im Hintergrund (hardwaremäßig) über die Leitung. Ja, jetzt habe ich auch den(deinen?) Quelltext mal in formatierter Form gesehen, also: SPCR-> SPI on, Master, F_CPU/4 SPSR-> 2x Ok, dann läuft der SPI tatsächlich mit 8MHz, befüllt wird über for-schelife mit eigenen Funktionsaufrufen write... Der Bus selber sollte in der Konfiguration ca. 1000k transportieren können, limitierend ist logischerweise das Hauptprogramm. Meine Überschlagsrechnung, die sich auf die relative Datenmenge bezog, wirkt sich, da sie auf dem Prozessortakt aufsetzt, also wahrscheinlich (zwar nur bei diesem Programm) genau so aus, die /5 ist der Unterschied zwischen sequential und byte: 8 bit Daten (Mode 8 && Adresse 20 nur einmal, daher vernachlässigbar) zu 40 bit Daten (mode 8 Adresse 24 daten 8). Wie sieht denn bei dieser relativ hohen Anbindung von 8MHz die Infrastruktur aus? Lang dürfen die Leitungen dann doch sicher nicht mehr sein - oder? Gruß Dominik
Meine Verbindungskabel habe ich aus Klingeldraht selber gebastelt. An der Platine des µC kommen dann 5-7cm Anschlussdraht. Die Speicherbank selber führt die Leitungen dann via Silberdraht weiter, nochmal etwa 7cm. Trotz der 8 MHz, einiger böser Lötstellen und ähnlichem aber problemlos, was die Signalqualität anbelangt. Die 1mByte/s hatte ich auch gehofft, aber es scheint so, dass die 8 MHz nochmal halbiert werden müssen - eine "Vollwelle" ist ja ein Takt an, einen aus, sozusagen. (Bin kein Elektroniker, daher bitte die schlechte Erklärung (aus meinen laienhaften (un)Verständnis) nachsehen.)
:
Bearbeitet durch User
Hallo Dirk, das lässt hoffen, dass ich ähnliche Resultate erziele. Der Datendurchsatz wird wohl ausreichen, habe den USART im Moment bei 16k, Protokoll und Blockgröße werde ich aber noch optimieren. Eine Frage habe ich noch, hast Du beim Ansprechen im Byte-Modus dem Speichers ein Dummy-Byte zum Daten abholen geschickt oder den nächsten Instruction-Befehl? (macht ja bei dem Speicher schon 20% Performance-Unterschied aus) Geht das? Gruß Dominik
Hallo Dirk, Warum ich gefragt habe... Nachtrag: Siehe Anhang MAP004 - 7 bytes Siehe Anhang MAP007 - 8 bytes Sollte also die nächste Instruction parallel zum Datenabruf möglich sein, funktioniert mein Systemdesign mit dem 512er Speicher im BYTE-Zugriff, ansonsten muss ich generell auf PAGE oder SEQUENTIAL umsteigen. In den Beiden OSZI-Abdrücken sieht man es im oberen Signalverlauf des MOSI (unteres Signal UART bei 17k), bei 7 byte ist noch Platz, bei 8 byte ist es sehr auf "Kante genäht". Der SPI arbeitet hier schon mit 2 er Teiler = 9,216 MHz. Gruß Dominik P.S.: Doppel-Anhang-Post, sorry hat die Änderung im vorherigen Beitrag wohl doch übernommen.
:
Bearbeitet durch User
Hallo Dominik, dem Speicher ist es egal, was du ihm als Dummy-Byte im READ-Modus schickst. Nur wird er den Befehl nicht als solchen erkennen dann. Zum Befehl absetzen musst du immer CS auf HIGH setzen, CS wieder LOW setzen, Befehl und Datum schicken, wieder das HIGH/LOW-Spiel ... Also das weitere komprimieren der Kommunikation klappt so leider nicht. Pagemode mit einem 32-Byte-Puffer klingt doch ok. Oder eben Sequential Mode, wenn du nicht jedes Datum sofort wieder lesen musst, sondern einfach erstmal nur Daten wegspeichern willst. Das spart dann maximal Overhead.
:
Bearbeitet durch User
Hallo Dirk, Dirk K. schrieb: > dem Speicher ist es egal, was du ihm als Dummy-Byte im READ-Modus > schickst. Nur wird er den Befehl nicht als solchen erkennen dann. Zum > Befehl absetzen musst du immer CS auf HIGH setzen, CS wieder LOW setzen, > Befehl und Datum schicken, wieder das HIGH/LOW-Spiel ... stimmt, habe es gerade im Sequenzdiagramm gesehen. Ansonsten war die Idee ja nicht schlecht. > Pagemode mit einem 32-Byte-Puffer klingt doch ok. Oder eben Sequential > Mode, wenn du nicht jedes Datum sofort wieder lesen musst, sondern > einfach erstmal nur Daten wegspeichern willst. Das spart dann maximal > Overhead. Denke so werde ich es machen, dann ist es ja prinzipiell auch total egal ob ich den 512k oder 1M Speicher nehme, die Zeiger haben in beiden fällen immer die gleiche Größe. Hast Du den µC mittels SPI programmiert? Macht es Probleme den Speicher am Bus zu lassen? Denke mal der funkt dann alle x byte mal dazwischen, also CS mit Pull-Up und Jumper vorsehen, oder? Gruß Dominik
Das Board habe ich per USB programmiert, ist ein schön fertig aufgebauter Arduino Nano (oder auch Pro Mini). Im Wesentlichen ist das USART mit Rx/Tx via USB-Seriell-Wandler. Die SPI-Peripherie kannst du dran lassen, auch wenn du den ATmega darüber programmierst. Die Chips funken nichts, wenn sie nicht gefragt werden; denen ist auch alles auf den Leitungen egal, sofern du nicht mit dem CS-Finger auf sie zeigst. :)
:
Bearbeitet durch User
Hallo Dirk, Dirk K. schrieb: > Das Board habe ich per USB programmiert, ist ein schön fertig > aufgebauter Arduino Nano (oder auch Pro Mini). Im Wesentlichen ist das > USART mit Rx/Tx via USB-Seriell-Wandler. > Die SPI-Peripherie kannst du dran lassen, auch wenn du den ATmega > darüber programmierst. Die Chips funken nichts, wenn sie nicht gefragt > werden; denen ist auch alles auf den Leitungen egal, sofern du nicht mit > dem CS-Finger auf sie zeigst. :) stimmt ja, die SS/CS Leitung ist ja gar nicht mit dem programmieradapter verbunden, also mache ich dort einen pull-up dran, spart sogar eine Zeile quelltext ? Gruß dominik
Hallo zusammen, Hallo Dirk, die Speicherchips sind gestern schon von Mikrochip-Direkt aus Thailand eingetroffen, super verpackt und super schnell. Preislich auch dtl. unter den Resellern (wobei die meisten diese Chips auch gar nicht im Sortiment haben). Ich habe dann gestern mal einen ersten Versuch im Byte-Mode gemacht, Der ATMGEA schreibt die USART-Daten direkt per SPI in den Chip, nachdem die 128k abgespeichet sind, liefert er diese auch direkt wieder per USART aus (Quick n´dirty): void LCV_PushByte(uint8_t data) { LCV_PORT &= ~(1<<LCV_CS); //SS/CS auf low SPI_MasterTransmit(LCV_WRITE); //Write Instruction SPI_MasterTransmit(lcvWritePointer>>16); //24bit-Adresse 23LCV1024 SPI_MasterTransmit(lcvWritePointer>>8); //16bit-Adresse 23LCV512 SPI_MasterTransmit(lcvWritePointer); SPI_MasterTransmit(data); LCV_PORT |= (1<<LCV_CS); //SS/CS auf high lcvWritePointer++; if(lcvWritePointer==131072UL) lcvWritePointer=0; lcvUsed+=1; } do //Hauptprogramm { while(lcvUsed<131072L) { while( !(UCSR0A & (1<<RXC0)) ); LCV_PushByte(UDR0); } while(lcvUsed>0) { while(!(UCSR0A & (1<<UDRE0))); UDR0=LCV_PullByte(); } } while(1); (Die Pull-Funktion ist der Push-Funktion weitestgehend ähnlich.) Bei dieser Vorgehnsweise limitiert im Moment der USART den Datendurchsatz auf 23k (Übertragen: 128blöcke 262144byte Zeit=11.375s Byte/s=23045.626373626375). Der SPI-Bus läuft bei 9.216 MHZ auf einem Breadboard. LOL. Die Oszi-Abdrucke zeigen oben MOSI und unten MISO. Es ist also bei so einer Vorgehensweise noch reichlich Platz auf dem Bus. Allerdings nicht genug um gleichzeitig zu lesen, selbst wenn das restliche Programm 0 Takte verbrauchen würde. Mit dem 512er würde es so gerade gehen. Aber das war ja nach den Berechnungen im Vorfeld schon klar. Ansonsten gefällt mir der 23LC*XXXX schonmal echt spitze. Insbesondere da er nur die gleichen Pins + CS belegt, die ohnehin für den ISP reserviert waren. Frage an die C-Profis: Die If-Abfrage in der PUSH-Funktion gefällt mir pers. garnicht, allerdings bekomme ich immer nur Datenmüll wenn ich die bedingte Zuweisung =()?: mit 32 bit Variablen nutze, weiß einer woran das liegen kann, war bis jetzt eigentlich immer ein Problem. Gruß Dominik
:
Bearbeitet durch User
Hallo Dirk, kleine Ergänzung, so sieht es auf dem Bus aus wenn man in den SEQENTIAL-MODE umschaltet (allerdings bei gleichem Hauptprogramm). So jetzt muss ich das ganze noch Interrupt-Save machen ;-) Danke für die Hilfestellungen. Gruß Dominik
Dominik V. schrieb: > Frage an die C-Profis: Die If-Abfrage in der PUSH-Funktion gefällt mir > pers. garnicht, allerdings bekomme ich immer nur Datenmüll wenn ich die > bedingte Zuweisung =()?: mit 32 bit Variablen nutze, weiß einer woran > das liegen kann, war bis jetzt eigentlich immer ein Problem. Mach doch einfach lcvWritePointer&=131071UL; Damit hast Du eine konstante Laufzeit.
Sequential sieht doch super aus! :) Schön, dass es funktioniert :)
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.