hallo,
ich weiß ich bin nicht der erste und vermutlich nicht der letzte der
Probleme mit lcd's Displays hat.
momentan folge ich dem avr tut und bin bei dem Display angekommen ,geht
auch soweit, nur störte mich an der lcd-routines das der µC immer 5ms
warte und das sind bekannter maßen welten also habe ich versucht die
pausen mit hilfe von timern und interupts zu realisieren.
Problem:
wen das Display mal an war funktioniert alles und ich kann problemloses
die Anzeige ändern in dem ich den Inhalt des rams ändere. Das Problem
ist ich habe ist das das Display nur in 30% alles fälle richtig
Initialisierung wird...
wobei ich noch zur Initialisierung die normalen Zeitschleifen des tut’s
nutze weil wenn der µC ne halbe Sekunde braucht bis er läuft ist mir das
noch egal(ich arbeit mit µC's seid dienstags).
hier mal der Code vom eigentlichem Programm:
1
.include "m8515def.inc"
2
3
4
.def temp1 = r16
5
.def temp2 = r17
6
.def temp3 = r18
7
8
//----------------Interupts------------------
9
Vector:
10
11
rjmp Reset ;Program Reset:1
12
rjmp VECInt0 ;External IRQ 0:2
13
rjmp VECInt1 ;External IRQ 1:3
14
rjmp VECTmr1_Capt ;Timer/Ctr 1 Capture Event:4
15
rjmp VECTmr1_CompA ;Timer/Ctr 1 Compare Match A:5
16
rjmp VECTmr1_CompB ;Timer/Ctr 1 Compare Match B:6
17
rjmp VECTmr1_Ovf ;Timer/Ctr 1 Overflow:7
18
rjmp VECTmr0_Ovf ;Timer/Ctr 0 Overflow:8
19
rjmp VECSPI_STC ;Serial Transfer Complete:9
20
rjmp VECUART_RX ;UART, RX Complete:10
21
rjmp VECUART_UDRE ;UART, Data Register Empty:11
22
rjmp VECUART_TX ;UART, TX Complete:12
23
rjmp VECAna_Comp ;Analog Comparator:13
24
25
Reset:
26
rjmp Init
27
VECInt0:
28
reti
29
VECInt1:
30
reti
31
VECTmr1_Capt:
32
reti
33
VECTmr1_CompA:
34
reti
35
VECTmr1_CompB:
36
reti
37
VECTmr1_Ovf:
38
reti
39
VECTmr0_Ovf:
40
rjmp timer0_overflow
41
VECSPI_STC:
42
reti
43
VECUART_RX:
44
reti
45
VECUART_UDRE:
46
reti
47
VECUART_TX:
48
reti
49
VECAna_Comp:
50
reti
51
52
53
54
55
Init:
56
//------------------Stack--------------------
57
ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
58
out SPL, temp1
59
ldi temp1, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
60
out SPH, temp1
61
62
63
ldi temp1, 0xFF ; alle Pins am Ausgabeport auf Ausgang
andi temp1, 0b00001111 ; oberes Nibble auf Null setzen
172
sbr temp1, 1<<PIN_RS ; entspricht 0b00010000
173
out LCD_PORT, temp1 ; ausgeben
174
rcall lcd_enable ; Enable-Routine aufrufen
175
; 2. Nibble, kein swap da es schon
176
; an der richtigen stelle ist
177
andi temp2, 0b00001111 ; obere Hälfte auf Null setzen
178
sbr temp2, 1<<PIN_RS ; entspricht 0b00010000
179
out LCD_PORT, temp2 ; ausgeben
180
rcall lcd_enable ; Enable-Routine aufrufen
181
182
rcall set_timer_50us
183
184
mov temp1, r30
185
ldi r30, 0x88
186
ST Z, temp1
187
188
cpi temp1, 0x88
189
brne disp_next
190
191
ldi r30, 0x88
192
ldi temp1, 0xFF
193
ST Z, temp1
194
195
rcall set_timer_30ms
196
197
disp_next:
198
199
reti
ich benutze ein AtMega8515 auf einem STK500 und einer takt Frequenz von
1MHz, reiset delay = 64ms und einem Standart 2x20 Display.
ich hoffe das ich den Fehler nicht sehe weil er einfach zu
offensichtlich ist.
mfg MySystem
Au weia, so was sollte man eigentlich als Anhang posten.
Ich habe mir das Programm nicht durchgelesen, nur so viel dazu:
Schreib Deinen Text, den Du ausgeben willst ins RAM.
In einer Interruptroutine (alle 100µs) gibst Du dann jeweils ein Zeichen
an das LCD aus (das gilt nicht für die Initialisierung).
@ MySystem (Gast)
>ich weiß ich bin nicht der erste und vermutlich nicht der letzte der>Probleme mit lcd's Displays hat.
Und vor allem mit der Rechtschreibung.
http://www.apostroph.de/
Und mit der Netiquette.
Hi
Als Allererstes solltest du folgendes machen: Im AVR-Studio unter
Tools->Options->Editor folgendes einstellen:
'Replace Tabs with Space' und Tabwidth=1.
Und wenn du es ganz gut machen willst schaltest du unter 'Edit' mit
'Show Whitespace' die nicht sichtbaren Zeichen ein und schmeisst die
Tabulatoren raus. Dann kann man deinen Quelltext in jedem Editor ohne
Augenschmerzen betrachten. Und am besten, beim Programmieren die Finger
von der Tabulatortaste lassen.
>Das Problem ist ich habe ist das das Display nur in 30% alles fälle >richtig
Initialisierung wird...
Wenn dem so ist, warum schreibst du erst so ein Programm, um das zu
merken.
So etwas macht man erst, wenn die grundlegenden Routinen sicher
funktionieren.
Interruptroutinen so lang wie nötig, aber so kurz wie möglich machen.
Deine Aussgaberoutine gehört in die Main. In der IR nur ein Flag setzen
das in der Main abgefragt wird. Wenn gesetzt Routine ausführen,Flag
zurücksetzen und weiter warten.
....
MfG Spess
MySystem wrote:
> nur störte mich an der lcd-routines das der µC immer 5ms> warte und das sind bekannter maßen welten also habe ich versucht die> pausen mit hilfe von timern und interupts zu realisieren.
Ich habe mir das mit den Zeitschleifen gleich am Anfang wieder abgewöhnt
und frage bis auf die Initialisierung immer das Busy-Bit ab; ist auch
nicht schwer und die schnellstmögliche Ausgabe auf das LCD ist so auch
gewährleistet.
Gruß
Thomas
Hi
>Ich habe mir das mit den Zeitschleifen gleich am Anfang wieder abgewöhnt>und frage bis auf die Initialisierung immer das Busy-Bit ab;
Du sprichst mir aus der Seele. Aber es gibt noch eine starke Fraktion,
die noch nicht gemerkt haben, das die Zeit der HD44780 100%-kompatiblen
Displays vorbei sind. Trotzdem wird Anfängern immer noch
Minimalvarianten angeraten. Leider noch kein Fall für den Staatsanwalt.
MfG Spess
Hallo,
ich spendiere 80 Bytes als Puffer und aktualisiere zyklisch im 5ms
Timer-Interrupt.
Die Ausgabe selbst ist ja nur 1-2us.
Einen Reset im laufenden Betrieb brauch ich nicht, bzw. lasse ich den
mit Warteschleifen in der init-Function ablaufen.
Gruss,
Michael
spess53 wrote:
> Du sprichst mir aus der Seele. Aber es gibt noch eine starke Fraktion,> die noch nicht gemerkt haben, das die Zeit der HD44780 100%-kompatiblen> Displays vorbei sind. Trotzdem wird Anfängern immer noch> Minimalvarianten angeraten. Leider noch kein Fall für den Staatsanwalt.
Interessant, mit welcher Verbissenheit manche nur ihre eigene Lösung als
die einzig Wahre akzeptieren und alle anderen ohne Begründung als
grundsätzlich schlecht abkanzeln.
Ich benutze die Minimallösung und habe keinerlei Probleme damit.
Die CPU-Auslastung ist trotz Wartezeitmethode weit unter 1%, also wozu
unnütz nen Portpin verschwenden?
Manchmal benutze ich auch die Interruptmethode (ein Zeichen je 1ms
ausgeben), da wäre das Busybit eh völlig unnütz.
Diese Methode ist vorteilhaft, wenn man viel Ausgaben in
unterschiedlichen Bereichen des LCD anzeigen will. Man kann gleich
direkt in den Bildspeicher im SRAM schreiben, ohne erst umständlich
positionieren zu müssen.
Ich habe früher auch LCDs mit 3 Pins und 74HC164 im 8Bit-Modus
angesteuert. Jetzt benutze ich aber ausschließlich die Ansteuerung im
4Bit-Modus mit 6 Pins.
In der Initialisierung benutze ich selbstverständlich die Delay-Macros,
da ja nach dem Poweron nicht sofort zeitkritische Tasks auszuführen
sind. Das Delay stört also in keinster Weise.
Ich benutze auch nicht die Clear-Funktion, sondern überschreibe immer
den alten Text. Die Clear-Funktion hat neben der langen Wartezeit noch
den Nachteil, daß ein deutliches Flackern zu sehen ist.
Peter