Forum: Mikrocontroller und Digitale Elektronik PIC16F690 LCD ansteurung


von Hamid M. (diagramm)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen

ich Programmiere mein ersten PIC16F690 mit ein 2x8-LCD(MC0802ASGR-4)
im 4bit-Betrieb Modus. Leider krieg ich das LCD nicht zum Laufen.

ich hab mir das ganze auch schon in der Simulation in MPLAB angeschaut
und Finde im Programm keine Fehler. Vielleicht kann ja jemand mal 
schauen wo mein fehler im Code liegt oder mir sagen was ich anders 
machen muss.

wäre echt super und schon mal danke im voraus



; LED Programm 4 bit Ansteuerung  (LCD TYP: MC0802A-SGR)
; Port C zu LCD Display
;         PC1 -> RS
;         PC2 -> RW
;         PC3 -> E
;
;         PC4 -> D4
;         PC5 -> D5
;         PC6 -> D6
;         PC7 -> D7
; alle Anderen von D1 bis D3 GND
;**********************************************************************
;                                                                     *
;    Files required: P16F690.INC                                      *

    list      p=16F690           ; list directive to define processor
    #include <p16F690.inc>        ; processor specific variable 
definitions
    __CONFIG   _CP_OFF & _CPD_OFF & _BOR_OFF & _MCLRE_ON & _WDT_OFF & 
_PWRTE_ON & _INTRC_OSC_NOCLKOUT & _FCMEN_OFF & _IESO_OFF
; Definiton der Ports
Temp_VAR        UDATA      0X20
;***************************************************************
TEMP1            RES 1   ; allgemeines Hilfsregister 1
TEMP2            RES 1   ; allgemeines Hilfsregister 1
;**********************************************************************
RESET_VECTOR  CODE  0x000 ; processor reset vector1   goto    main 
; go to beginning of program
goto  main

MAIN_PROG CODE
;*********************************************************************
; Unter_programme:
INIT
    banksel TRISC
    movlw 0x00   ; PortC 7..0 als Ausgang definieren
    movwf TRISC

    BANKSEL ANSEL    ; setze RC0 ..RC7 Digital Ausgang
    movlw 0x00   ;
    movwf ANSEL

  BANKSEL ANSELH    ; setze RC0 ..RC7 Digital Ausgang
    movlw 0x00   ;
    movwf ANSELH
return

; 1)LC-Display initialisiert
LCDINIT
    banksel PORTC      ; RA5, RA3, RA4 Alle Control-Lines = Low
    movlw 0x00  ; (E, RS, R/W)
    movwf PORTC

    movlw .150            ; 15 ms warten
    call VERZ100US

    movlw 0x0F
    andwf PORTC,f      ; Höherw. Nibble löschen
    movlw 0x30    ; Befehl für 8-Bit-Interface (Set to 4-bit operation)
    iorwf PORTC,f      ; Befehl an LCD

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

    movlw .41            ; 4.1 ms warten
    call VERZ100US

    movlw 0x0F
    andwf PORTC,f      ; Höherw. Nibble löschen
    movlw 0x30    ; Befehl für 8-Bit-Interface (Set to 4-bit operation)
    iorwf PORTC,f      ; Befehl an LCD

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

    movlw .1              ; 100us warten
    call VERZ100US

    movlw 0x0F
    andwf PORTC,f      ; Höherw. Nibble löschen
    movlw 0x30    ; Befehl für 8-Bit-Interface (Set to 4-bit operation)
    iorwf PORTC,f      ; Befehl an LCD

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3


    ;call LCDBUSY ;Warten bis LCD bereit

    banksel PORTC      ; RA5, RA3, RA4 Alle Control-Lines = Low

    movlw 0x0F
    andwf PORTC,f ;Höherw. Nibble löschen
    movlw 0x20 ;Befehl für 4-Bit Interface
    iorwf PORTC,f  ;Befehl an LCD

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

    movlw 0x01    ;   4 Bit, 2 Zeilen, 5x7
    call LCDBEFEHL       ;   Befehl an LCD

    movlw 0x28   ; Display aus, Cursor aus, Blinken aus
    call LCDBEFEHL       ; Befehl an LCD

    movlw 0x08 ;Shift aus
    call LCDBEFEHL ;Befehl an LCD

    movlw 0x06 ;Display ein
    call LCDBEFEHL ;Befehl an LCD

    movlw 0x0C ;Display ein
    call LCDBEFEHL ;Befehl an LCD
