Hallo, ich möchte ein 1x16 Display (2x8) zweizeilig beschreiben. Das Display ist von reichelt (http://www.reichelt.de/?;ACTION=3;LA=2;GROUP=A5211;GROUPID=3005;ARTICLE=10945;START=0;SORT=artnr;OFFSET=16;SID=285LwJH6wQARwAAAQoaygd6117d70754e93fcbe1250a8de99b8ad). Ich weiss nur nicht wo ich den Befehl zur Ansteuerung genau einbinden soll. Auf jeden Fall muss die Adresse 0x40 angesprochen werden um den Zeilenwechsel zu ermöglichen. Das Display wurde bei der Initialisierung 2 zeilig initialisiert. Kann mir jemand helfen? Gruß Kay Hier das Programm: ;*********************************************************************** ;Ansteuerung eines LCD Displays ;PIC 16F628 ;Takt 4MHz ;Kay ;06.08.09 ;*********************************************************************** ;Pinbelegung des PIC**************************************************** ;*********************************************************************** ; PortB,0 -> Enable ; PortB,1 -> not connected ; PortB,2 -> RS (Register Select) ; PortB,3 -> RW (Read / Write) ; PortB,4 -> D4 (Datenbus 4 bittig) ; PortB,5 -> D5 (Datenbus 4 bittig) ; PortB,6 -> D6 (Datenbus 4 bittig) ; PortB,7 -> D7 (Datenbus 4 bittig) ; ; RS = 1 -> Daten des Datenbusses werden als Zeichen in den Textpuffer übertragen ; RS = 0 -> Daten des Datenbusses werden als Befehl in der Steuerregister geschrieben ; ; RW = 1 -> Lesefunktion ; RW = 0 -> Schreibfunktion ;*********************************************************************** ;Varablen vereinbaren*************************************************** ;*********************************************************************** loops equ 0x20 ; timer für wait loops2 equ 0x21 ; timer für wait loops3 equ 0x22 loops4 equ 0x23 loops5 equ 0x24 LcdStatus equ 0x25 ; LcdDaten equ 0x26 ; ;LcdE equ PortB,0 ; enable Lcd ;LcdRw equ PORTB,3 ; read/write Lcd ;LcdRs equ PORTB,2 ; Daten Lcd (nicht control) ;*********************************************************************** ;Programm starten******************************************************* ;*********************************************************************** org 0x00 goto Init ;*********************************************************************** ;Initialisierung des PIC************************************************ ;*********************************************************************** Init bsf status,rp0 ; select Bank1 movlw B'00000010' ; Pull up resistors activ movwf option_reg movlw B'11111111' ; PortA all input movwf trisa movlw B'00000000' ; PortB all output movwf trisb bcf status,rp0 ; select Bank0 movlw B'00000000' ; Interrupt disable movwf Intcon ;*********************************************************************** ;Hauptprogramm********************************************************** ;*********************************************************************** Main call InitLcd Out movlw 'G' movwf LcdDaten call OutLcdDaten movlw 'u' movwf LcdDaten call OutLcdDaten movlw 't' movwf LcdDaten call OutLcdDaten movlw 'e' movwf LcdDaten call OutLcdDaten movlw 'n' movwf LcdDaten call OutLcdDaten movlw ' ' movwf LcdDaten call OutLcdDaten movlw 'T' movwf LcdDaten call OutLcdDaten movlw 'a' movwf LcdDaten call OutLcdDaten ; 8 Zeichen fertig ; ACHTUNG ; Einfuegen eines Zeilenwechsels beim 2x8-Display call OutLcdControl movlw 'g' movwf LcdDaten call OutLcdDaten ;*********************************************************************** ;LCD initialisieren***************************************************** ;*********************************************************************** InitLcd movlw D'150' ; Delay after Vdd rises to 4,5V movwf loops call Wait bcf PortB,0 ; defined status for enable bit bcf PortB,2 ; RS = 0 -> instruction signal bcf PortB,3 ; RW = 0 -> write mode movlw B'00110000' ; InitLcd step 1: 8 bit interface call Transmit ; transfer 8 bit instruction signal movlw B'00110000' ; InitLcd step 2: 8 bit interface call Transmit ; transfer 8 bit instruction signal movlw B'00110000' ; InitLcd step 3: 8 bit interface call Transmit ; transfer 8 bit instruction signal movlw B'00100000' ; InitLcd step 4: 4 bit interface call Transmit ; transfer 8 bit instruction signal call LcdBusy ; Lcd busy? If Lcd busy, busy flag is high (PortB,7) movlw B'00000001' ; clear und cusor home call OutLcdControl movlw B'00101000' ; function set, 4-bit 2-zeilig, 5x7 call OutLcdControl movlw B'00001000' ; display off call OutLcdControl movlw B'00000110' ; entry mode, increment, disable display-shift call OutLcdControl ;movlw B'00000011' ; cursor home, cursor home ;call OutLcdControl movlw B'00001100' ; display on, cursor off, cursor flash off call OutLcdControl ;*********************************************************************** ;Transfer 8 bit intruction signal*************************************** ;*********************************************************************** Transmit movwf PortB ; Data to Databus bsf PortB,0 ; enable Chip signal nop ; wait bcf PortB,0 ; disable Chip signal movlw D'50' ; Delay of 50ms movwf loops call Wait return ;*********************************************************************** ;LCD busy at the moment?************************************************ ;*********************************************************************** LcdBusy bsf STATUS, RP0 ; make Port B4..7 input movlw B'11110000' iorwf TRISB, f bcf STATUS, RP0 BusyLoop bcf PortB,2 bsf PortB,3 ; Lesen bsf PortB,0 nop movf PortB, w movwf LcdStatus bcf PortB,0 nop bsf PortB,0 ; Enable nop bcf PortB,0 btfsc LcdStatus, 7 ; teste bit 7 goto BusyLoop bcf PortB,3 bsf STATUS, RP0 ; make Port B4..7 output movlw B'00001111' andwf TRISB, f bcf STATUS, RP0 return ;******************************************************************** ;aus W ein Byte mit Steuerdaten zum Display übertragen*************** ;******************************************************************** OutLcdControl movwf PortB call LcdBusy movf LcdDaten, w andlw H'F0' movwf PortB ; Hi-teil Daten schreiben bsf PortB,0 nop bcf PortB,0 ; Disable LcdBus swapf LcdDaten, w andlw H'F0' movwf PortB ; Lo-teil Daten schreiben bsf PortB,0 nop bcf PortB,0 ; Disable LcdBus return ;******************************************************************* ;aus W ein Datenbyte zum Display übertragen************************* ;******************************************************************* OutLcdDaten movwf LcdDaten call LcdBusy movf LcdDaten, w andlw H'F0' movwf PortB ; Hi-teil Daten schreiben bsf PortB,2 ; Daten bsf PortB,0 ; Enable LcdBus nop bcf PortB,0 ; Disable LcdBus swapf LcdDaten, w andlw H'F0' movwf PortB ; Lo-teil Daten schreiben bsf PortB,2 ; Daten bsf PortB,0 nop bcf PortB,0 ; Disable LcdBus bcf PortB,2 ; return ;******************************************************************* ;Subroutines******************************************************** ;******************************************************************* ;Zeitverzögerung um loops * 1 ms ; 4 MHz externer Takt bedeutet 1 MHz interner Takt ; also dauert 1 ms genau 1000 Befehle ; 100 Schleifen a 10 Befehle sind 1000 Befehle = 1 ms WAIT top movlw D'100' ; timing adjustment variable (1ms) movwf loops2 top2 nop ; sit and wait nop nop nop nop nop nop decfsz loops2, F ; inner loops complete? goto top2 ; no, go again decfsz loops, F ; outer loops complete? goto top ; no, go again retlw 0 ; yes, return from WAIT
Wie kommst Du auf die Idee, dass Du ein einzeiliges Display zweizeilig ansteuern kannst?
> Wie kommst Du auf die Idee, dass Du ein einzeiliges Display zweizeilig > ansteuern kannst? Weil das bei den meisten einzeiligen LCDs mit HD44780-kompatiblen Controllern so üblich ist.
Moin! Wie kann ich 16 kByte Daten in einem 8kByte Flash ablegen ;) Mal im Ernst, die Pixelauflösung reicht doch von vorne bis hinten nicht um vernünftige Zeichen darzustellen.
@Kay (Gast) Ja ich kann helfen. Schau dir mal den Befehl "Set DDRAM Address" im Datenblatt des KS0066U auf S.16 an. @Diensthabender Troll (Gast) das hat beim KS0066U mehr praktische Gründe. Der Controller kann nur 8 Zeichen ansteuern, aber dafür 2 Zeilen.
Wer redet denn hier von Pixeln??? Es handelt sich doch eindeutig um ein Text-LCD. HD44780-kompatible Controller haben zwei separate DD-RAM-Bereiche je 40 Zeichen (Bytes), die meist auf beide Hälften des sichtbaren Teils LCDs aufgeteilt werden. Daher sind auch die meisten einzeiligen LCDs wie Zweizeilige anzusteuern. Die ersten 8 Zeichen dieses 16x1 gehören an Adresse 00h bis 07h (0 bis 7) ins DD-RAM, die zweiten 8 Zeichen an Adresse 40h bis 47h (64 bis 71). Den oben geposteten Code habe ich mir nicht angeschaut, da ich bei PIC nicht mitreden kann/will.
Kay schrieb: > movlw 'T' > movwf LcdDaten > call OutLcdDaten > movlw 'a' > movwf LcdDaten > call OutLcdDaten > > ; 8 Zeichen fertig > ; ACHTUNG > ; Einfuegen eines Zeilenwechsels beim 2x8-Display An der Stelle solltest du dem Display die Sequenz senden, damit es auf die 2. Zeile umschaltet. Also RS auf L und dann 0C0H ans Display schicken, danach sollte es gehen. > call OutLcdControl > movlw 'g'
> das hat beim KS0066U mehr praktische Gründe. Der Controller kann nur 8 > Zeichen ansteuern, aber dafür 2 Zeilen. Nur 8 Zeichen?? - Das liegt aber nicht am Controller, sondern am LCD. Denn der Controller kann zweimal 40 Zeichen ansteuern. Bei kleineren LCDs kann man den sichtbaren Teil sogar mit Shiftbefehlen verschieben, also Scrolltext anzeigen.
Diensthabender Troll schrieb: > Nur 8 Zeichen?? - Das liegt aber nicht am Controller, sondern am LCD. > Denn der Controller kann zweimal 40 Zeichen ansteuern. Direkt kann er 40 Pixelspalten und 16 Pixelzeilen ansteuern, was bei einer 5x8 Schriftart 8x2 Zeichen entspricht. Die 40 Zeichen funktionieren nur über zusätzliche Treiber ICs die vom HD44780 kompatiblen Controller angesteuert werden. Um diese einzusparen verdrahtet man das 1x16 Display als 2x8. So kommt man nur mit dem Controller alleine aus.
Ich mache das immer so, daß die Zeichenausgaberoutine mitzählt und dann automatisch in die nächste Zeile wechselt, z.B.:
1 | void lcd_data( u8 d ) |
2 | {
|
3 | u8 i; |
4 | |
5 | LCD_RS = 1; |
6 | lcd_byte( d ); |
7 | i = ++position; |
8 | switch( i ){ |
9 | case 0xC0 + LINELEN: i = 0x80; break; |
10 | case 0x80 + LINELEN: i = 0xC0; break; |
11 | default: return; |
12 | }
|
13 | lcd_command( i ); |
14 | }
|
Was ist denn das für ein komischer Assembler, kann der nichtmal .DB Anweisungen? Das ist ja voll ätzend, alle Bytes einzeln zu basteln. Das wäre schon allein ein Grund für mich, vom PIC auf AVR umzusteigen:
1 | .db "Hallo Peter", 0 |
Peter
@Diensthabender Troll (Gast) Dir ist wohl echt ein bissle langweilig, aber mir auch: der Speicher reicht für 40 Zeichen, aber die Pins nicht. Im Dateblatt steht da was von "SEG1 Extension Driver (40SEG) SEG40". Und wenn ich das richtig verstehe braucht man für mehr Zeichen einfach noch mehr ICs die alle was Kosten.
Peter Dannegger schrieb: > Was ist denn das für ein komischer Assembler, kann der nichtmal .DB > Anweisungen? > Das ist ja voll ätzend, alle Bytes einzeln zu basteln. Naja, mit dem Assembler hat das wenig zu tun, der kann es. Allerdings können nur die neueren (18Fxxx) und ein paar wenige von den 16Fxxx Daten direkt aus dem Flash lesen. > Das wäre schon allein ein Grund für mich, vom PIC auf AVR umzusteigen: >
1 | > .db "Hallo Peter", 0 |
2 | > |
Für mich nicht. Der AVR hat andere Ecken und Macken. [picasm] ORG 0400 da 0x00,0x07,0xE0,0x00,0x00,0x3F,0xFC... [/picasm] PS: Ob der ASM direkt Strings verarbeiten kann, habe ich noch nicht getestet, bin aber der Meinung, es geht.
Benedikt schrieb: > Direkt kann er 40 Pixelspalten und 16 Pixelzeilen ansteuern, was bei > einer 5x8 Schriftart 8x2 Zeichen entspricht. Danke für die Aufklärung, das ist natürlich das Hauptargument für die Zeilenteilung. Mit der Ausgabeseite der LCD-Controller habe ich mich nicht näher beschäftigt, da ich keine LCD-Module bauen möchte und dieses Wissen für das Benutzen vorhandener LCDs nicht übermäßig wichtig ist. Daher ist mir auch die Aufteilung 40x16 Pixel nicht aufgefallen. Helfer schrieb: > der Speicher reicht für 40 Zeichen, aber die Pins nicht Danke, ich hab's verstanden (siehe oben). Dass für mehr Pixel die Pins nicht reichen und daher zusätzliche Treiber-ICs nötig sind, war mir schon klar. Mir war allerdings die Aufteilung 40x16 Pixel nicht aufgefallen. Wieder was gelernt....
Vielen Dank für eure Hilfe! Ich werde es gleich mal ausprobieren ob es klappt. Gruß Kay
Jens A: schrieb: > [picasm] > ORG 0400 > da 0x00,0x07,0xE0,0x00,0x00,0x3F,0xFC... > [/picasm] > > PS: Ob der ASM direkt Strings verarbeiten kann, habe ich noch nicht > getestet, bin aber der Meinung, es geht. Ja, geht. Mache ich immer so mit Texten für das LCD. Nur die Umlaute klappen nicht unbedingt automatisch. Siehe auch http://sprut.de/electronic/pic/assemble/pseudo.html#da Sven
Ich glaube nicht dass es sinvoll ist, den String auf dem Interruptvektor abzulegen...
Wo wird ein String auf dem Interuptvektor abgelegt?
Hm, ich sehe schon ich muss noch viel lernen wenn es darum geht ein paar Cent zu sparen. Nichts für ungut.
Hey, kurzes Feedback, es funktioniert alles wunderbar. Allerdings habe ich mich für ein 8 Bit Interface entschieden. Vielen Dank an "Helfer" und "Jens A.", ihr habt mir wirklich weiter geholfen!
solange man mit den Steuerbits das Display nicht ansteuert kann man ja trotzdem den Port weiterhin voll nutzen.
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.