Hallo zusammen, ich habe mal eine Frage an euch. Ich möchte mit einem LPC2468 ein monochrom STN-Display ansteuern. Im Idealfall soll ein Schachbrettmuster erzeugt werden. Ein LCD-Controller steht nicht zur Verfügung. Der Controller so "nur" das Display ansteuern. Hier das Displaydatenblatt: beyondinfinite.com/lcd/Library/Kyocera/KG057QV1CA-G00.pdf Mein erstes Problem ist, wie ich das Timing überhaupt erzeugen soll, ich brauche auf jeden Fall mal einen Pixelclock (CP), FRM, LOAD und dann noch die Daten. Als Entwicklungsumgebung habe ich IAR Embedded Workbench for ARM 4.5, falls das wichtig sein sollte. Für Ideen wäre ich sehr dankbar! Gruß Chris
Muß es unbedingt der LPC2468 sein? Der LPC2478, der zum LPC2468 identisch ist, aber noch einen LCD-Controller integriert hat kann das von Haus aus. Damit kannst du auch mehrere Graustufen erzeugen.
Hallo Kai, ja es muss ohne LCD-Controller gehen. Denn der gleiche Code muss auch auf einem LPC1768 (Cortex-M3) laufen, dieser hat leider kein LCD Controller. Gruß Chris
Tja, mit einem ARM7 lässt es sich wohl nur vernünftig im Hauptprogramm mit verschachtelten Schleifen machen, da der ARM7 zu lange braucht um in eine ISR rein und wieder raus zu kommen, d.h. du schaffst da die nötige Frequenz nicht. Mit einem Cortex M3 ist es natürlich etwas anders. Dort könntest du das ganze Timing mit einer Timer-ISR machen, die mit 1,44MHz feuert. Allgemein gilt: Sieben IO-Pins als Ausgang definieren und entsprechend dem Timingdiagramm auf Seite 13 (bzw. 10 lt. Seitenzahl im PDF) an diesen Pins wackeln.
Hallo Kai, also ist es eher nicht ratsam mit der Capture/Compare Einheit zu arbeiten, da diese wohl zu lagsam ist, sehe ich das so richtig. Da bleibt mir dann also nur die Möglichkeit die High-Speed GPIOs zu benutzen? Gruß und danke dir schon einmal für deine Beiträge Chris
Mit der Capture-Funktion kannst du ja auf Zustandswechsel der CAP-Pins reagieren, d.h. den aktuellen Timer-Wert bekommst du in ein Register kopiert und du kannst einen Interrupt auslösen. Das bringt dir hier aber nichts. Wenn du nur ein Schachbrettmuster ausgeben willst, dann könnte es mit der Match-Funktion und -Pins der Timer gehen, aber das wirst du ja kaum wollen. Um etwas sinnvolles darzustellen brauchst du dann die FastIOs, die man mit bis zu ~15MHz schalten kann. Hast du ein Board mit dem LPC2468 drauf, oder willst/musst du das auch noch entwerfen?
Hi Kai, ich habe das Board schon. Das ist von der Firma Future Electronics, ein Mainboard (Longbow) + CPU-Board mit LPC2478. Habe gerade gemerkt das es der 2478 und nicht 2468. Das ändert aber nichts an der Sache, da ich den LCD-Controller nicht benutzen kann(Vorgabe). Habe jetzt schon mal mit den FIOs gespielt, allerdings komme ich nur auch eine Frequenz von ca. 10MHz. Ich lasse da in einer Endlosschleife einen GPIO von Port 3 setzten und wieder rücksetzen. Wenn ich jetzt noch andere GPIOs zappeln lasse, geht die Frequenz doch recht schnell runter... so übern Daumen ca. 2MHz. Evtl. hast du noch eine Idee, wie ich den Programmaufbau machen kann, werde da Morgen weiter testen. Aber vielen vielen Dank dir, das hilft mir wirklich weiter deine Beiträge. Gruß Chris
Am besten ist es, wenn die notwendigen Pins alle in einem Port liegen, so kannst du auch alle mit einem Befehl verändern. Wie sind die sieben Pins denn zugeordnet? Mit welcher Frequenz läuft der LPC24xx eigentlich?
Ja das habe ich schon mal getestet habe 4GPIOs von Port3 gleichzeitig gesetzt und rückgesetzt. Das ganze habe ich mit FIO3DIRU=0x2A80 gemacht, für P3.23, P3.25, P3.27, P3.29. Für meine Datenbits(D0-D3) wollte ich das so machen, mir ist jetzt nicht ganz klar wie ich die benötigten Takte erzeugen soll. CP ist ja der schnellste, dementsprechend müssen die anderen ja verzögert werden. Das z.b. die fallende Flanke von CP die Daten detektiert. Der LPC2478 soll mit maximal Takt laufen, also 72MHz. Kann ich eigentlich irgendwie überprüfen, ob er das auch macht, also mit dem Oszi prüfen??? Gruß Chris
Direkt mit dem Oszi prüfen kannst du den Takt nicht. Dazu könntest du aber eine Timer-ISR schreiben und innerhalb der ISR einen Pin toggeln. Wenn du den Timer nun mit sinnvollen Werten initialisierst, dann müsste der Pin auch sinngemäß toggeln. Achtung: Der Timer als Peripherieblock besitzt auch einen eigenen Taktteiler (PCKSEL0 und PCLKSEL1). Der Rest morgen.
Hier mal ein Beispielcode für die Ansteuerung. Der Code geht davon aus, dass alle betreffenden Pins im Port3 liegen. Weiterhin mußt du noch die sieben Defines am Anfang an deine Pinzuweisungen anpassen. Eventuell ist es auch noch notwendig die Zeilen
1 | for (iDelay=0;iDelay<DELAYLOOP;iDelay++) __asm("nop"); |
anzupassen, da der IAR diese Notation __asm() evtl. nicht unterstützt. Wenn der Delay zu kurz oder zu lang ist, dann einfach das Define DELAYLOOP anpassen. Außerdem muß darauf geachtet werden, dass der Compiler diese scheinbar unnötige Zeile nicht wegoptimiert!
Hallo Kai, habe hier mal meinen Code angehängt, wo ich 4 Bits gleichzeitig toggeln lasse. Mir ist nicht klar warum ich kein gleichmäßiges Rechtecksignal erhalte, siehe Oszibild. Gruß Chris Edit: Wow, habe gerade erst gesehen, das du geschrieben hast. Da werde ich mich gleich mal ran machen, um es zu testen. Danke!!!!
Code von mir habe ich oben angehängt, siehst du diesen nicht?
Teste gerade deinen Code, hab ich die Defines so richtig #define PIN_D0 0x02000000 //P3.25 #define PIN_D1 0x00800000 //P3.23 #define PIN_D2 0x20000000 //P3.29 #define PIN_D3 0x08000000 //P3.27 Beim Complieren kommen dann lauter Warnungen in dem TranslatedData-Array, siehe hier "Warning[Pe069]: integer conversion resulted in truncation" Ich muss jetzt noch 3 GPIOs von Port3 auf dem Board suchen.....
Habe deinen Code übersehen. TranslatedData muß unsigned long sein und nicht unsigned char. Mein Fehler.
1 | const unsigned long TranslatedData[16] = ... |
Das ungleichmäßige Tastverhältnis in deinem Code ist übrigens einfach zu erklären: 1. Pins auf low setzen 2. Pins auf high setzen 3. Rücksprung an den Anfang der while-Schleife 1. Pins auf low setzen 2. Pins auf high setzen 3. Rücksprung an den Angang der while Schleife Der Rücksprung und ggf. noch die Prüfung ob 1 auch wirklich != 0 ist (je nach Compiler und Optimierung) benötigt halt auch noch etwas Zeit und damit ist der High-Pegel länger als der Low-Pegel. Deine Defines sehen erstmal richtig aus, vorausgesetzt, dass die Pins auch so zugeordnet sind.
Hallo Kai, so bei den Daten tut sich schon mal was :-) Jetzt muss ich auf dem Board mal 7 GPIOs auf einem Port suchen, dann kann ich weiter testen. Du bist echt klasse, danke schön das du dir die Mühe mit einem Anfänger machst!!!!
Hallo Kai, ich habe ein 4x4 Schachbrettmuster :-) juhu Ich habe bestimmt mal noch eine Frage zum Programm, werde es mir Morgen genau anschauen. Ich hoffe ich darf dich dann nochmal Fragen. Einen schönen Feierabend wünsche ich dir, Chris
Es freut mich, dass es jetzt so gut geklappt hat. Wichtig ist, dass du versuchst das Programm zu verstehen. Hast du mal die Frequenz von FRM gemessen? Idealerweise sollte die zwischen 70 und 80 Hz liegen. LOAD müsste dann beim 240-fachem, d.h. 16,8-19,2 kHz liegen und CP beim 80-fachem von LOAD bzw. 19200-fachem von FRM, d.h. bei 1,344-1,536 MHz. Sollten die Werte gravierend davon abweichen, so muss du da nochmal was im Programm ändern.
Hallo Kai, ja werde dann jetzt versuchen dein Programm zu verstehen. FRM habe ich jetzt noch nicht gemessen, aber ein wenig flackert das Bild, das liegt dann wohl an einer zu niedrigen FRM-Frequenz. Werde Morgen nochmal alle Signale durch messen, glaube CP lag bei 2MHz. Da bin ich mir aber nicht 100%ig sicher. Ich schau Morgen nochmal... Nochmals besten Dank dir!!!!!!!!!
So habe jetzt mal die Signale gemessen: FRM = 33Hz CP = 645kHz LOAD = 7,8kHz Anbei auch 3 Oszibilder: 1tes Bild = ganzer Frame 2tes Bild = Frame Anfang 3tes Bild = Frame Ende Könntest du mir noch sagen, wieso du auf den Wert von 9600 beim ScreenBuffer kommst? Ich bin noch am analysieren... sehr elegant hast du das gemacht mit dem schieben. Ganz hab ichs aber noch nicht verstanden, ich teste dann mal weiter. Gruß Chris
Ok ich habs, es sind ja 320bit=40byte pro Zeile, dann noch 240 Spalten --> 40byte * 240 = 9600byte = 768000bit für den Screenbuffer Hatte ganz vergessen das ja ein char 8bit breit ist. oh man....
Dein Display ist hat eine Auflösung von 320x240x1bpp = 76800bit = 9600Byte. Reduzier mal das Define DELAYLOOP auf 1 oder 2 und schau, ob du damit mit den Frequenzen in den vorgegeben Bereich kommst. Edit: Na da hast du's ja selber. :-)
DELAYLOOP 4 //Bild flackert stark FRM = 33Hz CP = 645kHz LOAD = 7,8kHz DELAYLOOP 2 //Bild flackert wenig FRM = 45,8Hz CP = 880kHz LOAD = 11kHz DELAYLOOP 1 //Bild steht FRM = 66,4Hz CP = 1,22MHz LOAD = 16kHz
Naja, mit DELAYLOOP 1 bist du doch schon sehr nah an den geforderten Werten. Mich würde jetzt nurnoch interessieren, ob der LPC24xx auch wirklich auf 72MHz läuft, weil mir 60 Takte für einen Pixel (bzw. vier) doch recht viel vorkommen, aber das kann auch täuschen.
ersetze die for (iDelay=0;iDelay<DELAYLOOP;iDelay++) __asm("nop"); mit __asm("nop"); dann wird noch schneller, die for schleife kostet auch zeit.
Ja das ist wirklich schon sehr gut von den Werten. Habe mir jetzt alles mal ausführlich dokumentiert, wenn ichs dann ganz fertig habe, darfst du gerne mal drüber schauen. Also 60Takte pro Pixel, hast du 72MHz / 1,2MHz gerechnet, oder? Ja das würde mich auch interessieren, ob der LPC2478 wirklich auf 72MHz läuft. Du hattest ja oben was von Timer-ISR geschrieben, da was ich wieder nicht so recht wie ich das machen kann. Grüße Chris Edit: Ja ok das macht sinn, nur den nop-Befehl zu nehmen. Kann das allerdings erst am Montag testen..
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.