Forum: Mikrocontroller und Digitale Elektronik Problem ATMEGA2560


von Fredl (Gast)


Lesenswert?

Grüß euch,

habe folgendes Problem: Bin gerade dabei eine Tastatur zu programmieren. 
Auf einem standard 4x20 Display steht in der 1. Zeile "Bitte Zahl 
eingeben". Wenn ich nun eine Taste drücke wird die ISR abgearbeitet und 
die Tastennummer am Display angezeit. Nun ist es aber so, dass die 
Nummer an der richtigen Stelle am Display angezeigt wird ABER der 
Display-Text teilweise unvollständig in andere Zeilen kopiert wird z.B. 
in der 2.Zeile steht "itte" un in der 4. "ngeben"

Passt da was mit dem Stackpointer nicht, Adressbereich, Größe etc.? 
Verwende AVR STudio 4 mit dem GCC Compiler von WINAVR.

Wäre toll, wenn mir wär Tipps geben könnte.

lf Fred

von Fredl (Gast)


Lesenswert?

HAbe gerade gelesen, dass der WINAVR Compiler den ATMEGA2560 gar nicht 
unterstützt sondern nur den 2561-er Chip. Komischerweise steht auch im 
AVRStudio unter Flash-Size:0x20000 das wären aber dann ja nur 128kB und 
nicht 256, mhhhh

Fred

von Pete K. (pete77)


Lesenswert?

Du möchtest einen Tipp ? --> Poste mal den source code, wie sollen wir 
sonst helfen ?

Könnte auch ein String Problem oder eine falsche Schleifenindizierung 
sein.

von Fredl (Gast)


Lesenswert?

#include <avr/interrupt.h>
#include <avr/io.h>
#include <math.h>
#include "macros.h"
#include "lcd.h"
#include "i2c.h"
#include "i2ceeprom.h"
#include "i2cclock.h"
#include "i2cswitch.h"
#include "mdb.h"
#include "spi.h"
#include "keyboard.h"
#include "menue.h"
#include "memory.h"
#include "mixdrink.h"



volatile unsigned int value_new=0;
unsigned char InPutNr[4];
extern volatile char lcd_x;
unsigend char tmp0=0;
unsigned char Kaffeestaerke=1;

SIGNAL (SIG_INTERRUPT6) // Externer Interrupt Tastatur
{
  cli();
  EIMSK=0x00;

  I2C_SetSwitch(0x7E,0xFD); //Enable  Touch Screen Controller
  warte(1);
  spi_writeword_tsc(0x0820,0x7800); // De-bounce 120ms in Page 1, 
Address 1
  I2C_SetSwitch(0x7E,0xFF); //Disable Touch Screen Controller
  warte(1);


    if(InPutNr[lcd_x-16]=='\0' && lcd_x<20)
        InPutNr[lcd_x-16]='\0';

      value_new=GetKey(VENDING,lcd_x,2);

      if(value_new>=0x20 && value_new<=0x7E) //Zeichen wurde eingegeben
      {  tmp0=1;
         InPutNr[lcd_x-16]=value_new;
         if(lcd_x<18)++lcd_x;
      }

    if(value_new==VIRTUAL_KEY_DOSIERUNG)
      {
        Kaffeestaerke++;
        if(Kaffeestaerke>1)Kaffeestaerke=-1;
        print_lcd(3,1,"%p %d  ",MSG_MAINMENU_COFE,(Kaffeestaerke+2) );
      }

      else
        InPutNr[lcd_x-16]=0;

  warte(300); //Wait 300ms

  I2C_SetSwitch(0x7E,0xFD); //Enable  Touch Screen Controller
  warte(1);
  spi_writeword_tsc(0x0820,0x3800); // De-bounce 120ms in Page 1, 
Address 1
  I2C_SetSwitch(0x7E,0xFF); //Disable of Touch Screen Controller
  warte(1);

  EIMSK=0x40;
  sei();

}


void main()
{
......

while(1)
{
   print_lcd(1,1,"Bitte Zahl eingeben");
}
}



Ich habe hier mal nur einen Teil des Codes beigefügt, den ich momentan 
ausführe! In der Fkt. GetKey(VENDING,lcd_x,2) wird der Tastatur 
COntroller mittels SPI eingelesen und die Daten dann entsprechend einer 
Tabelle dekodiert. Das fkt. auch problemlos, eben nur der Display Text 
verschiebt sich bzw. wird kopiert und teilstücke auf den 4 zeilen 
dargestellt nachdem der µC con der ISR zurückkommt.

mfg
Fred

lg manfred

von Pete K. (pete77)


Lesenswert?

Die Variable Kaffestärke ist als char deklariert, aber als Zahl 
verwendet. Ebenso lcd_x und tmp. Versuche mal mit unsigned int.

Schau generell mal nach char/int.

Die Wartezeiten erscheinen mir im Interrupt auch sehr lang.

von Fredl (Gast)


Lesenswert?

Hallo Pete,

hab ich nun gemacht aber hilft auch nix, der Display Text spielt noch 
imma verrrückt. Hab auch schon den neuen GCC Compiler runter geladen, 
keine besserung. Sobald die ISR abgearbeitet wird haut es den Text am 
Display durcheiander. Gibt es irgendwo einstellungen im AVR Studio die 
manuell nachgstellt werden sollten/müssen?

lg fred

von Pete K. (pete77)


Lesenswert?

