- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 6 von 6

Thema: Frage zu LCD

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21

    Frage zu LCD

    Anzeige

    Praxistest und DIY Projekte
    Guten Tag!
    Wie schon in einem früheren Thread erwähnt möchte ich meine Schaltung mit einem LC-Display austatten um Akkuspannung, Zeit usw. abzulesen.
    Es handelt sich dabei um ein 2Zeiliges Display mit je 16 Zeichen. Die Datenleitungen hängen auf PortC, die Steuerleitungen auf PortE (E0=Ena, E1=R/W, E2=RS)

    Hab jetzt mal ein Testprogramm gemacht damit ich den Umgang mit dem Display lernen kann. Das folgende Programm funktioniert und gibt auf dem Display "AB" aus.
    Code:
    ;***************************************************************************** 
    ;* 
    ;* DATEINAME    : disp1.asm 
    ;* TITEL		: Display ansteuern
    ;* DATUM  		: 14.7.08 
    ;* AUTOR  		: STK 
    ;* VERSION   	: 1.0 
    ;* 
    ;* 
    ;***************************************************************************** 
    
    .include "m8515def.inc" 
    
    ;--KONSTANTENDEKLARATION--------------------------------------------- 
       ; status register bits 
    .equ CarryFlag      = 0 
    .equ ZeroFlag       = 1 
    .equ NegativeFlag   = 2 
    .equ TwosFlag       = 3 
    .equ SignFlag       = 4 
    .equ HalfCarryFlag   = 5 
    .equ TransferFlag   = 6 
    .equ GlobalFlag       = 7 
    .equ Frequenz   	= 4000000
    .equ Teiler 	    = 4000
    
    ;--VARIABLENDEKLARATION---------------------------------------- 
    .def work = R16                  ;Temp. Variable 
    .def zaehler = R17
    .def sreg_save = R18
    .CSEG            
    .org 0x0000        
    
    rjmp MAIN         		;Reset
    rjmp UnusedInt_ISR 		;Ext. Int0
    rjmp UnusedInt_ISR		;Ext. Int1 
    rjmp UnusedInt_ISR 		;Timer1 Capture Event
    rjmp timer		        ;Timer1 Compare Match A
    rjmp UnusedInt_ISR 		;Timer1 Compare Match B
    rjmp UnusedInt_ISR 		;Timer1 Overflow 
    rjmp UnusedInt_ISR 		;Timer0 Overflow
    rjmp UnusedInt_ISR 		;Serial Transfer Complete
    rjmp UnusedInt_ISR 		;USART Rx Complete
    rjmp UnusedInt_ISR 		;USART Data Reg. Empty
    rjmp UnusedInt_ISR 		;USART Tx Complete
    rjmp UnusedInt_ISR 		;Analog Comperator
    rjmp UnusedInt_ISR 		;Ext. Int Request 2
    rjmp UnusedInt_ISR 		;Timer0 Compare Match
    rjmp UnusedInt_ISR 		;EEPRom Ready
    rjmp UnusedInt_ISR 		;Store Program memory ready
    UnusedInt_ISR:   reti 
    
      
    ;--Hauptprogramm------------------------------------------------
    MAIN: 
       ;Stackpointer initialisieren 
       ldi   work,low (RAMEND)         ; RAMEND ist eine im include file vorgegebene Konstante, 
       out   SPL,work 
       ldi work, high(RAMEND)    
       out   SPH,work 
    rjmp init                      
                                
    Main_loop: 
    ;Hauptprogramm
    ;Display Position 1
    	ldi work, 0b001	
    	out porte, work
    
    	ldi work, 0b10000000
    	out portc, work
    
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait100: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait100
    
    	ldi work, 0b000
    	out porte, work
    
    ;Schreibe A auf Display
    	
    	ldi work, 0b101	
    	out porte, work
    
    	ldi work, 0b01000001
    	out portc, work
    
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait10: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait10
    
    	ldi work, 0b100	;Daten in Textpuffer geschrieben
    	out porte, work
    
    ;Display Position 2
    
    	ldi work, 0b001	
    	out porte, work
    
    	ldi work, 0b10000001
    	out portc, work
    
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait101: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait101
    
    	ldi work, 0b000	
    	out porte, work
    
    ;Schreibe B auf Display
    
    	ldi work, 0b101	
    	out porte, work
    
    	ldi work, 0b01000010
    	out portc, work
    
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait11: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait11
    
    ldi work, 0b100	;Daten in Textpuffer geschrieben
    	out porte, work
    	
    
    	rcall ende
    
    rjmp Main_loop; 
    
    
    
    ;--Unterprogramme----------------------------------------------------- 
    init: 
       clr zaehler
       ser work 
       out ddrc, work               ;Ausgang: Display D0-D7 
       out ddre, work				;Ausgang: Display Ena, RW, RS
       clr work
    	out tccr1a, work
    	ldi work, 0b00001001
    	out tccr1b, work
    
    	ldi work, 0b01100000		;Timer Einstellungen
    	out tIMSK, work
    
    	
    	ldi work, HIGH(Frequenz / Teiler)
    	out ocr1ah, work
    	
    	ldi work, LOW(Frequenz / Teiler)
    	out ocr1al, work
    	sei   
    
    
    ;warten
    
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait0: ;>1,64ms warten
    	ldi work, 0b00111100
    	cpse work, zaehler
    	rjmp wait0
     
        rcall init_disp
    rjmp main_loop 
    
    init_disp:
    	ldi work, 0b000	
    	out porte, work
    
    	ldi work, 0b00000001 ;Display löschen
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait1: ;>1,64ms warten
    	ldi work, 0b00001000
    	cpse work, zaehler
    	rjmp wait1
    	
    	ldi work, 0b000	
    	out porte, work
    
    
    	ldi work, 0b00000010 ;Cursor auf Anfang
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait3: ;>1,64ms warten
    	ldi work, 0b00001000
    	cpse work, zaehler
    	rjmp wait3		
    
    	ldi work, 0b000	
    	out porte, work
    
    	ldi work, 0b00000100 ;Entry mdoe
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait4: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait4		
    
    	ldi work, 0b000	
    	out porte, work
    	
    	ldi work, 0b00001100 ;Display ein
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait5: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait5		
    
    	ldi work, 0b000	
    	out porte, work
    	
    	ldi work, 0b00010100 ;Cursor Shift
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr zaehler
    	clr work
    	out TCNT1L, work
    	out TCNT1H, work
    	wait8: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait8	
    
    	ldi work, 0b000	
    	out porte, work
    
    	ldi work, 0b00111000 ;Function set
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr work
    	clr zaehler
    	out TCNT1L, work
    	out TCNT1H, work	
    	wait2: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait2
    
    	ldi work, 0b000	
    	out porte, work
    
    	ldi work, 0b01000000 ;CGRAM
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr work
    	clr zaehler
    	out TCNT1L, work
    	out TCNT1H, work	
    	wait6: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait6
    
    	ldi work, 0b000	
    	out porte, work
    
    	ldi work, 0b10000000 ;DDRAM
    	out portc, work
    	ldi work, 0b001	
    	out porte, work
    	clr work
    	clr zaehler
    	out TCNT1L, work
    	out TCNT1H, work	
    	wait7: ;>40us warten
    	ldi work, 0b00000001
    	cpse work, zaehler
    	rjmp wait7
    	ldi work, 0b000	
    	out porte, work
    ret
    
    ende:
    	rjmp ende
    ret
    
    
    ;*********Interrupt************
    timer:
    	in sreg_save, sreg
    	inc zaehler
    	out sreg, sreg_save
    reti
    Mir kommt jetzt aber vor das das etwas viel Code ist um 2 Zeichen auszugeben, daher wollte ich mal nachfragen ob ich das schon richtig mache und ob das vielleicht irgendwie kompakter oder eleganter gelöst werden kann.

    mfg
    Stefan

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Hallo Stefan,

    kompakter und eleganter -- das kann man fast immer erreichen. Wenn Deine Software fehlerfrei läuft, hast Du ja schon einen sehr großen Schritt getan!

    Hier ein ASM-LCD-Beispiel, aus dem Du vielleicht noch ein paar Ideen entnehmen kannst.

    Dein Code wäre besser lesbar, wenn Du ihn mehr strukturiertest. Du schreibst zwar "Unterprogramme" in einen Kommentar, aber danach folgt Code, innerhalb dessen Du viel hin- und herspringst. "init" könnte man z.B. als echtes Unterprogramm gestalten, mit "rcall" erreichen, mit "ret" verlassen. Ebenso die "wait"-Routinen; die ließen sich dann mit einem Parameter aufrufen, der die Wartezeit angibt, so dass Du nicht so viele Sprünge/Labels (wait0, wait1, wait3 usw.) benötigst. Wie gesagt, das ist einfach eine Frage des (persönlichen) Stils und keine Sache von "richtig" oder "falsch".

    Es ist >2 Jahre her, dass ich éine LCD-Ansteuerung selbst in Assembler geschrieben habe -- ich kenne die Probleme gut! Glückwunsch zum erfolgreichen Programm!

    Gruß

    Fred
    Only entropy comes easy. - Anton Checkhov

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21
    Hallo!
    Hab mich schon daran gemacht die Unterprogramm etwas auszubauen. Die Pausen sind jetzt ebenfalls als ein Unterprogramm ausgeführt. Danke für den Tipp.
    Einen konstanten Text ausgeben ist eh kein Problem, schwieriger wird jetzt die Akkuspannung am Display auszugeben. (z.B.: 10000000 = 5,00V) Das hab ich mir noch nicht so recht zusammengereimt wie ich das jetzt umsetzen soll.
    Ich werd jetzt mal das Beispiel durcharbeiten zu dem du mir den Link gepostet hast, vielleicht werd ich ja schlauer.

    Danke
    mfg
    Stefan

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.02.2006
    Ort
    3. Planet eines kleinen Sonnensystems in einem Seitenarm der Milchstraße
    Alter
    69
    Beiträge
    622
    Hallo Stefan,

    Zitat Zitat von Stefan_84
    ...(z.B.: 10000000 = 5,00V)...
    vermutlich eher so etwas wie 1023 = 5V und 0=0V. Da bringt Dich dieses Tutorial zur Festkommaarithmetik hoffentlich weiter.

    Viel Erfolg! Wie gesagt, eine LCD-Ansteuerung so in Assembler zu schreiben, dass sie überhaupt funktioniert, beweist, dass der Rest für Dich auch sehr gut zu schaffen ist!

    Viele Grüße

    Fred
    Only entropy comes easy. - Anton Checkhov

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21
    Ja genau! Danke.
    Jetzt muss ich erst mal schauen wie ich das ins Assambler umsetzen kann.

    Danke
    mfg
    Stefan

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    08.01.2005
    Ort
    Germany
    Beiträge
    55
    Hallo Forum,

    ich denke mal, mein Anliegen paßt hier rein.

    Hat schon mal jemand die Mini-LCD-Module 2x8 von Reichelt (EA DIPS082, 40x20mm) im 4-Bit-Modus stabil zum Laufen gebracht?

    Im 8-Bit-Modus habe ich damit keine Probleme, aber im 4-Bit-Modus drehe ich bald vom Teller. Direkt nach dem Flashen zeigt es korrekt an, auch nach einem Reset.
    Schalte ich aber die Spannung neu ein, dann zeigt es entweder nur die erste Zeile oder Müll an, diesen aber meist in der 2.Zeile. Erst nach zwei bis dreimaligem resetten zeigt es wieder korrekt an.
    Dies deutet auf Fehler in der Initialisierung hin. Die Initialisierung ist aber nach dem saumiserablen Datenblatt eine ganz normale, wie für 2x16 oder andere mit dem 44780-Standardcontroller. Nicht mal eine lauffähige Initialisierungsroutine haben die als Beispiel drin, nur solche Kinderkacke, die jeder sowieso schon weiß. Mit einem 16x2-Display im 4-Bit-Modus läuft das gleiche Programm ohne Probleme.

    Weiterhin ist mir aufgefallen, daß, wenn es nach dem Resetten dann beide Zeilen anzeigt, der Kontrast etwas geringer wird. Von Kontrasteinstellungen wird im Datenblatt aber nichts erwähnt, sind auch keine Befehlssequenzen dafür vorhanden. Hat jemand schon Erfahrungen mit diesem Display und vor allem, gibt es etwas, was im Datenblatt nicht drinsteht, aber wichtig ist? Ich bin da fast am Verzweifeln. Habe auch schon mit dem Timing rumgespielt, auch 3sek vor der Initialisierung gewartet, hat aber nix gebracht.

    mfg Roger

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad