-         

Ergebnis 1 bis 10 von 10

Thema: LCD & myavr weiss beim programmieren nicht weiter

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34

    LCD & myavr weiss beim programmieren nicht weiter

    Anzeige

    Hallo, ich habe das myavr board, und habe mich mit dem tutorial von microkontroller.net beschäftigt.

    Aber an zwei stellen weiss ich nicht weiter.
    Ich habe keine ahnung wie ich das display initalisiere, angepasst an mein Anschlussmuster.

    und ich weiss nicht wie ich die delays schreiben muss (5ms und 50us)

    In den beiden dateien die ich anhänge (das tesprogramm und die lcd routinen), sollte alles zu finden sein,
    ich denke ich bin auf dem richtigen weg, und bis dahin müsste alles stimmen...

    Ich könnte natürlich einfach blind aus dem tutorial kopieren, würde aber lieber verstehen was ich da mache.

    Ich würde mich sehr freuen, wenn jemand der schon erfahrung damit hat sich dieses kurz ansehen könte.

    Danke.



    Achso: das Display (16x2) ist HD44780 kompatibel und ich möchte es im 4 bit modus ansteuern.

    MfG Georg
    Angehängte Dateien Angehängte Dateien

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    eins noch : ich arbeite mit einem Atmega8, und externem 4mhz quartz, von daher bin ich mir bei dieser timing geschichte beim enable impuls nicht sicher...

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von albundy
    Registriert seit
    16.10.2004
    Beiträge
    282
    Hallo,

    Zur Initialisierung ...
    Code:
     lcd_init:
               rcall delay5ms
               ldi r16, 0b00110000        ;muss 3mal hintereinander gesendet
               out Portd, r16                 ;werden zur Initialisierung
               rcall lcd_enable             ;1
               rcall delay5ms
               rcall lcd_enable             ;2
               rcall delay5ms
               rcall lcd_enable             ;3
               rcall delay5ms
               ldi r16, 0b00100000        ;4bit-Modus einstellen
               out Portd, r16
               rcall lcd_enable
               rcall delay5ms
               ldi r16, 0b00101000        ;2 Zeilen einstellen...
               rcall lcd_command
               ldi r16, 0b00001100        ;Display an , Cursor u. Blinken aus
               rcall lcd_command
               ldi r16, 0b00000100        ;Increment ohne Display shift
               rcall lcd_command
    ret
    Lcd_enable mit 5 Nop's bei 4 Mhz ist OK.

    Bei Lcd_data und Lcd Command, hast du einen Fehler drin.
    Andi r16,0b00001111 setzt die oberen 4 Bits auf 0, nicht die unteren.

    Die Warteschleifen kannst du entweder selbst ausrechnen oder mal nach
    AVRdelayloop googeln. Das Programm erstellt aus der Quarzfrequenz und der Wartezeit den ASM Code.

    Für 50µs bei 4 Mhz, mußt du 200 Takte warten. (1/4000000 = 0,25µs)

    ldi r16,66
    loop: dec r16
    brne loop ; der Controller braucht 3 Takte pro Schleifendurchlauf

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    Danke ! daraus ergibt sich aber schon wieder eine frage :

    mit brne lass ich die schleife 3mal durchlaufen ?

    und wieso lädst du die 66 in r16 und wiederholst sie 3mal, anstatt direkt 200 hinein zu laden ?

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    Ich hab jetzt mal die änderungen vorgenommen, und mit dem delay generator eine schleife von 0,005sek (5ms) berechnet, wenn ich das programm brenne und starte passiert garnix...

    und wenn ich in AVR studio simuliere scheint der beim lcd init festzustecken (in der ersten delay schleife, sieht so aus als würde der aus der schleife rauskommen und direkt wieder reingehen, wieso tut er das?

    Code:
    ; LCD Routinen
    ;;;;;;;;;;;;;;;;;;
    
    ;4 Bit Interface
    
    ;Pinbelegung LCD
    ; 
    ; RS   - portD 2
    ; E    - portD 3
    ; RW   - Masse (write = Low)
    
    ; DB4  - portD 4
    ; DB5  - portD 5
    ; DB6  - portD 6
    ; DB7  - portD 7
    
    
    
    
    
    
    ;soll das display initalisieren
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    lcd_init:
               rcall delay5ms
               ldi r16, 0b00110000        ;muss 3mal hintereinander gesendet
               out Portd, r16                 ;werden zur Initialisierung
               rcall lcd_enable             ;1
               rcall delay5ms
               rcall lcd_enable             ;2
               rcall delay5ms
               rcall lcd_enable             ;3
               rcall delay5ms
               ldi r16, 0b00100000        ;4bit-Modus einstellen
               out Portd, r16
               rcall lcd_enable
               rcall delay5ms
               ldi r16, 0b00101000        ;2 Zeilen einstellen...
               rcall lcd_command
               ldi r16, 0b00001100        ;Display an , Cursor u. Blinken aus
               rcall lcd_command
               ldi r16, 0b00000100        ;Increment ohne Display shift
               rcall lcd_command
    ret 
    
    
    ;----------------------------------------->
    
    
    
    
    
    lcd_data:
    
    ; soll daten an das LCD senden
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
               
    
    
    ; erstmal das byte "sichern"		   
    		   
    		   mov r17, r16
               
    ; dann die unteren bits im register auf 0 setzen
    
    		   andi r16, 0b11110000
    		   
    
    ; danach RS (portD 2 auf High setzen) : 	   
               
    		   sbr r16, 0b00000100      
    		   
    		   
    ; jetzt r16 nach portD ausgeben 
    		      
               out PORTD, r16             
               
    ; nun muss nur noch die enable routine zum übergeben des halben bytes ausgeführt werden	   
    		
    		   rcall lcd_enable             
                                          
    									  
    
    ; das selbe dann jetzt nochmal nur mit nem swap davor, um jetzt die andere hälfte des bytes zu übertragen								  								  
    ; und vorher aber noch das andere byte aus dem backup register holen 
               
    		   mov r16, r17
    		   
    		   swap r16                              
               andi r16, 0b11110000       
               sbr r16, 0b00000100             
               out PORTD, r16             
               rcall lcd_enable  
    		   
    		   
    ;dann muss wohl noch eine delay routine ausgegeben werden, um ein paar millisekunden zu geben, 
    ;damit das lcd die daten übernimmt, da ich ja R/W auf masse gelegt hab  
              
               rcall delay50us              
              
    ; und dann zurück zum programm
    		 
    		   ret  
    ;------------------------------------------------------------>
    
    
    
    
    
    lcd_command:
    
    ; soll kommandos an das LCD senden, wie lcd_data, nur ohne rs zu setzen
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    		   
    		   mov r17, r16
               andi r16, 0b11110000     
               out PORTD, r16             
                 
    		   rcall lcd_enable             
                                          
    									  
    ; und die zweite hälfte
    
    		   mov r16, r17
    		   
    		   swap r16                              
               andi r16, 0b11110000                
               out PORTD, r16             
               rcall lcd_enable  
    		   
               rcall delay50us              
              
    ; und dann zurück
    		 
    		   ret  
    
    ;--------------------------------------------->
    
    
    
    
    
    lcd_enable:
    
    ;soll den enable impuls erzeugen
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
               
    		   
    ; E auf High setzen (portD 3)
    		   
    		   sbi PORTD, 3                 
    		   
    
    ; 5 taktzyklen warten
    		   
    		   nop                          
               nop
               nop
    		   nop
    		   nop
    
    ; E wieder auf low
         
    		   cbi PORTD, 3
              
    		   
    ; und zurück
    
    		   ret   
    
    ;-------------------------------------------------------------->
    
    
    
    
    
    lcd_clear:
    
    ;soll das Display löschen
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;DB4 (portD 4  auf 1 setzen, rest auf 0
    
    		   ldi r16, 0b00010000   
    
    
    ;lcd_command ausführen
    
    		   rcall lcd_command
    
    
    ;5ms warten
               
    		   rcall delay5ms
               
    
    ;und zurück
    		   
    		   ret
    		   
    ;------------------------------------------------------------->
    
    
    	    
    
    
    delay50us:
    
    ; um dem lcd dieplay entsprechende reaktinszeiten zu lassen:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
    
    ; delaying 200 cycles, 50us bei 4mhz
             
    		 
    		  ldi  R20, $42
    WGLOOP0:  dec  R20
              brne WGLOOP0
              nop
              nop
    ret
    
    ;------------------------------------------------------------>
    
    
    
    
    
    delay5ms:
    
    ; um dem lcd dieplay entsprechende reaktionszeiten zu lassen:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
    
    
    ; delaying 19998 cycles, bein 4mhz 0,005 sek
              
    		  
    		  ldi  R20, $21
    WGLOOP1:  ldi  R21, $C9
    WGLOOP2:  dec  R21
              brne WGLOOP2
              dec  R20
              brne WGLOOP1
              nop
              nop
    
    ret
    
    ;------------------------------------------------------------>
    [/code]

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    Hallo, ich nochmal ... hab grad schon mal einen fehler gefunden, ich habe die routinen am anfang eingebunden, so dass er direkt als erstes die routinen verarbeitet hat was ja nicht gehen kann *lichtaufgeh* jetzt gibt er vom programm zumindest schon mal was asu, allerdins immer was er will, mal ein "h", dann beim nächsten programmstart mal ein "L" oder auch mal hallo, aber er beginnt im display unten links und in umgekehrter reihen folge... irgendwas stimmt noch nicht

  7. #7
    Erfahrener Benutzer Begeisterter Techniker Avatar von albundy
    Registriert seit
    16.10.2004
    Beiträge
    282
    mit brne lass ich die schleife 3mal durchlaufen ?

    und wieso lädst du die 66 in r16 und wiederholst sie 3mal, anstatt direkt 200 hinein zu laden ?
    Die Schleife wird 66 mal durchlaufen.
    brne heißt: Springe zu Loop, solange R16 > 0 ist.

    ldi r16, 0b00101000 ;2 Zeilen einstellen
    Bei der Initialisierung mußt du wahrscheinlich 1 Zeile einstellen.
    (Wenn in deinem LCD Datenblatt steht 1.Zeile von $00 bis $0F und 2.Zeile von $10 bis $1F)
    Versuch mal ldi r16,0b00100000 ;1 Zeile einstellen

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    ne, das ist es auch nicht, er gibt jetzt zwar oben links das zeichen aus, aber halt immer nur eins, und kein zweites.

    zudem: wenn ich im AVR workpad das programm neustarte scheint das display_clear nicht richtig zu funktionieren, da oben links dann immer noch ein zeichen steht, und das programm dann nach lust und laune irgendwo auf dem display die komplette zeichekette ausgibt, aber nicht unbedingt zusammen, teilweise auch nur nen paar buchstaben...

  9. #9
    Erfahrener Benutzer Begeisterter Techniker Avatar von albundy
    Registriert seit
    16.10.2004
    Beiträge
    282
    Code:
    lcd_clear: 
    
    ;soll das Display löschen 
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
    
    ;DB4 (portD 4  auf 1 setzen, rest auf 0 
    
             ldi r16, 0b00010000    
    
    
    ;lcd_command ausführen 
    
             rcall lcd_command
    Das ist auch falsch.
    Ldi r16, 0b00000001 ; Bit 0 muß auf "1"

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    19.09.2005
    Ort
    Meschede
    Alter
    33
    Beiträge
    34
    super, danke für deine mühe, super dass es solche leute gibt, da fällt das lernen doch viel leichter... danke nochmal

Berechtigungen

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