return

; 2)Dieses Unterprogramm sendet einen Befehl nibbleweise an das 
LC-Display.
LCDBEFEHL

     movwf TEMP1 ;Auszugebendes Zeichen (befindet sich im
                 ; w-Register) in TEMP1 zwischenspeichern
     call LCDBUSY ;Warten bis LCD bereit ist

     banksel PORTC
     movlw 0x0F
     andwf PORTC,f ;Höherwertiges Nibble löschen
     movf TEMP1,w
     andlw 0xF0 ;Höherwertiges Nibble ausmaskieren
     iorwf PORTC,f ;High-Nibble an LCD übergeben

    bcf PORTC,2 ; R\W
    bcf PORTC,1 ; RS
    bsf PORTC,3 ; E
    nop
    bcf PORTC,3 ; E

     movlw 0x0F
     andwf PORTC,f ;Höherwertiges Nibble löschen
     swapf TEMP1,w
     andlw 0xF0 ;Niederwert. Nibble ausmaskieren
     iorwf PORTC,f ;Low-Nibble an LCD übergeben

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

    CLRF PORTC

return

LCDZEICHEN
     movwf TEMP1 ; Auszugebendes Zeichen (befindet sich im w-Register) 
in
     call LCDBUSY ;Warten bis LCD bereit ist

     movlw 0x0F
     andwf PORTC,f ;Höherwertiges Nibble löschen
     movf TEMP1,w
     andlw 0xF0 ;Höherwertiges Nibble ausmaskieren
     iorwf PORTC,f ;High-Nibble an LCD übergeben

    bsf PORTC,1 ; RS
    bcf PORTC,2 ; R\W
    bsf PORTC,3 ; E
nop
    bcf PORTC,3 ; E

     movlw 0x0F
     andwf PORTC,f ;Höherwertiges Nibble löschen
     swapf TEMP1,w
     andlw 0xF0 ;Niederwert. Nibble ausmaskieren
     iorwf PORTC,f ;Low-Nibble an LCD übergeben

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

return

; 3) Dieses Unterprogramm prüft das Busy-Flag des LC-Displays,
LCDBUSY

    banksel TRISC
    movlw 0xF0 ;Höherwertigeren HalbPort
    iorwf TRISC,w ; als Eingang definieren
    movwf TRISC

    banksel PORTC  ; Daten ,zeichen von LCD Lesen
    bcf PORTC,1 ; RS
    bsf PORTC,2 ; R\W
    bsf PORTC,3 ; E
    nop
    bcf PORTC,3 ; E

    movf PORTC,w
    andlw 0xF0 ;Niederw.Nibble ausmaskieren
    movwf TEMP2

    BSF PORTC,3        ; durch toggeln der LCD-Enable-Leitung)
    nop
    BCF PORTC,3

    swapf PORTC,w ;Niederwertigeres Nibble Busy-Flag
    andlw 0x0F ;Höherwertiges Nibble ausmaskieren

    iorwf TEMP2,w ;Nibbles verbinden
    btfsc TEMP2,7 ;Busy-Flag prüfen (High=busy)
    goto LCDBUSY ;Dieses UP so oft abarbeiten,bis das Busy-

    bcf PORTC,2         ; R\W ; Busy = low: LCD im Schreiben-

    banksel TRISC
    movlw 0x0F ;Höherwertigeren HalbPort
    andwf PORTC,w ; als Ausgang definieren
    movwf TRISC

return


