Hallo, ich möchte mein EA DIP204B-6 LCD statt wie bisher im 8Bit Modus im SPI Mode betreiben, aber es will nicht. Brücke für das IM Bit ist umgelötet. Mein MCU läuft mit einer MCLK von 20MHz der SPI Bus mit einem Prescaler von 64 damit also mit 312,5kHz. Den Quellcode habe ich angehangen. Datenblätter habe ich schon gewälzt aber ich komme einfach nicht weiter. Wär super wenn mir jemand sagen kann wo der/die Fehler liegen. MfG Christian
- Es reicht völlig, das SPI nur ein Mal zu initialisieren, wenn da keine anderen (langsamere/schnellere) Slaves angeschlossen sind - In dem Datenblatt, dass ich auf die schnelle gefunden hab steht "Serial Clock Cycle Time tc 1 - 20 µs", was ich als 50kHz maximaler SPI-Takt lesen würde. - In der Busy-Flag abfrage musst du noch ein Byte schicken, damit du auch tatsächlich was von dem Display kriegst:
1 | CHECK_BF: ;Prepare Command |
2 | ;Start Byte |
3 | ldi temp_0, 0b00111111 |
4 | ;Read BF |
5 | BUSY: |
6 | cbi PORTA, CS_LCD |
7 | ;Start Byte |
8 | out SPDR, temp_0 |
9 | rcall WAIT_SPI |
10 | ; NEU: 2. Byte schicken |
11 | |
12 | ldi temp_0, 0 ; im Datenblatt wird eine 0 geschickt |
13 | out SPDR, temp_0 |
14 | rcall WAIT_SPI |
15 | |
16 | in temp_1, SPDR |
17 | sbi PORTA, CS_LCD |
18 | sbrc temp_1, 7 |
19 | rjmp BUSY |
20 | ret |
- ach ja, das kann man vereinfachen:
1 | WAIT_SPI: |
2 | in temp_2, SPSR |
3 | ;bst temp_2,7 |
4 | ;brts END_WAIT |
5 | sbrs temp_2, SPIF |
6 | rjmp WAIT_SPI |
7 | END_WAIT: |
8 | ret |
hth. Jörg ps.: Ich hab dieses Datasheet gelesen: http://www.trash.net/~luethi/microchip/datasheets/lcd/ks0073.pdf pps. ich hoffe, ich hab nicht zuviel Mist geschrieben, denn mein Code ist ungetestet :(
oh, sry, den Punkt mit dem SPI-Takt bitte schnell vergessen: tc 1-20µs heißt natürlich 50kHz-1MHz Takt sry --Jörg
@Jörg: Also es läuft leider immer noch nicht. Aber das mit dem Nullbyte habe ich ja überhaupt nicht wargenommen, das war auf jeden Fall ein Fehler. Sorry das Datenblatt war das richtige aber ich hätte es ja auch anhängen können - Vielen Dank für deine Mühen Die Initialisierung des SPI habe ich wissentlich vorgenommen da die UP´s später in ein Programm übernommen werden sollen in denen ich schon mehrere SPI Teilnehmer habe - die alle ausnahmslos funktionieren nur dieses ******* LCD nicht. Ich habe jetzt mal wirklich nur die reine Initialisierung des LCD vorgenommen ohne BF-Abfrage sondern mit einer großzügigen Zeit von 45µs bzw nach CLEAR LCD mit fetten 20ms. Nach der Init müsste letztendlich wenigstens der Cursor zu sehen sein aber nix ist. Die Init ganz schlicht:
1 | ;Die Definition von DDR und PORT ist hier nur zur Verdeutichung der verwendeten Werte so eingefügt davor und danach stehen noch die nötigen Befehle: |
2 | ;CS(LCD) |
3 | ldi temp_0, (1<<DDA2) |
4 | out DDRA, temp_0 |
5 | ldi temp_0, (1<<PA2) |
6 | out PORTA, temp_0 |
7 | ;SPI_SCK, SPI_MOSI, SPI_MOSI |
8 | ldi temp_0, (1<<DDB7)|(0<<DDB6)|(1<<DDB5) |
9 | out DDRB, temp_0 |
10 | ;------------------------------------------------------------- |
11 | |
12 | LCD_INIT: rcall WAIT_20ms |
13 | rcall SPI_INIT_LCD |
14 | cbi PORTA, CS_LCD |
15 | ;Start Byte |
16 | ldi temp_0, 0b00011111 |
17 | out SPDR, temp_0 |
18 | rcall WAIT_SPI |
19 | ;Function set - 8 Bit Modus, clear RE Bit |
20 | ldi temp_0, 0b00110000 |
21 | rcall SHIFT_OUT |
22 | rcall WAIT_45us |
23 | |
24 | ;Entry mode set - increment cursor automaticly after write data |
25 | ldi temp_0, 0b00000110 |
26 | rcall SHIFT_OUT |
27 | rcall WAIT_45us |
28 | |
29 | ;Function Set - 8 Bit Modus, set RE Bit & enable cursor blink mode BE=1 |
30 | ldi temp_0, 0b00110110 |
31 | rcall SHIFT_OUT |
32 | rcall WAIT_45us |
33 | |
34 | ;Extended function set - enable 4 line modus & invertin cursor |
35 | ldi temp_0, 0b00001011 |
36 | rcall SHIFT_OUT |
37 | rcall WAIT_45us |
38 | |
39 | ;Function set - 8 Bit Modus, clear RE Bit |
40 | ldi temp_0, 0b00110000 |
41 | rcall SHIFT_OUT |
42 | rcall WAIT_45us |
43 | |
44 | ;Display ON/OFF control - Display on, cursor off & cursor blink enable |
45 | ldi temp_0, 0b00001110 |
46 | rcall SHIFT_OUT |
47 | rcall WAIT_45us |
48 | |
49 | ;Clear Display - clear all signs on display and set cursor to column 1, row 1 |
50 | ldi temp_0, 0b00000001 |
51 | rcall SHIFT_OUT |
52 | rcall WAIT_SPI |
53 | rcall WAIT_20ms |
54 | sbi PORTA, CS_LCD |
55 | ret |
56 | |
57 | SHIFT_OUT: mov temp_1, temp_0 |
58 | andi temp_0, 0b00001111 |
59 | out SPDR, temp_0 |
60 | rcall WAIT_SPI |
61 | swap temp_1 |
62 | andi temp_1, 0b00001111 |
63 | out SPDR, temp_0 |
64 | rcall WAIT_SPI |
65 | ret |
66 | |
67 | WAIT_SPI: in temp_2, SPSR |
68 | sbrs temp_2, SPIF |
69 | rjmp WAIT_SPI |
70 | END_WAIT: ret |
Wie empfindlich ist den das LCD? Nicht das es beim Umlöten der Brücke die Hufe hochgerissen hat. Vorher ging es im 8Bit Mode und jetzt geht es immerhin noch an und der Kontrast und die Helligkeit passen auch. Bin für jeden Tipp dankbar...
Ist das Display wirklich richtig angeschlossen? ;) Sind die Wartezeiten korrekt (da steht zwar 45us bzw 20ms, aber tun die das auch) ? --> Poste deine Warteroutinen Irgendwie blick ich nicht ganz, ob man dem Display die 8- oder die 4Bit Initialisierung für SPI schicken muss. ...und natürlich kann es sein, dass du das Display 'getötet' hast :( ?! --Jörg
Hallo Jörg, das LCD lebt noch, auf jeden Fall habe ich das DORD Bit falsch gesetzt. Ich bekomme nun den Cursor angezeigt aber die Initialisierung haut noch nicht richtig hin. Die Kommentare der einzelnen Init-Schritte sind noch von der 8Bit-Bus Variante. Dort gibt es aber eben nur die Optionen 4- und 8Bit ich habe es erst mal auf 8Bit gelassen, werde weiter probieren. Die Warteschleifen sind nach dem Schema in der txt Datei aufgebaut - die 20ms sind tatsächlich 21,..ms. Die 8µs sind mehr als 11 und ist nur vom rumprobieren reingerutscht. Und die 45µs passen auch, habe ich mit dem Oszi überprüft. Ich denke mal morgen werde ich das LCD zum laufen bekommen, werde dann noch mal die korrekte Initialisierungssequenz reinsetzen, die der Bascom Beispiele aus der Codesammlung waren bei mir nicht erfolgreich - mal sehen. MfG Christian
Schön zu hören (dass nicht kaputt ist, etc.)! Ich kann noch eine (AVR-GCC) C-Version (fertig) machen (hab Semesterferien und deshalb etwas Zeit ;) ). Dazu müsstest du mir verraten wie deine Schaltung aussieht, wenn du nicht selber compilieren willst (Ich hab das Display nicht). Ich weiß, in der Codesammlung gibt's eine C-Version, die finde ich aber nicht so toll. hth. Jörg
Das ist ein feiner Zug von dir, aber ich will es eigentlich alleine schaffen - mal abgesehen von den Tipps. Sonst bleibt einfach nicht soviel hängen. Und mit C muss ich mich erst noch beschäftigen. Hab zwar C und ASM im Studium gehabt aber leider keine Zeit gehabt mich damit intensiv und praktisch auseinander zu setzen. Da ich das aber schon immer lernen wollte muss ich da jetzt durch...
So funkts,
1 | .include "m644def.inc" |
2 | |
3 | .cseg |
4 | .equ CS_LCD = 2 |
5 | |
6 | .def temp_0 = r16 |
7 | .def temp_1 = r17 |
8 | .def temp_2 = r18 |
9 | .def temp_3 = r19 |
10 | .def lcddata = r20 |
11 | |
12 | .org 0x0000 rjmp MAIN |
13 | |
14 | MAIN: ldi temp_0, LOW(RAMEND) |
15 | out SPL, temp_0 |
16 | ldi temp_0, HIGH(RAMEND) |
17 | out SPH, temp_0 |
18 | |
19 | ;CS(LCD) |
20 | ldi temp_0, (1<<DDA2) |
21 | out DDRA, temp_0 |
22 | ldi temp_0, (1<<PA2) |
23 | out PORTA, temp_0 |
24 | ;SPI_SCK, SPI_MOSI, SPI_MOSI |
25 | ldi temp_0, (1<<DDB7)|(0<<DDB6)|(1<<DDB5)|(1<<DDB4) |
26 | out DDRB, temp_0 |
27 | |
28 | rcall LCD_INIT |
29 | |
30 | END: |
31 | rjmp END |
32 | |
33 | SPI_INIT_LCD: push temp_0 |
34 | ldi temp_0, (0<<SPI2X) |
35 | out SPSR, temp_0 |
36 | ldi temp_0, (0<<SPIE)|(1<<SPE)|(1<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0) |
37 | out SPCR, temp_0 |
38 | pop temp_0 |
39 | ret |
40 | |
41 | |
42 | WAIT_20ms: ldi temp_0,0x34 |
43 | Loop3: ldi temp_1,0x34 |
44 | Loop2: ldi temp_2,0x34 |
45 | Loop1: dec temp_2 |
46 | brne Loop1 |
47 | dec temp_1 |
48 | brne Loop2 |
49 | dec temp_0 |
50 | brne Loop3 |
51 | ret |
52 | |
53 | WAIT_SPI: in temp_2, SPSR |
54 | sbrs temp_2, SPIF |
55 | rjmp WAIT_SPI |
56 | END_WAIT: ret |
57 | |
58 | LCD_INIT: rcall WAIT_20ms |
59 | rcall SPI_INIT_LCD |
60 | |
61 | ;Function set - 8 Bit Modus, clear RE Bit |
62 | ldi lcddata, 0x30 |
63 | rcall LCD_COMMAND |
64 | ;Entry mode set - increment cursor automaticly after write data |
65 | ldi lcddata, 0x06 |
66 | rcall LCD_COMMAND |
67 | ;Function Set - 8 Bit Modus, set RE Bit & enable cursor blink mode BE=1 |
68 | ldi lcddata, 0x36 |
69 | rcall LCD_COMMAND |
70 | ;Extended function set - enable 4 line modus & invertin cursor |
71 | ldi lcddata, 0x09 |
72 | rcall LCD_COMMAND |
73 | ;set SEGRAM adress (Icons) - set start adress of the icon line |
74 | ldi lcddata, 0x40 |
75 | rcall LCD_COMMAND |
76 | ;write 0x00 16 times to erase the icons |
77 | ldi temp_3, 0x10 ;Loop Counter |
78 | NEXT_ICON: ldi lcddata, 0x00 |
79 | rcall LCD_DATA |
80 | dec temp_3 |
81 | brne NEXT_ICON |
82 | ;Function set - 8 Bit Modus, clear RE Bit |
83 | ldi lcddata, 0x30 |
84 | rcall LCD_COMMAND |
85 | ;Display ON/OFF control - Display on, cursor off & cursor blink enable |
86 | ldi lcddata, 0x0D |
87 | rcall LCD_COMMAND |
88 | ;Clear Display - clear all signs on display and set cursor to column 1, row 1 |
89 | ldi lcddata, 0x01 |
90 | rcall LCD_COMMAND |
91 | ret |
92 | |
93 | LCD_DATA: push temp_0 |
94 | cbi PORTA, CS_LCD |
95 | ldi temp_0, 0b01011111 |
96 | out SPDR, temp_0 |
97 | rcall WAIT_SPI |
98 | rcall SHIFT_OUT |
99 | sbi PORTA, CS_LCD |
100 | pop temp_0 |
101 | ret |
102 | |
103 | LCD_COMMAND: push temp_0 |
104 | cbi PORTA, CS_LCD |
105 | ldi temp_0, 0b00011111 |
106 | out SPDR, temp_0 |
107 | rcall WAIT_SPI |
108 | rcall SHIFT_OUT |
109 | sbi PORTA, CS_LCD |
110 | pop temp_0 |
111 | ret |
112 | |
113 | SHIFT_OUT: mov temp_0, lcddata |
114 | andi lcddata, 0b00001111 |
115 | out SPDR, lcddata |
116 | rcall WAIT_SPI |
117 | swap temp_0 |
118 | andi temp_0, 0b00001111 |
119 | out SPDR, temp_0 |
120 | rcall WAIT_SPI |
121 | rcall CHECK_BF |
122 | ret |
123 | |
124 | CHECK_BF: ldi temp_0, 0b00111111 |
125 | out SPDR, temp_0 |
126 | rcall WAIT_SPI |
127 | ldi temp_0, 0x00 |
128 | out SPDR, temp_0 |
129 | rcall WAIT_SPI |
130 | in temp_0, SPDR |
131 | sbrc temp_0, 7 |
132 | rjmp CHECK_BF |
133 | ret |
134 | .exit |
Danke Jörg, wie gesagt das mit der Null schreiben beim BF auslesen hätte ich bestimmt noch ein paar Tage ignoriert obwohl es ja logisch ist da ich das BF Flag ja sonst gar nicht aus dem LCD bekomme. Ansonsten waren es noch haufenweise Strg+C und Strg+V Fehler gepaart mit etwas Dummheit.
Ich hab trotzdem weitergemacht ;) Aber hauptsächlich um mit Doxygen zu spielen. Das Ergebnis ist für den Anfang recht umfangreich. Im Anhang ist: - die Library (ks0073.c und ks0073.h) - eine Demo (lcd_test.c, inkl. Makefile und AVR-Studio-projekt). - eine Hex-datei, falls du nicht selber kompilieren willst (näheres in der readme.txt) --Jörg
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.