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
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
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.
#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
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.
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
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
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.
Was steht denn in MSG_MAINMENU_COFE und wie ist das deklariert ? Wird noch irgendwo anders etwas auf dem Display ausgegeben ?
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.