Problem ATMEGA2560

Gast #942224
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
Gast #942308
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
Gast #942354
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
Gast #942380
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
#942391
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.
Gast #942408
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren