www.mikrocontroller.net

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


Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....


/*************************************************************************
Title:    testing output to a HD44780 based LCD display.
Author:   Peter Fleury  <pfleury@gmx.ch>  http://jump.to/fleury
File:     $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
Software: AVR-GCC 3.3
Hardware: HD44780 compatible LCD text display
          ATS90S8515/ATmega if memory-mapped LCD interface is used
          any AVR with 7 free I/O pins if 4-bit IO port mode is used
**************************************************************************/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "lcd.h"
#include <inttypes.h>
//Letztes Update!
//Für 8 Lichtschranken gemacht

//---------------------------------------------------------------------------
unsigned int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = c;                      /* sende Zeichen */
  return 0;
}

//---------------------------------------------------------------------------
int sendx(void)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = 'x';                      /* sende Zeichen */
}
int senda(void)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = 'a';                      /* sende Zeichen */
}

//---------------------------------------------------------------------------

void uart_puts (unsigned char *s)
{
  while (*s)
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    uart_putc(*s);
    s++;
  }
}
//-------------------------------------------------------------------------------
unsigned int wandle(unsigned int y)
{
unsigned char Buffer[20];
  unsigned int i = y;

  sprintf( Buffer, "%u", i );

  uart_puts( Buffer );

}

//-------------------------------------------------------------------------------


static const PROGMEM unsigned char copyRightChar[] =
{
  0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
  0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
};


//-------------------------------------------------------------------------------


void wait_until_key_pressed(void);


void wait_until_key_pressed(void)
{
    unsigned char temp1, temp2;
    unsigned int i;
    
    do {
        temp1 = PIND;                  // read input
        for(i=0;i<65535;i++);
        temp2 = PIND;                  // read input
        temp1 = (temp1 & temp2);       // debounce input
    } while ( temp1 & _BV(PIND2) );
    
              
}

//----------------------------------------------------------------------------

void Disp_Ctrl(void)
{
wait_until_key_pressed();

   
       lcd_command(LCD_DISP_ON);
        
       
        
       lcd_command(_BV(LCD_CGRAM));  /* set CG RAM start address 0 */
}


//-------------------------------------------------------------------------------

int main(void)
{

unsigned int overflow = 0;
    unsigned int ubergabe[41] = {0};
  unsigned int reg[40] = {0};
  unsigned int Sicherheitsloop = 0;
  unsigned short iZaehl = 0;
  unsigned short i = 0;
  unsigned short AnzahlDurchlaufe = 0;
  
  DDRD =0xFF;                         //UART
  DDRB =0x00;                         //Lichtschranken
  DDRA =0xFF;                         //Port für LCD
  DDRC =0x00;                         //Port für div. Steuer-Taster


  PORTA = 0x00;


  //TCCR0 |=  (1<<CS00)|(1<<CS02);              //Prescaler für Timer auf 1024          

  UCSRB |= (1<<TXEN);                            //Senden aktivieren
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  

  UBRRH = 00;                                    //Baudrate einstellen 9600 bei 8 MHz
  UBRRL = 51;

          
        
        lcd_clrscr();                      //Display löschen
        lcd_puts("SC-SW: Durchgang");              //Ausgangstext auf dem Display
         Disp_Ctrl();                                            //Steuerbefehl an das Display senden


  for(;;)
  {
    
    if (PINC==0xFD)                      //wenn Scroll-Taster gedrückt...
    {
      AnzahlDurchlaufe++;
      lcd_puts("Messung-1 ok? Sd");
                    //erhöhe AnzahlDurchlaufe auf EINS
      Disp_Ctrl();
      for (;PINC != 0xFE;)                                //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird
      {
      lcd_puts("Messung-x ok? Sd");
      Disp_Ctrl();  
      }

    }

    if (TIFR &(1<<TOV0))                   //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins
      {
        overflow++;
        TIFR = 1<<TOV0;
      }

       switch(PINB)
      {
        
            case 0xFE:
        TCCR0 |=  (1<<CS00)|(1<<CS02);                 //Timer starten                  
          reg[0]=TCNT0;
          ubergabe[0]=overflow;
      break;



      case 0xFD:
        reg[1]=TCNT0;
                ubergabe[1]=overflow;
      break;



      case 0xFB:
        reg[2]=TCNT0;
        ubergabe[2]=overflow;
      break;



      case 0xF7:
        reg[3]=TCNT0;
        ubergabe[3]=overflow;
      break;



      case 0xEF:
        reg[4]=TCNT0;
        ubergabe[4]=overflow;
      break;



      case 0xDF:
        reg[5]=TCNT0;
        ubergabe[5]=overflow;
      break;
      
      
        
      case 0xBF:
        reg[6]=TCNT0;
        ubergabe[6]=overflow;
      break;



      case 0x7F:
        reg[7]=TCNT0;
        ubergabe[7]=overflow;
      break;
  
    }                              //Ab hier Sendevorgang über RS232

  if (PINC==0xFE)                          //wenn Send-Taster gedrückt...
  {
    senda();                          //schicke "a"...
    
    for(Sicherheitsloop=0;Sicherheitsloop<50;Sicherheitsloop++) //Schickt das Ganze 50x an das VB-Programm (aus Sicherheitsgründen)
    {
      for(iZaehl=0; iZaehl <= 7; iZaehl++)                    //schickt die einzelnen Reg./Überlauf-Einträge an das VB-Programm
      {
        wandle(reg[i+AnzahlDurchlaufe]);
        sendx();
        wandle(ubergabe[i+AnzahlDurchlaufe]);
      }
      TCCR0=0;                          //Timer-Reg. auf NULL
    }  


  }

}
}