; 5) eine Zeitverzögerung für Übergabeparameter
VERZ100US
     movwf TEMP1 ;Übergabeparameter in TEMP1 sichern
VERZSCHL1
    ; movlw .25 ;Bei Verwendung eines 4-MHz-Taktes
    ; movlw .75 ;Bei Verwendung eines 12-MHz-Taktes
     movlw .250 ;Bei Verwendung eines 20-MHz-Taktes
     movwf TEMP2
VERZSCHL2
     nop
    decfsz TEMP2,f
    goto VERZSCHL2
    decfsz TEMP1,f
    goto VERZSCHL1
return


AUSGABE
       movlw 0x01 ;Display löschen
       call LCDBEFEHL

       movlw 'H'
       call LCDZEICHEN

       movlw 'H'
       call LCDZEICHEN

       ;movlw 'l'
       ;call LCDZEICHEN

       ;movlw 'o'
       ;call LCDZEICHEN

       ;movlw '.'
       ;call LCDZEICHEN


       movlw 0xC0 ;2.Zeile
       call LCDBEFEHL

       movlw 'w'
       call LCDZEICHEN

       movlw 'i'
       call LCDZEICHEN


       movlw 20 ;Leerzeichen
       call LCDZEICHEN

       movlw 'g'
       call LCDZEICHEN

       movlw 'e'
       call LCDZEICHEN

       movlw 0x27 ;Hochkomma (')
       call LCDZEICHEN
return


;********************************************************************
  org 0x80
main

;                            AD-Wandlung
;*********************************************************************** 
*******
; 3.1) Ausschalten des Comperators
        BANKSEL CM1CON0  ; ausschalten des comp1
        movlw B'00000000'
        MOVWF CM1CON0

        BANKSEL CM2CON0  ; ausschalten des comp2
        movlw B'00000000'
        MOVWF CM2CON0

        banksel CM2CON1
        movlw B'00000000'
  movwf CM2CON1
;--------------------------------------------------------------------
; 3.4) AD_wandlung_abschaltung
;--------------------------------------------------------------------
        Banksel ANSEL    ; Abschalten des AD-Wandlers
        clrf ANSEL

        BANKSEL ADCON0   ; Abschalten(VDD,AN2,ADON)
        clrf ADCON0

Beginn
       call INIT ;Controller initialisieren
       call LCDINIT ;Display initialisieren
Schleife

       call AUSGABE ;Einen Text am LC-Display ausgeben
       movlw .500 ; und anschließend 15ms warten

       call VERZ100US

       goto Schleife
end

von Severino R. (severino)


Lesenswert?

Hast Du einen ICD2 oder PICkit2? Versuch mal das Programm resp. die 
Initialisierung des LCD im Einzelschritt auszuführen. Wenn es dann geht, 
liegt das Problem (meistens) im Timing.
Oft sind die Wartezeiten zu kurz.

Wichtige Regeln - erst lesen, dann posten!
[...]
    * Längeren Sourcecode nicht im Text einfügen, sondern als 
Dateianhang
[...]

Kannst Du bitte den Sourcecode auf das absolute (aber vollständige, d.h. 
inkl. __CONFIG und Initialisierungen) Minimum für die Ausgabe von ein 
paar Zeichen auf's LCD reduzieren?

von Tobias J. (tobiasjohn) Benutzerseite


Lesenswert?

Hey, du hast doch schon heute Morgen einen Beitrag mit dem selben Inhalt 
eröffnet.

Bleib doch in dem einen Beitrag... das würde die Übersichtlichkeit 
deutlich erhöhen.

Ich schau mir gerade das Datenblatt an.

Ansonsten kann ich meinem Vorredner nur zustimmen: Reduziere erstmal den 
Sourcecode auf das nötigste...

Sagmal: Was für ein Controller ist des in dem LCD-Modul.
Das Datenblatt ist ja echt super schlecht...

Gruß,
 Tobias

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
Noch kein Account? Hier anmelden.