Forum: Mikrocontroller und Digitale Elektronik LCD nach Ein/Ausschalten TOT?


von Björn (Gast)


Lesenswert?

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

von Björn (Gast)


Lesenswert?

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!

von Falk B. (falk)


Lesenswert?

@  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

von Peter D. (peda)


Lesenswert?

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

von Marcus W. (blizzi)


Lesenswert?

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.

von Björn (Gast)


Lesenswert?

dann müsste ja ein _delay_ms(10) am Anfang gleich nach Main auch abhilfe 
schaffen wenns am timing liegt oder?

danke

von Björn (Gast)


Lesenswert?

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.

von Björn (Gast)


Lesenswert?

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

von Tupf (Gast)


Lesenswert?

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 ...

von Björn (Gast)


Lesenswert?

das führte auch zu keinem Ergebnis....habe es gerade probiert.

von Björn (Gast)


Angehängte Dateien:

Lesenswert?

hier schicke ich mal den Dateianhang vom gesamten Projekt.

von Thilo M. (Gast)


Lesenswert?

Habe den Code jetzt nicht koplett analysiert, hast du das Timing lt. 
Datenblatt des Displays eingehalten? Einige Pausen sind bei der 
Initialisierung nötig.

von Björn (Gast)


Lesenswert?

der Code ist für einen HD44780, egal welches Display letztendlich an 
diesem HD44780 hängt.
Bisher hats schließlich auch funktioniert....^^

von Björn (Gast)


Lesenswert?

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!

von Falk B. (falk)


Lesenswert?

@  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

von Björn (Gast)


Lesenswert?

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ß

von Jens 3. (jens343)


Lesenswert?

Da mach ich als noob alles in ams noch schneller und kürzer :D

von Marcus W. (blizzi)


Lesenswert?

Wo lag denn der Fehler?
Ich hab keine Lust die beiden Codes zu vergleichen.
Gruß

von Björn (Gast)


Lesenswert?

der Fehler lag im Timing, habe eine header-Datei falsch eingebunden

von Björn (Gast)


Lesenswert?

könntet ihr mir nochmal mit dem Taster helfen??


Danke

von Björn (Gast)


Lesenswert?

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!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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."

von Peter D. (peda)


Lesenswert?

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

von Geier Meier (Gast)


Lesenswert?

@ 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?!?

von Severino R. (severino)


Lesenswert?

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?

von Björn (Gast)


Angehängte Dateien:

Lesenswert?

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!

von Björn (Gast)


Lesenswert?

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!

von holger (Gast)


Lesenswert?

>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.

von Björn (Gast)


Angehängte Dateien:

Lesenswert?

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!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Björn (Gast)


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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

von Björn (Gast)


Lesenswert?

weil ich zu dumm bin eine solche zu verstehen.

von Björn (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>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 ?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von holger (Gast)


Lesenswert?

@ 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 ;)

von sven s. (Gast)


Lesenswert?

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

von Björn (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Björn (Gast)


Lesenswert?

okay, jetzt versuche ich es aber nochmal mit dem einen 
Tastenentprellvorschlag, der neulich hier gepostet wurde.

Werde ich daheim dann mal probieren.

von Peter D. (peda)


Lesenswert?

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