Danke für eure Hilfe, ist wichtig!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marcus W. (blizzi)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Björn (Gast)
Datum:

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

danke

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tupf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das führte auch zu keinem Ergebnis....habe es gerade probiert.

Autor: Björn (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier schicke ich mal den Dateianhang vom gesamten Projekt.

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Björn (Gast)
Datum:

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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ENTWARNUNG!

Es geht....

Hier der funktionierende Code zum Ein-/Ausschalten des STK500 ohne 
zwischenfälle:
/*************************************************************************
Title:    testing output to a HD44780 based LCD display.
Author:   Peter Fleury  <pfleury@gmx.ch>  http://jump.to/fleury
File:     $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
Software: AVR-GCC 3.3
Hardware: HD44780 compatible LCD text display
          ATS90S8515/ATmega if memory-mapped LCD interface is used
          any AVR with 7 free I/O pins if 4-bit IO port mode is used
**************************************************************************/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "lcd.h"
unsigned int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = c;                      /* sende Zeichen */
  return 0;
}

//---------------------------------------------------------------------------
int sendx(void)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = 'x';                      /* sende Zeichen */
}
int senda(void)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }
 
  UDR = 'a';                      /* sende Zeichen */
}

//---------------------------------------------------------------------------

void uart_puts (unsigned char *s)
{
  while (*s)
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    uart_putc(*s);
    s++;
  }
}
//-------------------------------------------------------------------------------
unsigned int wandle(unsigned int y)
{
unsigned char Buffer[20];
  unsigned int i = y;

  sprintf( Buffer, "%u", i );

  uart_puts( Buffer );

}

/*
** constant definitions
*/
static const PROGMEM unsigned char copyRightChar[] =
{
  0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
  0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
};


/*
** function prototypes
*/ 
void wait_until_key_pressed(void);


void wait_until_key_pressed(void)
{
    unsigned char temp1, temp2;
    unsigned int i;
    
    do {
        temp1 = PIND;                  // read input
        for(i=0;i<65535;i++);
        temp2 = PIND;                  // read input
        temp1 = (temp1 & temp2);       // debounce input
    } while ( temp1 & _BV(PIND2) );
    
    loop_until_bit_is_set(PIND,PIND2);            /* wait until key is released */
}







