Hallo! Ich habe ein STK500 und nun einen code von AVR-Studio programmiert, der einen einfachen Text auf dem display ausgibt. Dies funktioniert auch wunderbar, solange ich das STK500 nicht EIN-/Ausschalte bzw Resete. Wenn ich das mache, dann erscheint auf dem Display (16x2) nur ein schwarzer Balken in der obersten Zeile. Sobald ich das Programm wieder neu flashe, funktioniert es blendend. Also ganz klasse, wenn man das Board dann mal Aus/Einschaltet. Ich hau mein Board gleich an die Wand.... Vielen Dank für Hilfe
hier mal der Code, jaja ich weiß, die Tastenentprellung ist noch nicht drinnen, außerdem sollte er aber so ja auch einen Text am Display je nach Tastendruck an PINC (0xFD) machen oder? Weil eine Schleife die solange abfrägt bis ich einen anderen Taster drücke, sollte das Problem auch beheben können....
1 | /*************************************************************************
|
2 | Title: testing output to a HD44780 based LCD display.
|
3 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
4 | File: $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
|
5 | Software: AVR-GCC 3.3
|
6 | Hardware: HD44780 compatible LCD text display
|
7 | ATS90S8515/ATmega if memory-mapped LCD interface is used
|
8 | any AVR with 7 free I/O pins if 4-bit IO port mode is used
|
9 | **************************************************************************/
|
10 | #include <stdlib.h> |
11 | #include <avr/io.h> |
12 | #include <avr/pgmspace.h> |
13 | #include "lcd.h" |
14 | #include <inttypes.h> |
15 | //Letztes Update!
|
16 | //Für 8 Lichtschranken gemacht
|
17 | |
18 | //---------------------------------------------------------------------------
|
19 | unsigned int uart_putc(unsigned char c) |
20 | {
|
21 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
22 | {
|
23 | }
|
24 | |
25 | UDR = c; /* sende Zeichen */ |
26 | return 0; |
27 | }
|
28 | |
29 | //---------------------------------------------------------------------------
|
30 | int sendx(void) |
31 | {
|
32 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
33 | {
|
34 | }
|
35 | |
36 | UDR = 'x'; /* sende Zeichen */ |
37 | }
|
38 | int senda(void) |
39 | {
|
40 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
41 | {
|
42 | }
|
43 | |
44 | UDR = 'a'; /* sende Zeichen */ |
45 | }
|
46 | |
47 | //---------------------------------------------------------------------------
|
48 | |
49 | void uart_puts (unsigned char *s) |
50 | {
|
51 | while (*s) |
52 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ |
53 | uart_putc(*s); |
54 | s++; |
55 | }
|
56 | }
|
57 | //-------------------------------------------------------------------------------
|
58 | unsigned int wandle(unsigned int y) |
59 | {
|
60 | unsigned char Buffer[20]; |
61 | unsigned int i = y; |
62 | |
63 | sprintf( Buffer, "%u", i ); |
64 | |
65 | uart_puts( Buffer ); |
66 | |
67 | }
|
68 | |
69 | //-------------------------------------------------------------------------------
|
70 | |
71 | |
72 | static const PROGMEM unsigned char copyRightChar[] = |
73 | {
|
74 | 0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07, |
75 | 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00 |
76 | };
|
77 | |
78 | |
79 | //-------------------------------------------------------------------------------
|
80 | |
81 | |
82 | void wait_until_key_pressed(void); |
83 | |
84 | |
85 | void wait_until_key_pressed(void) |
86 | {
|
87 | unsigned char temp1, temp2; |
88 | unsigned int i; |
89 | |
90 | do { |
91 | temp1 = PIND; // read input |
92 | for(i=0;i<65535;i++); |
93 | temp2 = PIND; // read input |
94 | temp1 = (temp1 & temp2); // debounce input |
95 | } while ( temp1 & _BV(PIND2) ); |
96 | |
97 | |
98 | }
|
99 | |
100 | //----------------------------------------------------------------------------
|
101 | |
102 | void Disp_Ctrl(void) |
103 | {
|
104 | wait_until_key_pressed(); |
105 | |
106 | |
107 | lcd_command(LCD_DISP_ON); |
108 | |
109 | |
110 | |
111 | lcd_command(_BV(LCD_CGRAM)); /* set CG RAM start address 0 */ |
112 | }
|
113 | |
114 | |
115 | //-------------------------------------------------------------------------------
|
116 | |
117 | int main(void) |
118 | {
|
119 | |
120 | unsigned int overflow = 0; |
121 | unsigned int ubergabe[41] = {0}; |
122 | unsigned int reg[40] = {0}; |
123 | unsigned int Sicherheitsloop = 0; |
124 | unsigned short iZaehl = 0; |
125 | unsigned short i = 0; |
126 | unsigned short AnzahlDurchlaufe = 0; |
127 | |
128 | DDRD =0xFF; //UART |
129 | DDRB =0x00; //Lichtschranken |
130 | DDRA =0xFF; //Port für LCD |
131 | DDRC =0x00; //Port für div. Steuer-Taster |
132 | |
133 | |
134 | PORTA = 0x00; |
135 | |
136 | |
137 | //TCCR0 |= (1<<CS00)|(1<<CS02); //Prescaler für Timer auf 1024
|
138 | |
139 | UCSRB |= (1<<TXEN); //Senden aktivieren |
140 | UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); |
141 | |
142 | UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz |
143 | UBRRL = 51; |
144 | |
145 | |
146 | |
147 | lcd_clrscr(); //Display löschen |
148 | lcd_puts("SC-SW: Durchgang"); //Ausgangstext auf dem Display |
149 | Disp_Ctrl(); //Steuerbefehl an das Display senden |
150 | |
151 | |
152 | for(;;) |
153 | {
|
154 | |
155 | if (PINC==0xFD) //wenn Scroll-Taster gedrückt... |
156 | {
|
157 | AnzahlDurchlaufe++; |
158 | lcd_puts("Messung-1 ok? Sd"); |
159 | //erhöhe AnzahlDurchlaufe auf EINS
|
160 | Disp_Ctrl(); |
161 | for (;PINC != 0xFE;) //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird |
162 | {
|
163 | lcd_puts("Messung-x ok? Sd"); |
164 | Disp_Ctrl(); |
165 | }
|
166 | |
167 | }
|
168 | |
169 | if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins |
170 | {
|
171 | overflow++; |
172 | TIFR = 1<<TOV0; |
173 | }
|
174 | |
175 | switch(PINB) |
176 | {
|
177 | |
178 | case 0xFE: |
179 | TCCR0 |= (1<<CS00)|(1<<CS02); //Timer starten |
180 | reg[0]=TCNT0; |
181 | ubergabe[0]=overflow; |
182 | break; |
183 | |
184 | |
185 | |
186 | case 0xFD: |
187 | reg[1]=TCNT0; |
188 | ubergabe[1]=overflow; |
189 | break; |
190 | |
191 | |
192 | |
193 | case 0xFB: |
194 | reg[2]=TCNT0; |
195 | ubergabe[2]=overflow; |
196 | break; |
197 | |
198 | |
199 | |
200 | case 0xF7: |
201 | reg[3]=TCNT0; |
202 | ubergabe[3]=overflow; |
203 | break; |
204 | |
205 | |
206 | |
207 | case 0xEF: |
208 | reg[4]=TCNT0; |
209 | ubergabe[4]=overflow; |
210 | break; |
211 | |
212 | |
213 | |
214 | case 0xDF: |
215 | reg[5]=TCNT0; |
216 | ubergabe[5]=overflow; |
217 | break; |
218 | |
219 | |
220 | |
221 | case 0xBF: |
222 | reg[6]=TCNT0; |
223 | ubergabe[6]=overflow; |
224 | break; |
225 | |
226 | |
227 | |
228 | case 0x7F: |
229 | reg[7]=TCNT0; |
230 | ubergabe[7]=overflow; |
231 | break; |
232 | |
233 | } //Ab hier Sendevorgang über RS232 |
234 | |
235 | if (PINC==0xFE) //wenn Send-Taster gedrückt... |
236 | {
|
237 | senda(); //schicke "a"... |
238 | |
239 | for(Sicherheitsloop=0;Sicherheitsloop<50;Sicherheitsloop++) //Schickt das Ganze 50x an das VB-Programm (aus Sicherheitsgründen) |
240 | {
|
241 | for(iZaehl=0; iZaehl <= 7; iZaehl++) //schickt die einzelnen Reg./Überlauf-Einträge an das VB-Programm |
242 | {
|
243 | wandle(reg[i+AnzahlDurchlaufe]); |
244 | sendx(); |
245 | wandle(ubergabe[i+AnzahlDurchlaufe]); |
246 | }
|
247 | TCCR0=0; //Timer-Reg. auf NULL |
248 | }
|
249 | |
250 | |
251 | }
|
252 | |
253 | }
|
254 | }
|
Danke für eure Hilfe, ist wichtig!
@ Björn (Gast) >hier mal der Code, jaja ich weiß, die Tastenentprellung ist noch nicht >drinnen, außerdem sollte er aber so ja auch einen Text am Display je Und das nächste Mal bitte als Anhang! MfG Falk
Björn wrote: > Ich hau mein Board gleich an die Wand.... Ich bezweifle mal, daß das hilft. Du hast warscheinlich nen Fehler in den LCD-Routinen. Insbesondere bei der Initialisierung werden gerne Fehler gemancht. Hier mal ein einfaches Beispiel für 2*40 LCD im 4Bit-Mode mit jedem beliebigen Pin: http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip Peter
Hallo Björn, das klingt so als ob eine einfache Warteschleife reichen würde. Wenn du das STK aus/anschaltest dauert es ein wenig bis das Display sich initialisiert hat (Power-on Reset) und die Betriebsspannung stabil ist. Feuerst du gleich auf das Display, so reagiert es nicht und bleibt uninitialisiert (charakteristisch der schwarze Balken). Beim Flashen bleibt ja die Versorgungsspannung an, daher fällt dein Timingproblem da nicht auf.
dann müsste ja ein _delay_ms(10) am Anfang gleich nach Main auch abhilfe schaffen wenns am timing liegt oder? danke
außerdem kann ich mit meinem programm dann das display nachdem es Tot ist nicht mehr aus dem Tod rausholen, sondern muss ein anderes Display-Ansteuereungsprog reinladen und dann kann ich erst wieder mit meinem flashen... irgendwoe ist da der wurm drin.
helf mir mal bitte kurz auf die Sprünge...habe mein Display an PORT-A hängen. was muss ich da alles in deinen *.c und *.h-Dateien verändern damit es funktioniert?? Habe mein Display wie folgt angeschlossen: http://homepage.hispeed.ch/peterfleury/starterkit-lcd-mm.gif
Bin mir nicht sicher wieviel SRAM der ATS90S8515 hat (512 bytes glaube ich???). Aber so ein Konstrukt unten koennte u.a. ein Stack Overflow verursachen: unsigned int ubergabe[41] = {0}; unsigned int reg[40] = {0}; Probier mal die Arrays kleiner zu machen. Bis dann ...
Habe den Code jetzt nicht koplett analysiert, hast du das Timing lt. Datenblatt des Displays eingehalten? Einige Pausen sind bei der Initialisierung nötig.
der Code ist für einen HD44780, egal welches Display letztendlich an diesem HD44780 hängt. Bisher hats schließlich auch funktioniert....^^
ENTWARNUNG! Es geht.... Hier der funktionierende Code zum Ein-/Ausschalten des STK500 ohne zwischenfälle:
1 | /*************************************************************************
|
2 | Title: testing output to a HD44780 based LCD display.
|
3 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
4 | File: $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
|
5 | Software: AVR-GCC 3.3
|
6 | Hardware: HD44780 compatible LCD text display
|
7 | ATS90S8515/ATmega if memory-mapped LCD interface is used
|
8 | any AVR with 7 free I/O pins if 4-bit IO port mode is used
|
9 | **************************************************************************/
|
10 | #include <stdlib.h> |
11 | #include <avr/io.h> |
12 | #include <avr/pgmspace.h> |
13 | #include "lcd.h" |
14 | unsigned int uart_putc(unsigned char c) |
15 | {
|
16 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
17 | {
|
18 | }
|
19 | |
20 | UDR = c; /* sende Zeichen */ |
21 | return 0; |
22 | }
|
23 | |
24 | //---------------------------------------------------------------------------
|
25 | int sendx(void) |
26 | {
|
27 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
28 | {
|
29 | }
|
30 | |
31 | UDR = 'x'; /* sende Zeichen */ |
32 | }
|
33 | int senda(void) |
34 | {
|
35 | while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ |
36 | {
|
37 | }
|
38 | |
39 | UDR = 'a'; /* sende Zeichen */ |
40 | }
|
41 | |
42 | //---------------------------------------------------------------------------
|
43 | |
44 | void uart_puts (unsigned char *s) |
45 | {
|
46 | while (*s) |
47 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ |
48 | uart_putc(*s); |
49 | s++; |
50 | }
|
51 | }
|
52 | //-------------------------------------------------------------------------------
|
53 | unsigned int wandle(unsigned int y) |
54 | {
|
55 | unsigned char Buffer[20]; |
56 | unsigned int i = y; |
57 | |
58 | sprintf( Buffer, "%u", i ); |
59 | |
60 | uart_puts( Buffer ); |
61 | |
62 | }
|
63 | |
64 | /*
|
65 | ** constant definitions
|
66 | */
|
67 | static const PROGMEM unsigned char copyRightChar[] = |
68 | {
|
69 | 0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07, |
70 | 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00 |
71 | };
|
72 | |
73 | |
74 | /*
|
75 | ** function prototypes
|
76 | */
|
77 | void wait_until_key_pressed(void); |
78 | |
79 | |
80 | void wait_until_key_pressed(void) |
81 | {
|
82 | unsigned char temp1, temp2; |
83 | unsigned int i; |
84 | |
85 | do { |
86 | temp1 = PIND; // read input |
87 | for(i=0;i<65535;i++); |
88 | temp2 = PIND; // read input |
89 | temp1 = (temp1 & temp2); // debounce input |
90 | } while ( temp1 & _BV(PIND2) ); |
91 | |
92 | loop_until_bit_is_set(PIND,PIND2); /* wait until key is released */ |
93 | }
|
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | int main(void) |
102 | {
|
103 | char buffer[7]; |
104 | int num=134; |
105 | |
106 | |
107 | |
108 | DDRD &=~ (1 << PD2); /* Pin PD2 input */ |
109 | PORTD |= (1 << PD2); /* Pin PD2 pull-up enabled */ |
110 | |
111 | |
112 | /* initialize display, cursor off */
|
113 | lcd_init(LCD_DISP_ON); |
114 | |
115 | unsigned int overflow = 0; |
116 | unsigned int ubergabe[40] = {0}; |
117 | unsigned int reg[40] = {0}; |
118 | unsigned int Sicherheitsloop = 0; |
119 | unsigned short iZaehl = 0; |
120 | unsigned char i = 0; |
121 | unsigned short AnzahlDurchlaufe = 0; |
122 | |
123 | DDRD =0xFF; //UART |
124 | DDRB =0x00; //Lichtschranken |
125 | DDRA =0xFF; //Port für LCD |
126 | DDRC =0x00; //Port für div. Steuer-Taster |
127 | |
128 | |
129 | PORTA = 0x00; |
130 | |
131 | |
132 | //TCCR0 |= (1<<CS00)|(1<<CS02); //Prescaler für Timer auf 1024
|
133 | |
134 | UCSRB |= (1<<TXEN); //Senden aktivieren |
135 | UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); |
136 | |
137 | UBRRH = 00; //Baudrate einstellen 9600 bei 8 MHz |
138 | UBRRL = 51; |
139 | |
140 | |
141 | |
142 | lcd_clrscr(); //Display löschen |
143 | lcd_puts("SC-SW: Durchgang"); //Ausgangstext auf dem Display |
144 | //Steuerbefehl an das Display senden
|
145 | |
146 | |
147 | for(;;) |
148 | {
|
149 | |
150 | if (PINC==0x01) //wenn Scroll-Taster gedrückt... |
151 | {
|
152 | AnzahlDurchlaufe++; |
153 | lcd_puts("Messung-1 ok? Sd"); //erhöhe AnzahlDurchlaufe auf EINS |
154 | |
155 | for (;PINC != 0xFE;) //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird |
156 | {
|
157 | lcd_puts("Messung-x ok? Sd"); |
158 | |
159 | |
160 | }
|
161 | }
|
162 | if (TIFR &(1<<TOV0)) //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins |
163 | {
|
164 | overflow++; |
165 | TIFR = 1<<TOV0; |
166 | }
|
167 | |
168 | switch(PINB) |
169 | {
|
170 | |
171 | case 0xFE: |
172 | TCCR0 |= (1<<CS00)|(1<<CS02); //Timer starten |
173 | reg[0]=TCNT0; |
174 | ubergabe[0]=overflow; |
175 | break; |
176 | |
177 | |
178 | |
179 | case 0xFD: |
180 | reg[1]=TCNT0; |
181 | ubergabe[1]=overflow; |
182 | break; |
183 | |
184 | |
185 | |
186 | case 0xFB: |
187 | reg[2]=TCNT0; |
188 | ubergabe[2]=overflow; |
189 | break; |
190 | |
191 | |
192 | |
193 | case 0xF7: |
194 | reg[3]=TCNT0; |
195 | ubergabe[3]=overflow; |
196 | break; |
197 | |
198 | |
199 | |
200 | case 0xEF: |
201 | reg[4]=TCNT0; |
202 | ubergabe[4]=overflow; |
203 | break; |
204 | |
205 | |
206 | |
207 | case 0xDF: |
208 | reg[5]=TCNT0; |
209 | ubergabe[5]=overflow; |
210 | break; |
211 | |
212 | |
213 | |
214 | case 0xBF: |
215 | reg[6]=TCNT0; |
216 | ubergabe[6]=overflow; |
217 | break; |
218 | |
219 | |
220 | |
221 | case 0x7F: |
222 | reg[7]=TCNT0; |
223 | ubergabe[7]=overflow; |
224 | break; |
225 | |
226 | } //Ab hier Sendevorgang über RS232 |
227 | |
228 | if (PINC==0xFE) //wenn Send-Taster gedrückt... |
229 | {
|
230 | senda(); //schicke "a"... |
231 | |
232 | for(Sicherheitsloop=0;Sicherheitsloop<50;Sicherheitsloop++) //Schickt das Ganze 50x an das VB-Programm (aus Sicherheitsgründen) |
233 | {
|
234 | for(iZaehl=0; iZaehl <= 7; iZaehl++) //schickt die einzelnen Reg./Überlauf-Einträge an das VB-Programm |
235 | {
|
236 | wandle(reg[iZaehl+AnzahlDurchlaufe]); |
237 | sendx(); |
238 | wandle(ubergabe[iZaehl+AnzahlDurchlaufe]); |
239 | }
|
240 | TCCR0=0; //Timer-Reg. auf NULL |
241 | }
|
242 | |
243 | |
244 | |
245 | |
246 | }
|
247 | }}
|
Vielen Dank!
@ Björn (Gast) >ENTWARNUNG! >Es geht.... NEIN! ES GEHT SO NICHT. Es wäre sehr zuvorkommend von dir, wenn du mal ein paar Hinweise beachten würdest. Wichtige Regeln - erst lesen, dann posten! Lies mal was hier drunter steht! MFG Falk
ja ok, mach ich künftig mit zip-Ordner. Wie kann ich nun diese Taster abfangen? Warum geht das so nicht? Er soll einfach nur einen Mux am Display machen:
1 | for(;;) |
2 | {
|
3 | |
4 | if (PINC==0xFE) //wenn Scroll-Taster gedrückt... |
5 | {
|
6 | AnzahlDurchlaufe++; |
7 | lcd_clrscr(); |
8 | lcd_puts("Messung-1 ok? Sd"); //erhöhe AnzahlDurchlaufe auf EINS |
9 | }
|
10 | for (;PINC != 0xFE;) //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird |
11 | {
|
12 | lcd_clrscr(); |
13 | lcd_puts("Messung-x ok? Sd"); |
14 | |
15 | }
|
Geht es wirklich nicht ohne diese Entprellung, falls nein, stoße ich langsam auf ein Speicherproblem zwecks Programmcode von meinem Mikrocontroller ATmega8515. Gruß
Wo lag denn der Fehler? Ich hab keine Lust die beiden Codes zu vergleichen. Gruß
der Fehler lag im Timing, habe eine header-Datei falsch eingebunden
Also das Display kann ich nun mit den Tastern ansprechen, jedoch reagiert es extrem träge auf Tastendrücke. Wenn ich z.B. den Taster drücke, muss ich etwa 2 sec. auf ein Ereignis am Display warten! Woran liegt das?? Danke!
LCD und Taster sind leider auf zwei Threads verzettelt, so dass der Quellcode hier nicht mehr aktuell ist. Weiteres siehe: Beitrag "Taster abfragen UND dann."
Björn wrote: > Also das Display kann ich nun mit den Tastern ansprechen, jedoch > reagiert es extrem träge auf Tastendrücke. Wenn ich z.B. den Taster > drücke, muss ich etwa 2 sec. auf ein Ereignis am Display warten! Du hast warscheinlich haufenweise Delays in Deinem Code und das sind allerfeinste CPU-Rechenzeitvernichter. Programme mit Delays sind in der Erweiterbarkeit stark begrenzt, da viel Rechenzeit mit Nichtstun vergeudet wird und die fehlt dann natürlich für andere Sachen. Es wäre also an der Zeit sich mal mit besseren Methoden der Tastenentprellung und Flankenerkennung zu befassen, damit Deine CPU wieder Luft zum Atmen hat. Ein Timerinterrupt ist geradezu ideal dafür, siehe Tutorial hier im Forum. Obendrein verarbeitet er die Tasten parallel, d.h. 8 Tasten gleichzeitig auf nem 8-Bitter, spart also ne Menge SRAM, Code und CPU-Zeit. Peter
@ Falk Brunner (falk) Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!? Dir kann es wohl keiner Recht machen?!?
Geier Meier wrote: > @ Falk Brunner (falk) > > Dir kann es wohl keiner Recht machen?!? [..] > Dir kann es wohl keiner Recht machen?!? Falk Brunner hat schon Recht. Ist es so schwierig, sich an ein paar Regeln zu halten? Meines Erachtens ist es ein Zeichen von Egoismus und Gleichgültigkeit, wie einige Posts gestaltet werden. Ist es denn so schwierig, einen Aussagekräftigen Betreff zu wählen und auch den verwendeten Controller darin zu erwähnen? Es braucht ja kein ganzer Satz zu sein, aber einige wesentliche Stichwörter wie z.B. "ATmega32 GCC Text-LCD" und man weiss sofort, dass es nicht um Assembler geht, nicht um ein TFT SVGA Display und nicht um einen PIC. Und was soll ein ganzes Sourcefile als Text gepostet?
also, ich habe nun breaks in meine case-Anweisung, dies hat das Wechsel-Problem beim LCD behoben (es kommen keine skurrilen zahlen mehr). Die Tastendrücke werden nun empfangen, ABER bis eine Änderung NACH dem Tastendruck geschieht vergeht jeweils etwa 1 SEKUNDE! Ich finde in meinem Code keine "delay-Fehler", die auf derartiges Problem hindeuten könnten. Habt ihr noch eine Idee? Ich schicke nun nochmal meinen Code. (ist jetzt erstmal noch OHNE Tastenentprellung, um den Wechsel des Displays zu sehen brauche ich die noch nicht, ich werde sie aber dann einfügen) Vielen Dank!
das mit dem flackern am Display liegt anscheinend an den einzelnen kurzen Leitungen. wenn ich an denen hin- und herzittere, dann flackert es mehr und weniger, manchmal dann garnicht.... danke!
>wenn ich an denen hin- und herzittere, dann flackert >es mehr und weniger, manchmal dann garnicht.... Schliesse es einfach richtig an, dann funktioniert es auch. Du hast ein Hardwareproblem.
ich schicke dann nochmal den code, jetzt funktioniert es soweit, jedoch am Anfang bei der "Messung - x ?" auswahl dauert alles noch so lange bis es am display ausgegeben wird.... Aber an den restlichen Display änderungen nicht, da geht es sofort nach dem tastendruck?!?! Warum ist das so?? danke!
Verzögerungsproblem Der Send-Taster hat das gleiche Bitmuster wie dein Scroll-Taster. Du gelangst wahrscheinlich unerwartet in die Senderoutine, wenn du scrollen willst. Und die gesamte Senderoutine dauert (Pi*Daumen: (2 Zahlen + x)*8*50 = 1200 Zeichen Minimum mit einem fetten sprintf() drin. Sind bei 9600 Baud gut 1,25 Sekunden!) Tastenabfrage Übrigens: Du machst im Moment die Abfrage eines ganzen Ports, um eine Taste herauszufinden. Dadurch kannst du nicht zwei Tasten gleichzeitig abfragen (Scroll-Taste UND Sende-Taste). Es wäre besser die einzelnen Bits zu testen Statt if (PINC == 0xFE) besser #define SCROLLTASTE !(PINC & (1<<PC0)) #define SENDTASTE !(PINC & (1<<PC1)) #define OKTASTE !(PINC & (1<<PC2)) if (SCROLLTASTE) ... while (SCROLLTASTE) ... if (OKTASTE) ... if (SENDTASTE) ... Speichernutzung Dein Programm legt sehr viel Material auf dem Stack ab. Ich hatte in der Simulation (Atmega32) einige Probleme mit fehlgeleiteten Sprüngen, die ich auf Stackprobleme zurückführe. Man kann das stackschonender Programmieren: 1/ Die lokalen Variablen aus main() herausziehen und daraus globale Variablen machen. Entrümpeln: Der Compiler meldet etliche unbenutzte Variablen. 2/ Weniger Strings benutzen. Viele Strings kann man aufteilen und mehrfach benutzen, z.B.
1 | void Disp_Messung(char i) |
2 | {
|
3 | #if 1
|
4 | char buffer[2]; |
5 | |
6 | if (i < 1 || i > 5) |
7 | return; |
8 | |
9 | lcd_puts("Messung - "); |
10 | buffer[0] = '0' + i; |
11 | buffer[1] = 0; |
12 | lcd_puts(buffer); |
13 | lcd_puts(" ?\nOK = OK-Taste"); |
14 | #else
|
15 | switch (i) |
16 | {
|
17 | case 1: lcd_puts("Messung - 1 ?\nOK = OK-Taste"); |
18 | break; |
19 | case 2: lcd_puts("Messung - 2 ?\nOK = OK-Taste"); |
20 | break; |
21 | case 3: lcd_puts("Messung - 3 ?\nOK = OK-Taste"); |
22 | break; |
23 | case 4: lcd_puts("Messung - 4 ?\nOK = OK-Taste"); |
24 | break; |
25 | case 5: lcd_puts("Messung - 5 ?\nOK = OK-Taste"); |
26 | break; |
27 | }
|
28 | #endif
|
29 | }
|
Timer Was du mit dem Timer treibst (Anfang der for-Schleife) verstehe ich nicht bzw. sehe nicht, dass irgendwo ein Timer gestartet wird.
Vielen Dank erstmal für deinen reichhaltigen Beitrag. zum Thema Timer: -Der Timer wird durch das Setzen der Prescaler-Bits in der switch-Anweisung (siehe "case 0xFE" gestartet). Das heißt, beim Drücken des ERSTEN Tasters soll der Timer gestartet werden. zum Thema Verzögerungsproblem: -Danke erstmal, dass du einen meiner Fehler entdeckt hast. Diese Send-Funktion hatte eine gewisse "Entprell"-Funktion. Nur ich weiß leider noch nicht wie ich es lösen soll, damit auch ohne die fälschlicherweise eingebaute send-über-UART-funktion das display nicht losrennt...Ich werde da nochmal schauen und es hinkriegen. zum Thema Speichernutzung: -Da ich ständig dran programmiere, habe ich schon wieder eine neue Version; da ich aber bewusst nicht jede kleine Änderung hier poste kann ich nur sagen, dass sich die Warnungen des Compilers jetzt auf wenige reduzierten ;) Weiterhin das Problem ist... ...Wie sieht es mit dem Flackern des Displays bei "Messung läuft" aus? Warum ist da das Flackern? und... Warum wird beim String i.wann einfach der Text abgeschnitten, nachdem ich durch meine Menüführung gegangen bin? (Erst die Messung ausgewählt, DANN mit OK bestätigt und DANN die letzte Taaste (0x7F) gedrückt) --> Dann kommt das Abschneiden des Strings. Wenn ich aber direkt nach dem Einschalten des Boards auf die 0x7F gehe, steht der vorher immer abgeschnittene Text richtig im Display. Danke erstmal!
Björn wrote: > zum Thema Verzögerungsproblem: > -Danke erstmal, dass du einen meiner Fehler entdeckt hast. Diese > Send-Funktion hatte eine gewisse "Entprell"-Funktion. Und warum nimmst Du nicht einfach eine fertige und funktionierende Entprellroutine inclusive Flankenerkennung? Peter
also das Problem mit dieser Sende-überRS232-Routine habe ich nun einfach mal auskommentiert, jetzt habe ich aber das problem, dass ich wieder das Display zu träge habe.
>Weiterhin das Problem ist... >...Wie sieht es mit dem Flackern des Displays bei "Messung läuft" aus? >Warum ist da das Flackern? Das dürfte das lcd_clrscr() vor Messung_laeuft() sein if (PINC == 0xFB) //Wenn OK-Taste gedrückt... { lcd_clrscr(); Messung_laeuft(tastenzaehler-1); } Scheint wohl recht häufig aufgerufen zu werden. Timer zu kurz eingestellt ?
holger wrote: >>Weiterhin das Problem ist... >>...Wie sieht es mit dem Flackern des Displays bei "Messung läuft" aus? >>Warum ist da das Flackern? > > Das dürfte das lcd_clrscr() vor Messung_laeuft() sein > > if (PINC == 0xFB) //Wenn OK-Taste gedrückt... > { > lcd_clrscr(); > Messung_laeuft(tastenzaehler-1); > } > > Scheint wohl recht häufig aufgerufen zu werden. Das ist sicher ein Grund. Man könnte an der Stelle warten, bis die Taste wieder losgelassen wird...
1 | // PINC2
|
2 | if (OKTASTE) //Wenn OK-Taste gedrückt... |
3 | {
|
4 | lcd_clrscr(); |
5 | Messung_laeuft(tastenzaehler-1); |
6 | while(OKTASTE); |
7 | } // OK-Taste |
Die abgeschnittenen Strings (bzw. deine neue Source) habe ich mir nicht angesehen. Die letzte Source von dir hatte bei mir ja Probleme mit dem Stack. Es wurde einfach zuviel RAM-Speicher verbraten. Wenn da nichts geändert wurde, kann ich mir die geschilderten Probleme vorstellen.
@ Stefan >Die abgeschnittenen Strings (bzw. deine neue Source) habe ich mir nicht >angesehen. Die letzte Source von dir hatte bei mir ja Probleme mit dem >Stack. Es wurde einfach zuviel RAM-Speicher verbraten. Wenn da nichts >geändert wurde, kann ich mir die geschilderten Probleme vorstellen. Da hast du recht ! Wenn man diese beiden mal static macht: > unsigned int ubergabe[40] = {0}; > unsigned int reg[40] = {0}; sagt WinAVR data=288 bss=160. Zusammen 448. Bleiben gerade mal 64 Bytes für Stack. Wenn man aus den lcd_puts() lcd_puts_P() macht, dürften sich einige Probleme in Luft auflösen ;)
ich raffs nicht dispalay avr messen taster .... wie kann man da länger als 1 stunde für brauchen??? ;_) warum machst du denn alles auf einmal mach doch ert mal das display fertig und wenn du das 100% im griff hast machst du die taster und und und am schluss alles in einen topf umrühren und alles geht gruss sven
also dann ändere ich das mal auf lcd_puts_P() . Bin wieder mal in der Firma und werde es heute nach Feierabend ausprobieren. Ich habe halt zur Zeit noch das Problem eben, dass die LCD nach der Anfangsanzeige (Mit Scrolltaster Messung wählen) zu langsam auf die tastendrücke reagiert. außerdem flackert es bei der Anzeige "Messung lauft", aber komischerweise nicht immer, wenn ich nämlich am Taster bisschen bewege, dann wird das flackern mehr oder weniger (am Gehäuse des Tasters). @sven: Ich bemühe mich es so zu machen wie du geschrieben hast, allerdings ist es schwer für mich, so strukturiert zu Denken und diese Problematiken zu durchschauen, da ich noch nie vorher ein solches "projekt" programmiert habe. Danke
Björn wrote:
> weil ich zu dumm bin eine solche zu verstehen.
Es reicht wenn Du verstehst, wie Du sie einbinden mußt.
Und wenn Du Fragen dazu hast, frag ruhig.
Beim LCD hast Du doch auch eine Fremdroutine benutzt.
Oder hast Du alles verstanden, was in der LCD-Routine steht?
Tasten abfragen sieht nur auf dem ersten Blick einfach aus, aber man
kann dabei viel falsch machen.
Es ist also nicht undumm, die Erfahrungen anderer zu nutzen, auch wenn
man nicht alles gleich versteht.
Und versuche, nicht alles auf einmal zu machen, teile die Aufgaben auf,
z.B.:
wenn Taste 1 betätigt, führe Aktion 1 aus.
wenn Taste 2 betätigt, führe Aktion 2 aus.
usw.
Beachte auch den feinen, wichtigen Unterschied:
"Taste wurde betätigt" ist ungleich "Taste ist im gedrückten Zustand"!
Peter
okay, jetzt versuche ich es aber nochmal mit dem einen Tastenentprellvorschlag, der neulich hier gepostet wurde. Werde ich daheim dann mal probieren.
Björn wrote: > okay, jetzt versuche ich es aber nochmal mit dem einen > Tastenentprellvorschlag, der neulich hier gepostet wurde. http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29 Die Repeatfunktion kann man drinlassen, auch wenn man sie nicht benutzt, sind ja nur 2 Bytes SRAM zusätzlich. Peter
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.