hallo leute, ich hab problem mit der ansteuerung eines 240*64 dots LCD. das display sitzt auf einer fertigen sharp-applikation worauf der toshiba t6963c controller zur ansteuerung genutzt wird. als erstes wollte ich ganz banal irgendein zeichen aufs display schieben. nur die erforderliche statusabfrage des toshibas scheint ein stolperstein zu sein, da dieser bei der abfrage keinen status ausgibt und folglich das proggi (anhang, in C) nicht weiterläuft. es bereitet mir auch etwas kopfzerbrechen zu verstehen, wie die ausgabe auf das display (aus dem speicher) funktionieren soll...ich verstehe es so, dass ich mein zeichen per pointer-gedöhns in den speicher schreibe und der controller (also der t69...) übernimmt den rest - sehe ich das flasch? ich hoffe ihr könnt helfen pumpkin p.s. doch doch, ich hab das datenblatt studiert, aber grundlegende fragen bleiben für mich dennoch offen (vgl oben). und: ich weiss dass es fertige assembler codes gibt, aber ich will es in c SELBER erarbeiten. ; )
vllt sollte ich erwähnen, dass es sich um die statusbits STA0 & STA1 handeln (so wie im manual beschrieben). und: ich habe mich weitestgehend an die init-sequence aus dem sharp datenblatt gehalten (was ich auf anfrage gerne reinstelle - ist aber keine wirkliche hilfe o,0). pumpkin
Hallo!! Ich hab dir mal den Code von meinem Display ran gehängt. Verwende den gleichen LCD Controller wie du, jedoch einen PIC zur Ansteuerung. Sorry, aber aus Zeitmangel, kann ich mir deinen Code nicht durchlesen. Bei mir funktioniert die Ansteuerung tadellos. Die Init und Low-Level Routinen kannst sicher 1:1 übernehmen, in einigen meiner Funktionen ist jedoch etwas bullshit drin, den ich für eine spezifische Applikation benötige. Du wirst es aber sicherlich merken, was ich meine...
: ) das sieht doch prima aus. vielen dank erstmal. hab erstmal einen kleinen fehler in meiner denkweise entdeckt - hoffe ich jedenfalls (--> erst datencode/befehlscode mit CS raus und erst dann RD/WR ?!? was ist mit dem CD? muss ja vorher an, richtig?). wäre aber klasse, wenn du dir meinen code mal anschauen könntest (um ihn anschließend in der luft zu zerfetzen ; ) ). pumpkin
Also prinzipiell sieht es so aus: # Adress- und Datenbus setzen # CS auf Low setzen # RD/WR auf Low --> zu diesem Zeitpunkt wird der Wert am Adress/Datenbus in den T6963C geschrieben CD wird verwendet um zwischen Befehl und Daten hin und her zu schalten. Warte mal, ich werd kurz drüberfliegen...
1.) Kann man in deinem Compiler die Steuerleitungen nicht als Port-Pins definieren? Immer PORTD zu verwenden ist sehr mühsam zu lesen. 2.) free_sequence scheint mir völlig sinnlos. Steht das im Datenblatt, dass man es so machen sollte? 3.) Du liest das Statusbit falsch. Wenn du den Status lesen willst, musst bei jedem Lesezyklus RD toggeln. Versuch mal meine Routine zu kopieren und teste den Code noch einmal. Wenn das nicht funktioniert werd ich weiterlesen.
ich könnte anstatt PORTD was anderes schreiben, klar. hab aber keine lust ; ) die free_sequence() ist meines erachtens nicht nötig...war nen 'verzweiflungs-debug-versuch'. du verstehst wahrscheinlich was ich meine ^^ . steht aber auch dran. meines erachtens toggle ich das readbit: **** PORTD = 0b11111001; //chip enabled & read enabled **** beim rausgehen setze ich es wieder auf high. timing falsch/nötig? in der whileschleife danach hängt er - es regt sich nix; weder STA0 noch STA1. pumpkin
DDRB = 0xFF; //PORTD ist wieder ausgang --> nur so nebenbei... müßte PORTB heißen Was passiert hier: while( !(PINB & (1 << 0)) || !(PINB & (1 << 1)) ) Bin mit deinem Compiler und µC nicht vertraut, was ist PINB? PORTD wird nicht zurückgesetzt --> kein RD toggeln Jedes mal wenn du das Statusregister ausliest musst du RD wieder auf LOW setzen, du tust das nicht!!!!!
was allgemeines: controller ATMega323 auf STK500 mit AVR Studio 4.xx ja, du hast recht, der kommentar ist falsch - hab im nachherein die ports vertauscht. egal. PINB sind die portpins vom PORTB (datenbus). ich rufe an dieser stelle deren status ab (um genau zu sein die pins 0 und 1). er compared (&) pin0 mit HIGH und pin1 mit HIGH. solange einer von beiden noch false ist (||), rotiert er. isn bissl kompliziert codiert. aber reicht ja für den anfang. ui, schiiit. du hast ja recht, RD wird garnich widerrufen. für sowas hatte ich die free_sequence() angedacht. executed er erst wenn ich zurück toggle? kann ich mir nich vorstellen. :o/ ich werd es heute nachmittag ausprobieren. pumpkin
*** Jedes mal wenn du das Statusregister ausliest musst du RD wieder auf LOW setzen, du tust das nicht!!!!! *** öhm, hast du dich verschrieben oder meinst du tatsächlich LOW? - ich komme rein - ich ändere die datenrichtung des busses (hin als eingang) - ich setze CS und RD auf LOW (zeitgleich) - ich warte auf die bits (vllt bis zum jüngsten tag) (- ich erhalte die bits) - ich dreh ne kleine ehrenrunde (***DEBUG***) - ich ändere wieder die datenrichtung des busses (zu ausgang) - ich ändere NOCH nicht CS und RD zu HIGH (!!).... pumpkin
Siehe einfach in meinem Code statusRead_T6963C(); # Datenbus auf Eingang # CS auf LOW # RD auf LOW # Datenbus lesen # RD auf HIGH # CS auf HIGH # Datenbus auf Ausgang und diesen Ablauf führst so lange aus bis die Bits entsprechend in dem Byte gesetzt sind, das du vom Bus gelesen hast. (siehe statusCheck1_T6963C()) Du darfst nicht auf die Bits warten!!!! Die ändern sich nur am Datenbus, wenn sie eine fallende RD Flanke haben!!!!!!! Deswegen muss die Sequenz (siehe oben) so oft ausgeführt werden, bis die Bits sich geändert haben.
Hallo, @pumpkin vielleicht mal so allgemein: so ein Display ist auch nur ein Mensch. ;) CS ChipSelect sagt dem Display, daß es gemeint ist. Das kann prinzipiell aktiv (L) bleiben, solange der Bus (hier speziell RD/WR/CD) nicht auch noch anderweitig benutzt werden. RD und WR sind Impulse mit Mindestlängen, die dem Display sagen, was ich von ihm will. Mit WR sage ich ihm, daß jetzt gültigen Daten an D0-D7 anliegen und es die bitte lesen soll. Natürlich darf ich diese Daten nicht verändern, während WR aktiv ist, darauf verlässt sich der Hersteller des Displays. Bei RD sieht es genauso aus. MIT RD auf L sage ich dem Display, daß ich Daten lesen will, es stellt diese an D0-D7 bereit und darf diese natürlich auch nicht ändern, solange RD aktiv ist, es weiß ja nicht, wann ich die Daten zu lesen geruhe. Wenn sich jetzt von Display irgendwas ändert, werde ich das also erst beim nächten Lesezyklus erfahren, also wenn RD wieder auf L geht. Dazu muß der vorige natürlich beendet werden, also RD auf H. Timingdiagramme im Datenblatt des T6369 sollte man sich spätestens ansehen, wenn der mit 8 oder 16MHz getaktet wird. Dann ist ein nop zwischen RD auf L und dem einlesen der Daten fällig (Tacc max. 150ns), sonst ist man auf Glück angewiesen, daß das Display schnell genug ist. Gruß aus Berlin Michael
!!! andenkopffass is ja nich zu fassen, so doof muss man erstmal sein. kommt ja nich oft vor, aber der groschen ist diesmal wirklich langsam gefallen (aber immerhin ist er jetzt da wo er hin soll). an diesen umstand habe ich garnicht gedacht dass ich den t69 immer wieder auf die füsse treten muss. in deinem code kann ich aber leider nicht erkennen, du hast leider nur die funktion statusRead_T6963C ohne einen aufruf (wenn doch, dann sehe ich jedoch keine schleife). aber die logik gebietet es ja, wie ihr so schön erklärt habt. auweia, peinlich peinlich! X) nun zu meiner anderen frage: ist es richtig, dass ich, wenn ich beispielsweise die '2' ausgeben will, einfach nur den code (als daten) auf den datenport (bei vorher gesetzten pointern) schicke (mode. internal CG)? also: C~D = 0 & ~WR = 0 & ~CS = 0. oder muss ich noch einen execute befehl hinterherschieben? pumpkin
Na klar hab ich die Aufrufe... void statusCheck1_T6963C(void) { while((statusRead_T6963C()&0x03)!=0x03); } Du willst eine ASCII 2 schreiben? Schau mal in meinem Code unter writeString_T6963C da siehst du was du tun musst um einen ASCII string zu schreiben.
hast recht, du hast welche...bin grad erst rein...hab nich nochmal nachgeguckt...aber ich find deine abfrage etwas gefährlich (nich böse sein, ich will auch mal "motzen" ; ) ). du benutzt den automode (set data auto write 0xB0) wenn ich nicht irre. kann ich für einen einzelnen char den data write modus (mit oder ohne in-/dekrement) (0b11000XXX) (seite 11) verwenden, oder haben die nichts miteinander zutun? pumpkin
so leute, ich bin so weit - ich kollabier' gleich spontan! aaah seit geraumer zeit sitze ich vor diesem display welches sich vehement weigert mit mir zu kommunizieren. ich habe in meiner verzweiflung drei quelltexte durchforstet (den von thomas p., den 'originalen' von toshiba und einen aus dem netz)...und finde keinerlei abweichung in der schematik zwischen meinem und den anderen. es funktioniert keinerlei ausgabe, weder 'manuell' noch im automode ('stream'beschickung). das programm rennt normal durch. ausser die letzte version, in der sich das display sogar weigert die ready_ask_2() routine zu beantworten; ergo keine 'stream'beschickung möglich. zudem tritt nunmehr wieder dieses phänomen bei der abfrage von STA3 (ready_ask_2()) auf: http://www.mikrocontroller.net/forum/read-1-411936.html#new ich habe alles denkbare ausprobiert (z.b. ERST WR-select DANN CS-enable und umgekehrt, mit NOP und ohne) - letzte option ist ein defekter t6963c (unwahrscheinlich); bitte dringend um hilfe, quelltext ist angehängt. pumpkin p.s. es regt sich was wenn ich den mega16 flashe und dann verifiziert wird...das display zeigt kuriosen datenmüll an bis es resetet wird. :'(
Hallo, void set_cmd_write(void) { PORTD = 0b11111110; //lower bits f.l.: C~D ~Ce ~Rd ~Wr asm volatile ("nop"::); asm volatile ("nop"::); PORTD = 0b11111010; //lower bits f.l.: C~D ~Ce ~Rd ~Wr } void set_data_write(void) { PORTD = 0b11110110; //lower bits f.l.: C~D ~Ce ~Rd ~Wr asm volatile ("nop"::); asm volatile ("nop"::); PORTD = 0b11110010; //lower bits f.l.: C~D ~Ce ~Rd ~Wr } Du setzt CE auf L, dann WR auf L und dann??? Ein Schreibzyklus endet mit der L/H-Flanke von WR oder CE... Bis zum Ende des Zyklus (min. 80ns nach der steigenden Flanke von WR oder CE müssen auch die Daten gültig bleiben. Taktdiagramm im Datenblatt... ;) Gruß aus Berlin Michael
mmmh, tDH (40ns, oder meinst du was anderes?)...habsch noch garnit gesehen den kleinen schlipsel : ) ....aber eh der aus der subroutine wieder raus ist und den datenport neu beschreibt, sind lange 40ns verstrichen. fµC = 3.686MHz - 270ns/takt...denkfehler von mir? pumpkin
jaaaaaaaaaaaaaa du bistn schatz michael...wie saublöd is das denn? hab ich erst gerafft als ich in asm debugged hab.... : ) es regt sich was...das wird ne laaaange nacht ^^ thomas (mit herzlichen grüßen aus berlin!)
Hi, auch nochmal eine Frage zum Thema: Wie habt Ihr das Display am uC angeschlossen ? Bei mir gehen die Datenleitungen direkt zum vom AVR zum Display (Display mit t6369c auf Platine von Electronic Assembly). Die Steuerleitungen ebenfalls. Den Resetpin der Displayapplikation hab ich per RC-Glied über die Steuerleitungen an den AVR angeschlossen. So, jetzt schalte ich erst das Display an (Saft auf die Leitung) und danach wird der AVR Resetet. ist der Ablauf so korrekt ? Oder wie habt ihr das gelöst ? Ich frag nur, weils bei mir einfach ums ver**n nicht wie vorgesehen läuft. mfg, Simon
Hi, kann mir jemand bitte kurz Auskunft geben, ob ich das Display richtig angeschlossen habe, oder vielleicht seine eigene Verdrahtung kurz schildern. Vielen Dank, Simon
hallo, so ähnlich hab ich es auch. nur das RC glied hab ich mir gespart. PORTD: (msb) X X FS ~Reset C~D ~Ce ~Rd ~Wr (lsb) PORTB: (msb) D7 ....................... D0 (lsb) was funktioniert denn nicht? pumpkin
Danke, ich ka**k ab. Einmal flasht das Display und zeigt irgendwas an, zur Zeit macht es garnichts und ganz selten blinkt der Cursor und das Display ist clean. ICh verwende den AT90CAN128 mit dem internen 1Mhz Takt, so dass ich mir das Timing erstmal zum Großteil sparen kann. Ich bastel da seit geraumer Zeit nebenbei immer mal wieder dran rum, hab auch schon so ziemlich alles hier eingestellten codes angesehen / verwendet. Das Display funktioniert aber 100% wenn ich es in die ursprünglich Anwendung einsetze ( Navi aus der Jahrtausendwende ;)) Wenn Du nichts dagegen hast, würd ich gerne mal später meinen code posten oder mailen. Übrigens hab ich noch ein Navimodul von uBlox ( GPS1 ) rumliegen. Wer mir bei ,meinem Problem hilft, kanns haben ;) mfg Simon
gerne, klasse wäre aber austausch über icq. bei mir zickt er seit gestern auch wieder rum. wenn ich meinen neuen code auf den blanken uC schicke sagt das display kein mucks, aber wenn auf dem controller vorher eine ältere version des codes drauf war bevor ich den neuen geflashed habe, dann läuft der neue code so wie er soll. ich habe keine ahnung wie das sein kann. pumpkin
ich benutze kein icq. skype wäre ok, schick mir kurz ne mail, wenns geht. Dann kann ich die heut nachmittag das zeuch schicken. Email addresse steht oben. mfg, Simon
sorry, aber der mailer-daemon hat zugeschlagen. gmx scheint bei euch geblockt zu sein. schreib mir an testicals(at)gmx.de pumpkin
moin, beim drüberfliegen ist mir zuerst das hier aufgefallen: void lcd_status(char MASK) { // prepare controllines according to Datasheet READ_DATA_PORT; ENABLE_COMMANDO; ENABLE_READ DISABLE_WRITE CHIP_ENABLE; //save status from port to var LCD_STATUS = PINA; //_delay_us(10); CHIP_DISABLE; DISABLE_READ; WRITE_DATA_PORT; return LCD_STATUS; } ablauf ist ja soweit korrekt, aber dein return-befehl funktioniert nicht da dein rückgabetyp void ist. komisch dass dein compiler nicht zickt. ändere void in char oder uint8_t (#include <inttypes.h>). while((lcd_status(MASK_1)&0x03)!=0x03); solltest du nicht verwenden. nimm lieber deinen auskommentierten code: /* //wait until proper status is available do { lcd_status(MASK_1); //timeout timer ausführen. } while (LCD_STATUS != MASK_1); */ pumpkin
Danke, das mit dem void ist natürlich klar, ist mir auch gleich aufgefallen. Auf jedenfall läuft die Schoße jetzt erstmal sozusagen im low-level betrieb. Display zeigt sauber an und ich kann sogar zeichen ausgeben, was allerdings noch etwas holprig läuft ( Das zurechtfinden im Speicher ist etwas gewöhnugsbedürftig). Aber soweit mal vielen Dank !
na wenigstens funktionierts bei dir - bei mir nich mehr...obwohl ich nochmal bei null angefangen hab XD pumpkin
@Pumpkin: Wie siehts aus ? Läufts wieder ? @all: mal ne blöde Frage, aber wie zeigt man Werte an, die mehr als eine dez. Stelle haben ? z.B 255d ? ich hab das jetzt mit itoa() und einem Ziffernzähler gemacht, aber das muss doch noch einfacher gehen , oder ??
wie soll ich die frage verstehen? du meinst, diese dreistellige zahl aufs display schreiben? das geht nur als chararray, da liegst du schon goldrichtig. integer to ascii ist ne feine sache, aber braucht wahrscheinlich gut platz wenn du den header einbindest. aber was solls...eh man da selber rumeiert.. ^^ um deine frage nach meinem erfolg zu beantwarten: ein klares JA, es läuft. und wie! ^^ guckst du hier: http://people.freenet.de/sound-inside/sharp_grafik_und_text_13_9.jpg pumpkin
Exakt ! Vielleicht stell´ich mich zu blöd an, aber Programmieren ist immer so ne Sache... Ich will ja zum Beispiel die in einer int Variablen gespeicherte Zahl (z.B 123) auf dem Display ausgeben und muss aber jede Ziffer einzeln schreibe. Also kommt nicht der gewünschte Effekt, da ja 123_d 7b_h ist und nicht 01_h 02_h 03_h . Verstehste ? mfg Simon (gratulation zum Display :)
joar, schon kappiert. geht halt nicht anders. aber was solls, wozu hat man denn sonst die string-schreib-routine gebastelt? ;) pumpkin p.s. falls dich der code mal interessiert: http://people.freenet.de/sound-inside/sharp_lm24014.rar
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.