int main(void)
{
    char buffer[7];
    int  num=134;
    
    
    
    DDRD &=~ (1 << PD2);        /* Pin PD2 input              */
    PORTD |= (1 << PD2);        /* Pin PD2 pull-up enabled    */


    /* initialize display, cursor off */
    lcd_init(LCD_DISP_ON);

     unsigned int overflow = 0;
    unsigned int ubergabe[40] = {0};
  unsigned int reg[40] = {0};
  unsigned int Sicherheitsloop = 0;
  unsigned short iZaehl = 0;
  unsigned char i = 0;
  unsigned short AnzahlDurchlaufe = 0;
  
  DDRD =0xFF;                         //UART
  DDRB =0x00;                         //Lichtschranken
  DDRA =0xFF;                        //Port für LCD
  DDRC =0x00;                         //Port für div. Steuer-Taster


  PORTA = 0x00;


  //TCCR0 |=  (1<<CS00)|(1<<CS02);              //Prescaler für Timer auf 1024          

  UCSRB |= (1<<TXEN);                            //Senden aktivieren
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  

  UBRRH = 00;                                    //Baudrate einstellen 9600 bei 8 MHz
  UBRRL = 51;

         
         
        lcd_clrscr();                      //Display löschen
        lcd_puts("SC-SW: Durchgang");              //Ausgangstext auf dem Display
                                                    //Steuerbefehl an das Display senden


  for(;;)
  {
    
    if (PINC==0x01)                      //wenn Scroll-Taster gedrückt...
    {
      AnzahlDurchlaufe++;
      lcd_puts("Messung-1 ok? Sd");                    //erhöhe AnzahlDurchlaufe auf EINS
      
      for (;PINC != 0xFE;)                                //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird
      {
      lcd_puts("Messung-x ok? Sd");
        
      
      }
    }
  if (TIFR &(1<<TOV0))                   //wenn generell Überlauf, erhöhe Variable "uberlauf" um eins
      {
        overflow++;
        TIFR = 1<<TOV0;
      }

       switch(PINB)
      {
        
            case 0xFE:
        TCCR0 |=  (1<<CS00)|(1<<CS02);                 //Timer starten                  
          reg[0]=TCNT0;
          ubergabe[0]=overflow;
      break;



      case 0xFD:
        reg[1]=TCNT0;
                ubergabe[1]=overflow;
      break;



      case 0xFB:
        reg[2]=TCNT0;
        ubergabe[2]=overflow;
      break;



      case 0xF7:
        reg[3]=TCNT0;
        ubergabe[3]=overflow;
      break;



      case 0xEF:
        reg[4]=TCNT0;
        ubergabe[4]=overflow;
      break;



      case 0xDF:
        reg[5]=TCNT0;
        ubergabe[5]=overflow;
      break;
      
      
        
      case 0xBF:
        reg[6]=TCNT0;
        ubergabe[6]=overflow;
      break;



      case 0x7F:
        reg[7]=TCNT0;
        ubergabe[7]=overflow;
      break;
  
    }                              //Ab hier Sendevorgang über RS232

  if (PINC==0xFE)                          //wenn Send-Taster gedrückt...
  {
    senda();                          //schicke "a"...
    
    for(Sicherheitsloop=0;Sicherheitsloop<50;Sicherheitsloop++) //Schickt das Ganze 50x an das VB-Programm (aus Sicherheitsgründen)
    {
      for(iZaehl=0; iZaehl <= 7; iZaehl++)                    //schickt die einzelnen Reg./Überlauf-Einträge an das VB-Programm
      {
        wandle(reg[iZaehl+AnzahlDurchlaufe]);
        sendx();
        wandle(ubergabe[iZaehl+AnzahlDurchlaufe]);
      }
      TCCR0=0;                          //Timer-Reg. auf NULL
    }  


  

}
}}



Vielen Dank!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
for(;;)
  {
    
    if (PINC==0xFE)                      //wenn Scroll-Taster gedrückt...
    {
      AnzahlDurchlaufe++;
      lcd_clrscr();
      lcd_puts("Messung-1 ok? Sd");                    //erhöhe AnzahlDurchlaufe auf EINS
    }  
      for (;PINC != 0xFE;)                                //solange in der Schleife bleiben, bis "SEND"-Taster zum Starten der Messung gedrückt wird
      {
      lcd_clrscr();
      lcd_puts("Messung-x ok? Sd");
        
   }    
Geht es wirklich nicht ohne diese Entprellung, falls nein, stoße ich 
langsam auf ein Speicherproblem zwecks Programmcode von meinem 
Mikrocontroller ATmega8515.

Gruß

Autor: Jens 343 (jens343)
Datum:

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

Autor: Marcus W. (blizzi)
Datum:

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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der Fehler lag im Timing, habe eine header-Datei falsch eingebunden

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
könntet ihr mir nochmal mit dem Taster helfen??


Danke

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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."

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Geier Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?!?

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Björn (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Björn (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

void Disp_Messung(char i)
{
#if 1
  char buffer[2];

  if (i < 1 || i > 5)
    return;

  lcd_puts("Messung - ");
  buffer[0] = '0' + i; 
  buffer[1] = 0; 
  lcd_puts(buffer);
  lcd_puts(" ?\nOK = OK-Taste");
#else
  switch (i)
  {
    case 1:  lcd_puts("Messung - 1 ?\nOK = OK-Taste");
             break;    
    case 2:  lcd_puts("Messung - 2 ?\nOK = OK-Taste");
             break;
    case 3:  lcd_puts("Messung - 3 ?\nOK = OK-Taste");
             break;
    case 4:  lcd_puts("Messung - 4 ?\nOK = OK-Taste");
             break;
    case 5:  lcd_puts("Messung - 5 ?\nOK = OK-Taste");
             break;
  }
#endif
}

Timer
Was du mit dem Timer treibst (Anfang der for-Schleife) verstehe ich 
nicht bzw. sehe nicht, dass irgendwo ein Timer gestartet wird.

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil ich zu dumm bin eine solche zu verstehen.

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

    // PINC2
    if (OKTASTE) //Wenn OK-Taste gedrückt...
    {
      lcd_clrscr();
      Messung_laeuft(tastenzaehler-1);
      while(OKTASTE);
    } // 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: sven s. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Björn (Gast)
Datum:

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

Werde ich daheim dann mal probieren.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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/Entprellun...


Die Repeatfunktion kann man drinlassen, auch wenn man sie nicht benutzt, 
sind ja nur 2 Bytes SRAM zusätzlich.


Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.