mikrocontroller.net

Forum: FPGA, VHDL & Co. LCD PicoBlaze Spartan3


Autor: Johannes D. (blue_screen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich durchforste nun schon eine Weile verschiedene Foren auf der Suche 
nach der Lösung meines Problems.

Es geht um folgendes:
Nach der Displayinitialisierung kann ich nur ASCI Zeichen mit xF 
schreiben.

Ich habe einen PicoBlaze IPCore auf einem Spartan3 laufen und ein 
HD44780 LCD.
Die Ansteuerung läuft im 4-bit mode.
Die Datenleitungen DB3-DB0 sind nicht angeschlossen.
Der FPGA läuft mit 30MHz.

Ausführliche Messungen mit dem Oszilloskop haben gezeigt, dass auch 
wirklich die richtigen Daten gesendet werden. Leider wird aber der 
Low-Nibble ignoriert und stattdessen immer "1111" genommen. Also werden 
immer nur die ASCI Zeichen aus der letzten Zeile der Tabelle 
geschrieben. Ein Timing Problem kann ich mir nicht mehr vorstellen, weil 
ich alles zwischen bei vollem Clockspeed und Verzögerungen im 
Sekundenbereich probiert habe.

Ich bin mir aber sicher, dass alle Leitungen korrekt sind, zumal das 
ganze auf einem Board schon fest verlötet ist (habe ich so bekommen). 
Außerdem gibt es ein Testprogramm, bei dem es läuft, aber ich habe 
keinen Zugriff auf dieses File, kann also dort nicht nach einer Lösung 
suchen. (Außerdem wird da kein PicoBlaze verwendet)

Es würde mich sehr freuen, wenn mir jemand helfen könnte.

Autor: neben_dran_sitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das müsst funktionieren ;) Gruß
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                            ;;
;; information                                                                ;;
;;                                                                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This code is used for picoblaze to initialize a LCD and to write on it.
;; It is tested on a Spartan 3E starter kit. The LCD data and command port is
;; connected to picoblaze port 0x10:
;;
;;   case port_id is
;;     when x"10" => lcd_output_data <= out_port(7 downto 4);
;;                   lcd_drive <= out_port(3);  
;;                   Lcd_rs <= out_port(2);
;;                   Lcd_e <= out_port(0);
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                            ;;
;; header                                                                     ;;
;;                                                                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          ;
          ; output ports
          CONSTANT LCD_PORT,         10
          
          ;
          ; constants
          CONSTANT DELAY_1US_CONSTANT, 0B
          
          ;
          ; bitfields
          CONSTANT LCD_E, 01
          CONSTANT LCD_DRIVE, 08
          
          ;
          ; adresses in scratchpad RAM
          CONSTANT STRING_RAM, 22             ; 22-2B - string for comand
          
          ;
          ; registers
          NAMEREG  s0, US_REG                 ; wait registers
          NAMEREG  s1, 40US_REG               ;
          NAMEREG  s2, MS_REG                 ;
          NAMEREG  s3, 20MS_REG               ;
          NAMEREG  s4, LCD_INST_REG           ; LCD registers
          NAMEREG  s5, LCD_DATA_REG           ;
          NAMEREG  s6, LCD_ROW_COUNTER        ;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                            ;;
;; LCD control functions                                                      ;;
;;                                                                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

lcd_init:
          CALL delay_20ms                     ; wait more that 15ms for display to be ready
          LOAD LCD_INST_REG, 30
          CALL lcd_write_inst4                ; send '3'
          CALL delay_20ms                     ; wait >4.1ms
          CALL lcd_write_inst4                ; send '3'
          CALL delay_1ms                      ; wait >100us
          CALL lcd_write_inst4                ; send '3'
          CALL delay_40us                     ; wait >40us
          LOAD LCD_INST_REG, 20
          CALL lcd_write_inst4                ; send '2'
          CALL delay_40us                     ; wait >40us
          LOAD LCD_DATA_REG, 28               ; function set
          CALL lcd_write_inst8
          LOAD LCD_DATA_REG, 06               ; entry mode
          CALL lcd_write_inst8
          LOAD LCD_DATA_REG, 0C               ; display control
          CALL lcd_write_inst8
          LOAD LCD_ROW_COUNTER, 10            ; 16 chars per line
lcd_clear:
          LOAD LCD_DATA_REG, 01               ; display clear
          CALL lcd_write_inst8
          CALL delay_1ms                      ; wait >1.64ms for display to clear
          CALL delay_1ms
          RETURN          

lcd_pulse_e:
          XOR LCD_INST_REG, LCD_E
          OUTPUT LCD_INST_REG, LCD_PORT
          CALL wait_1us
          XOR LCD_INST_REG, LCD_E
          OUTPUT LCD_INST_REG, LCD_PORT
          RETURN
          
lcd_write_inst4:
          AND LCD_INST_REG, F8                ; RS=0, E=0, master=1
          OUTPUT LCD_INST_REG, LCD_PORT
          CALL lcd_pulse_e
          RETURN

lcd_write_inst8:
          LOAD LCD_INST_REG, LCD_DATA_REG
          AND LCD_INST_REG, F0                ; master=0 RS=0 instruction, E=0
          OR LCD_INST_REG, LCD_DRIVE          ; master=1
          CALL lcd_write_inst4                ; write upper nibble
          CALL delay_1us
          LOAD LCD_INST_REG, LCD_DATA_REG     ; select lower nibble with
          SL1 LCD_INST_REG                    ; master=1
          SL0 LCD_INST_REG                    ; RS=0
          SL0 LCD_INST_REG
          SL0 LCD_INST_REG                    ; E=0
          CALL lcd_write_inst4                ; write lower nibble
          CALL delay_40us                     ; wait >40us
          LOAD LCD_INST_REG, F0               ; master=0 RS=0 instruction, RW=0 write, E=0
          OUTPUT LCD_INST_REG, LCD_PORT       ; release master enable
          RETURN
          
lcd_cursor_home:
          LOAD LCD_DATA_REG, 80
          CALL lcd_write_inst8
          LOAD LCD_ROW_COUNTER, 10
          RETURN
          
lcd_write_data:          
          LOAD LCD_INST_REG, LCD_DATA_REG
          AND LCD_INST_REG, F0                ; master=0, RS=0 Instruction, E=0
          OR LCD_INST_REG, 0C                 ; master=1, RS=1 Data, E=0
          OUTPUT LCD_INST_REG, LCD_PORT       ; set up RS and RW >40ns before enable pulse
          CALL lcd_pulse_e
          CALL delay_1us                      ; wait >1us
          LOAD LCD_INST_REG, LCD_DATA_REG     ; select higher nibble with
          SL1 LCD_INST_REG                    ; master=1
          SL1 LCD_INST_REG                    ; RS=1 Data
          SL0 LCD_INST_REG                    ; RW=0 Write
          SL0 LCD_INST_REG                    ; E=0
          OUTPUT LCD_INST_REG, LCD_PORT       ; set up RS and RW >40ns before enable pulse
          CALL lcd_pulse_e                    ; write lower nibble
          CALL delay_40us                     ; wait >40us
          LOAD LCD_INST_REG, F0               ; master=0, RS=0 Instruction, E=0
          OUTPUT LCD_INST_REG, LCD_PORT       ; release master enable
          SUB LCD_ROW_COUNTER, 01             ; if eol => cursor home
          CALL Z, lcd_cursor_home
          RETURN
          
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                            ;;
;; delay functions                                                            ;;
;;                                                                            ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

delay_1us:
          LOAD US_REG, DELAY_1US_CONSTANT
wait_1us: SUB US_REG, 01
          JUMP NZ, wait_1us
          RETURN
          
delay_40us:
          LOAD 40US_REG, 28                   ; 40 x 1us = 40us
wait_40us:CALL delay_1us
          SUB 40US_REG, 01
          JUMP NZ, wait_40us
          RETURN
          
delay_1ms:
          LOAD MS_REG, 19                     ; 25 x 40us = 1ms
wait_1ms: CALL delay_40us
          SUB MS_REG, 01
          JUMP NZ, wait_1ms
          RETURN
          
delay_20ms:
          LOAD 20MS_REG, 14                   ; 20 x 1ms = 20ms
wait_20ms:CALL delay_1ms
          SUB 20MS_REG, 01
          JUMP NZ, wait_20ms
          RETURN

Autor: Johannes D. (blue_screen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Das verrückte ist, mein Code wahr fast komplett richtig. Aber leider hat 
eine kleine Zeile nicht gestimmt. Ich hatte in der 4-bit mode Routine 
einen Delay zu kurz, den habe ich nun in korrekter Länge und siehe da, 
zur Zeit wird auf mein Display die ganze Zeit ein "A" geschrieben. Freut 
mich gerade sehr.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.