Poste bitte noch einmal Deine Änderungen.

von Fredl (Gast)


Lesenswert?

volatile unsigned int value_new=0;
unsigned char InPutNr[4];
extern volatile  unsigned int  tmp0;
extern volatile unsigned int lcd_x;
int Kaffeestaerke=1;

SIGNAL (SIG_INTERRUPT6) // Externer Interrupt Tastatur
{
  cli();
  EIMSK=0x00;

  I2C_SetSwitch(0x7E,0xFD); //Enable  Touch Screen Controller
  warte(1);
  spi_writeword_tsc(0x0820,0x7800); // De-bounce 120ms in Page 1,
Address 1
  I2C_SetSwitch(0x7E,0xFF); //Disable Touch Screen Controller
  warte(1);


    if(InPutNr[lcd_x-16]=='\0' && lcd_x<20)
        InPutNr[lcd_x-16]='\0';

      value_new=GetKey(VENDING,lcd_x,2);

      if(value_new>=0x20 && value_new<=0x7E) //Zeichen wurde eingegeben
      {  tmp0=1;
         InPutNr[lcd_x-16]=value_new;
         if(lcd_x<18)++lcd_x;
      }

    if(value_new==VIRTUAL_KEY_DOSIERUNG)
      {
        Kaffeestaerke++;
        if(Kaffeestaerke>1)Kaffeestaerke=-1;
        print_lcd(3,1,"%p %d  ",MSG_MAINMENU_COFE,(Kaffeestaerke+2) );
      }

      else
        InPutNr[lcd_x-16]=0;

 // warte(300); //Wait 300ms

  I2C_SetSwitch(0x7E,0xFD); //Enable  Touch Screen Controller
  warte(1);
  spi_writeword_tsc(0x0820,0x3800); // De-bounce 120ms in Page 1,
Address 1
  I2C_SetSwitch(0x7E,0xFF); //Disable of Touch Screen Controller
  warte(1);

  EIMSK=0x40;
  sei();

}


void main()
{
......

while(1)
{
   print_lcd(1,1,"Bitte Zahl eingeben");
}
}

lg fred

von Johannes M. (johnny-m)


Lesenswert?

cli() und sei() haben im Interrupt Handler nichts verloren, das Sperren 
und wieder-Freigeben der Interrupt-Bearbeitung wird von der Hardware 
automatisch gemacht. Genauso sinnfrei ist es, den Interrupt im Handler 
lokal zu sperren und am Ende wieder freizugeben (das wird schließlich 
durch die globale Freigabe bereits erledigt). Die Bearbeitung weiterer 
Interrupts ist während der Abarbeitung eines Interrupt Handlers sowieso 
nicht möglich.

Wenn während der Bearbeitung dieses (eigentlich viel zu langen) 
Interrupt Handlers ein erneutes Interrupt-Ereignis auftritt, dann wird 
der Handler praktisch sofort, nachdem er verlassen wird, erneut 
aufgerufen. Wenn Du das verhindern willst, musst Du das Interrupt-Flag 
vor dem Ende des Interrupt-Handlers löschen. Die Freigabe-Bits bringen 
da gar nichts.

Und wenn Du noch das beachtest, was unter den "wichtigen Regeln" bei 
"Formatierung" steht und den Code vernünftig formatierst, dann ist er 
auch leichter lesbar.

von Pete K. (pete77)


Lesenswert?

Was steht denn in MSG_MAINMENU_COFE und wie ist das deklariert ?

Wird noch irgendwo anders etwas auf dem Display ausgegeben ?

von Fredl (Gast)


Lesenswert?

const unsigned char MSG_MAINMENU_COFE[] PROGMEM = "Kaffeestaerke:";

ja in der Fkt. GetKey(VENDING,lcd_x,2);



unsigned int GetKey(KeyMode Mode, unsigned char lcd_x, unsigned char 
lcd_y)
{
  unsigned int  KeyCode=NOKEY, KeyCount=1, KeyHold=0, t1_ov=0x00;
  unsigned int KEYDATA_TEMP=0;

  I2C_SetSwitch(0x7E,0xFD);
  warte(1);
  KeyCode=KEYDATA;
  I2C_SetSwitch(0x7E,0xFF);
  warte(1);

 if(DecodeKey(KeyCode, KeyCount,0 , Mode)>=VIRTUAL_KEY_CONTROL_BEGIN && 
DecodeKey(KeyCode, KeyCount,0 , Mode)<=VIRTUAL_KEY_CONTROL_END && 
lcd_y!=0x00&&Mode!=ALPHA)
 {
 print_lcd(lcd_y, lcd_x,"%c",DecodeKey(KeyCode, KeyCount, 0, Mode));

  }
else return (NOKEY);

return KeyCode;

}



@KEYDATA: wird in der keyboard.h deklariert
#define KEYDATA  spi_readword_tsc(KEYP_DATA); // Read KEYPAD Data 
Register

von Pete K. (pete77)


Lesenswert?

Ich vermute, dass irgendwo über ein Stringende herausgeschrieben wird 
oder ungültige Zeichen geschrieben werden.

Mach mal eine debug-Ausgabe (z.B. über uart) in der Funktion print_lcd() 
und schaue Dir den String an, der ausgegeben werden soll.

von Pete K. (pete77)


Lesenswert?

Der Compiler müsste eigentlich ein paar Warnungen ausgeben. Bitte alle 
beheben.

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.