Forum: FPGA, VHDL & Co. LCD PicoBlaze Spartan3


von Johannes D. (blue_screen)


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.

von neben_dran_sitz (Gast)


Lesenswert?

Das müsst funktionieren ;) Gruß
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                            ;;
3
;; information                                                                ;;
4
;;                                                                            ;;
5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;
7
;; This code is used for picoblaze to initialize a LCD and to write on it.
8
;; It is tested on a Spartan 3E starter kit. The LCD data and command port is
9
;; connected to picoblaze port 0x10:
10
;;
11
;;   case port_id is
12
;;     when x"10" => lcd_output_data <= out_port(7 downto 4);
13
;;                   lcd_drive <= out_port(3);  
14
;;                   Lcd_rs <= out_port(2);
15
;;                   Lcd_e <= out_port(0);
16
;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
;;                                                                            ;;
19
;; header                                                                     ;;
20
;;                                                                            ;;
21
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22
23
          ;
24
          ; output ports
25
          CONSTANT LCD_PORT,         10
26
          
27
          ;
28
          ; constants
29
          CONSTANT DELAY_1US_CONSTANT, 0B
30
          
31
          ;
32
          ; bitfields
33
          CONSTANT LCD_E, 01
34
          CONSTANT LCD_DRIVE, 08
35
          
36
          ;
37
          ; adresses in scratchpad RAM
38
          CONSTANT STRING_RAM, 22             ; 22-2B - string for comand
39
          
40
          ;
41
          ; registers
42
          NAMEREG  s0, US_REG                 ; wait registers
43
          NAMEREG  s1, 40US_REG               ;
44
          NAMEREG  s2, MS_REG                 ;
45
          NAMEREG  s3, 20MS_REG               ;
46
          NAMEREG  s4, LCD_INST_REG           ; LCD registers
47
          NAMEREG  s5, LCD_DATA_REG           ;
48
          NAMEREG  s6, LCD_ROW_COUNTER        ;
49
50
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51
;;                                                                            ;;
52
;; LCD control functions                                                      ;;
53
;;                                                                            ;;
54
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55
56
lcd_init:
57
          CALL delay_20ms                     ; wait more that 15ms for display to be ready
58
          LOAD LCD_INST_REG, 30
59
          CALL lcd_write_inst4                ; send '3'
60
          CALL delay_20ms                     ; wait >4.1ms
61
          CALL lcd_write_inst4                ; send '3'
62
          CALL delay_1ms                      ; wait >100us
63
          CALL lcd_write_inst4                ; send '3'
64
          CALL delay_40us                     ; wait >40us
65
          LOAD LCD_INST_REG, 20
66
          CALL lcd_write_inst4                ; send '2'
67
          CALL delay_40us                     ; wait >40us
68
          LOAD LCD_DATA_REG, 28               ; function set
69
          CALL lcd_write_inst8
70
          LOAD LCD_DATA_REG, 06               ; entry mode
71
          CALL lcd_write_inst8
72
          LOAD LCD_DATA_REG, 0C               ; display control
73
          CALL lcd_write_inst8
74
          LOAD LCD_ROW_COUNTER, 10            ; 16 chars per line
75
lcd_clear:
76
          LOAD LCD_DATA_REG, 01               ; display clear
77
          CALL lcd_write_inst8
78
          CALL delay_1ms                      ; wait >1.64ms for display to clear
79
          CALL delay_1ms
80
          RETURN          
81
82
lcd_pulse_e:
83
          XOR LCD_INST_REG, LCD_E
84
          OUTPUT LCD_INST_REG, LCD_PORT
85
          CALL wait_1us
86
          XOR LCD_INST_REG, LCD_E
87
          OUTPUT LCD_INST_REG, LCD_PORT
88
          RETURN
89
          
90
lcd_write_inst4:
91
          AND LCD_INST_REG, F8                ; RS=0, E=0, master=1
92
          OUTPUT LCD_INST_REG, LCD_PORT
93
          CALL lcd_pulse_e
94
          RETURN
95
96
lcd_write_inst8:
97
          LOAD LCD_INST_REG, LCD_DATA_REG
98
          AND LCD_INST_REG, F0                ; master=0 RS=0 instruction, E=0
99
          OR LCD_INST_REG, LCD_DRIVE          ; master=1
100
          CALL lcd_write_inst4                ; write upper nibble
101
          CALL delay_1us
102
          LOAD LCD_INST_REG, LCD_DATA_REG     ; select lower nibble with
103
          SL1 LCD_INST_REG                    ; master=1
104
          SL0 LCD_INST_REG                    ; RS=0
105
          SL0 LCD_INST_REG
106
          SL0 LCD_INST_REG                    ; E=0
107
          CALL lcd_write_inst4                ; write lower nibble
108
          CALL delay_40us                     ; wait >40us
109
          LOAD LCD_INST_REG, F0               ; master=0 RS=0 instruction, RW=0 write, E=0
110
          OUTPUT LCD_INST_REG, LCD_PORT       ; release master enable
111
          RETURN
112
          
113
lcd_cursor_home:
114
          LOAD LCD_DATA_REG, 80
115
          CALL lcd_write_inst8
116
          LOAD LCD_ROW_COUNTER, 10
117
          RETURN
118
          
119
lcd_write_data:          
120
          LOAD LCD_INST_REG, LCD_DATA_REG
121
          AND LCD_INST_REG, F0                ; master=0, RS=0 Instruction, E=0
122
          OR LCD_INST_REG, 0C                 ; master=1, RS=1 Data, E=0
123
          OUTPUT LCD_INST_REG, LCD_PORT       ; set up RS and RW >40ns before enable pulse
124
          CALL lcd_pulse_e
125
          CALL delay_1us                      ; wait >1us
126
          LOAD LCD_INST_REG, LCD_DATA_REG     ; select higher nibble with
127
          SL1 LCD_INST_REG                    ; master=1
128
          SL1 LCD_INST_REG                    ; RS=1 Data
129
          SL0 LCD_INST_REG                    ; RW=0 Write
130
          SL0 LCD_INST_REG                    ; E=0
131
          OUTPUT LCD_INST_REG, LCD_PORT       ; set up RS and RW >40ns before enable pulse
132
          CALL lcd_pulse_e                    ; write lower nibble
133
          CALL delay_40us                     ; wait >40us
134
          LOAD LCD_INST_REG, F0               ; master=0, RS=0 Instruction, E=0
135
          OUTPUT LCD_INST_REG, LCD_PORT       ; release master enable
136
          SUB LCD_ROW_COUNTER, 01             ; if eol => cursor home
137
          CALL Z, lcd_cursor_home
138
          RETURN
139
          
140
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141
;;                                                                            ;;
142
;; delay functions                                                            ;;
143
;;                                                                            ;;
144
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
145
146
delay_1us:
147
          LOAD US_REG, DELAY_1US_CONSTANT
148
wait_1us: SUB US_REG, 01
149
          JUMP NZ, wait_1us
150
          RETURN
151
          
152
delay_40us:
153
          LOAD 40US_REG, 28                   ; 40 x 1us = 40us
154
wait_40us:CALL delay_1us
155
          SUB 40US_REG, 01
156
          JUMP NZ, wait_40us
157
          RETURN
158
          
159
delay_1ms:
160
          LOAD MS_REG, 19                     ; 25 x 40us = 1ms
161
wait_1ms: CALL delay_40us
162
          SUB MS_REG, 01
163
          JUMP NZ, wait_1ms
164
          RETURN
165
          
166
delay_20ms:
167
          LOAD 20MS_REG, 14                   ; 20 x 1ms = 20ms
168
wait_20ms:CALL delay_1ms
169
          SUB 20MS_REG, 01
170
          JUMP NZ, wait_20ms
171
          RETURN

von Johannes D. (blue_screen)


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.

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.