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