Hallo,
nachdem ich mich nun lange Zeit nicht mehr mit den AVRs beschäftigt habe, bestellt ich mir vor einigen tagen ein 4,3 Zoll XV-TFT60D Display. Soweit bin ich auch ganz begeistert von dem guten Stück.
Allerdings habe ich jetzt ein (oder besser zwei) Problem(e) mit meiner Interrupt Abfrage für die Touchscreen Koordinaten. Da ich den Dirk nicht weiter per E-Mail belästigen möchte, frage ich hier im Forum mal nach .
Den Code habe ich größtenteils aus dem Beispiel "MenuDemo" übernommen und ein wenig auf mein Projekt angepasst. Allerdings lasse ich einen Interrupt auslösen, wenn eine fallende Flanke vom TINT Signal erzeugt wird, also wenn ein Touchscreen Event besteht. Das ganze funktioniert soweit auch ganz gut, nur überspringt mein Mikroprozessor (ATmega32) scheinbar diese Passage:
Im unteren Bereich des Displays befindet sich ein Menüs mit vier auswählbaren Icons. Das Menü soll auch nur gewechselt werden, wenn in diesem unteren Bereich etwas ausgewählt wird. Leider wechselt das Display aber das Menü auch, wenn ich ich im oberen Bereich (also über den Icons) etwas auswähle. Meine Funktion "Play_Break ();" ist ihm scheinbar auch vollkommen egal .
Das zweite Problem besteht im Timing:
Ich muss grundsätzlich mit der for-Schleife eine gewisse Zeit überbrücken, weil ansonsten sämtliche TouchEvents ignoriert werden. Die Lösung mit der Pause gefällt mir leider gar nicht, gibt es vielleicht noch einen besseren Lösungsansatz? Ich vermute mal, dass der Displaycontroller nach dem "DisplayDecimalSigned16 (5, 130, (100 - meter));" noch etwas beschäftigt ist und somit nicht sofort auf ein TouchEvent reagieren kann.
So hier noch die vollständige "main.c" Datei:
Gruß
Fabi
nachdem ich mich nun lange Zeit nicht mehr mit den AVRs beschäftigt habe, bestellt ich mir vor einigen tagen ein 4,3 Zoll XV-TFT60D Display. Soweit bin ich auch ganz begeistert von dem guten Stück.
Allerdings habe ich jetzt ein (oder besser zwei) Problem(e) mit meiner Interrupt Abfrage für die Touchscreen Koordinaten. Da ich den Dirk nicht weiter per E-Mail belästigen möchte, frage ich hier im Forum mal nach .
Den Code habe ich größtenteils aus dem Beispiel "MenuDemo" übernommen und ein wenig auf mein Projekt angepasst. Allerdings lasse ich einen Interrupt auslösen, wenn eine fallende Flanke vom TINT Signal erzeugt wird, also wenn ein Touchscreen Event besteht. Das ganze funktioniert soweit auch ganz gut, nur überspringt mein Mikroprozessor (ATmega32) scheinbar diese Passage:
Code:
if (touchy < (272-71)) return;
Im unteren Bereich des Displays befindet sich ein Menüs mit vier auswählbaren Icons. Das Menü soll auch nur gewechselt werden, wenn in diesem unteren Bereich etwas ausgewählt wird. Leider wechselt das Display aber das Menü auch, wenn ich ich im oberen Bereich (also über den Icons) etwas auswähle. Meine Funktion "Play_Break ();" ist ihm scheinbar auch vollkommen egal .
Das zweite Problem besteht im Timing:
Code:
do
{
DisplayDecimal16 (45, 60, meter);
DisplayDecimalSigned16 (5, 130, (100 - meter));
for (i=0; i<100; i++)
{
if (scantouch == TOUCH)
{
Menu_Scan (); //This routine manages menu_state variable
Play_Break ();
scantouch = NOTOUCH;
}
_delay_ms (10);
}
} while (!(menu_state & (1<<menu_state_changed)));
So hier noch die vollständige "main.c" Datei:
Code:
#include <avr/io.h> //Headerdatei für Ports
#include <avr/wdt.h>
#include <util/delay.h>
#include <stdlib.h> //Headerdatei für Standardroutinen
#include <avr/interrupt.h> //Headerdatei für Interrupts
#include <avr/pgmspace.h>
#include "Display_SPI.h"
#include "Display_Graphics.h"
#include "Display_Numerical.h"
#include "Display_TouchPanel.h"
#include "Display_UserMemory.h"
#include "Display_Text.h"
#include "Display_System.h"
#define nop() __asm volatile ("nop")
#define menu_state_changed 0
#define PLAY 1
#define BREAK 0
#define TOUCH 1
#define NOTOUCH 0
//Funktionen
void Menu_Init (uint8_t index);
void Menu_Scan (void);
void Play_Break (void);
void Parameter_show (void);
void Parameter_settings (void);
void Container (void);
void Shutdown (void);
//variables used by menu
uint8_t menu_index;
uint8_t menu_state;
uint8_t pulse;
uint8_t counter_meter = PLAY;
uint16_t meter;
uint8_t scantouch;
uint16_t touchx, touchy;
//Interrupt bei fallender Flanke an PD2 //Hallsensor event
ISR (INT0_vect)
{
if (counter_meter == BREAK) return;
if (pulse < 1) //Anzahl der Impulse für einen Meter //12 magneten = 9meter/270impulse 30imp/meter
{
pulse++;
}
else
{
pulse = 0;
meter++;
}
}
//Interrupt bei fallender Flanke an PD3 //Touch event
ISR (INT1_vect)
{
uint8_t data;
if (!(TOUCHPANEL_EVENT)) return;
data = TouchPanel_ReadEvent();
if (!(data & TOUCH_EVENT_DOWN)) return;
if (scantouch == TOUCH) return;
if (!(TouchPanel_ReadDown(&touchx, &touchy))) return;
scantouch = TOUCH;
}
int main (void)
{
SPI_Init (); // Display Interface
_delay_ms (100);
_delay_ms (100);
_delay_ms (100);
while (DISPLAY_BUSY) {nop(); }
TouchPanel_SetConfig (TOUCH_EVENT_DOWN); //Enable Event TOUCH_EVENT_DOWN
TouchPanel_ReadEvent();
//Standardeinstellung am Display vornehmen
SetPenColor (0, 0, 0);
SetBrushColor (255, 255, 255);
SetUserFlashMemoryFont (60, 0); //Standardschrift
NumericalConfig (1<<1); //Zahlen ohne führende Null
SetDisplayMode (DISPLAYMODE_Landscape);
FillScreen_BrushColor (); // Clear screen
SetBacklightIntensity (255); // Max. backlight brightness
menu_index = 255;
Menu_Init (0); // Initialize menu 0
//Interrupt INT0 an PD2 und INT1 an PD3 auf fallende Flanke stellen
MCUCR |= (1<<ISC11)|(1<<ISC01);
GICR |= (1<<INT1)|(1<<INT0);
sei (); //Interrupt global aktivieren
while(1)
{
if (0 == menu_index) Parameter_show();
else
if (1 == menu_index) Parameter_settings();
else
if (2 == menu_index) Container();
else
if (3 == menu_index) Shutdown();
}
return 0;
}
//Hauptmenü initialisieren
void Menu_Init (uint8_t index)
{
if (index == menu_index) return; //Menü bereits aktiv
DisplayImagePackage_Image(0, 272-71, 0, index); //Passendes Menübild laden
menu_index = index;
menu_state |= (1<<menu_state_changed);
}
//Hauptmenü Tastendruck abfragen
void Menu_Scan (void)
{
uint8_t i;
uint16_t menu;
if (touchy < (272-71)) return;
for (i=0; i<4; i++)
{
if ((touchx > menu) && (touchx < (menu+120)))
{
Menu_Init(i);
return;
}
menu += 120;
}
}
//Play und Pausen Funktion der Streckenmessung
void Play_Break (void)
{
if ((touchx < 386) || (454 < touchx)) return;
if ((touchy < 91) || (159 < touchy)) return;
if (counter_meter == PLAY)
{
DisplayImagePackage_Image (386, 91, 3, 1);
counter_meter = BREAK;
}
else
{
DisplayImagePackage_Image (386, 91, 3, 0);
counter_meter = PLAY;
}
}
//Hauptmenue: Parameter show
void Parameter_show (void)
{
uint8_t i;
DrawRect_BrushColorFill (0, 0, 480, 272-72); // Clear Application Screen
SetBrushColor (205, 205, 205);
DrawRect_BrushColorFill (0, 0, 480, 50);
SetUserFlashMemoryFont (61, 0); //40px Arial proportional character align
DisplayText (5, 5, "Produktname");
SetBrushColor (255, 255, 255);
DisplayText (240, 75, "Meter");
DisplayText (240, 145, "Meter");
SetUserFlashMemoryFont (62, 2); //60px Arial center align
if (counter_meter == PLAY)
{
DisplayImagePackage_Image (386, 91, 3, 0);
}
else
{
DisplayImagePackage_Image (386, 91, 3, 1);
}
menu_state &= ~(1<<menu_state_changed); // confirm status flag
//Hauptschleife in der Routine
do
{
DisplayDecimal16 (45, 60, meter);
DisplayDecimalSigned16 (5, 130, (100 - meter));
for (i=0; i<100; i++)
{
if (scantouch == TOUCH)
{
Menu_Scan (); //This routine manages menu_state variable
Play_Break ();
scantouch = NOTOUCH;
}
_delay_ms (10);
}
} while (!(menu_state & (1<<menu_state_changed)));
SetUserFlashMemoryFont (60, 0); //Standardschrift
}
//Hauptmenue: Parameter settings
void Parameter_settings (void)
{
DrawRect_BrushColorFill (0, 0, 480, 272-72); // Clear Application Screen
SetBrushColor (205, 205, 205);
DrawRect_BrushColorFill (0, 0, 480, 50);
SetUserFlashMemoryFont (61, 0); //40px Arial proportional character align
DisplayText (5, 5, "Achtung!");
SetBrushColor (255, 255, 255);
SetUserFlashMemoryFont (60, 0); //Standardschrift
DisplayText (5, 55, "Moechten Sie die Auswahl wirklich bestaetigen?");
DisplayImagePackage_Image (0, 129, 1, 0);
menu_state &= ~(1<<menu_state_changed); // confirm staus flag
//Hauptschleife in der Routine
do
{
if (scantouch == TOUCH)
{
Menu_Scan (); //This routine manages menu_state variable
scantouch = NOTOUCH;
}
} while (!(menu_state & (1<<menu_state_changed)));
SetUserFlashMemoryFont (60, 0); //Standardschrift
}
//Hauptmenue: Container
void Container (void)
{
DrawRect_BrushColorFill (0, 0, 480, 272-72); // Clear Application Screen
DisplayImagePackage_Image (0, 0, 2, 1);
menu_state &= ~(1<<menu_state_changed); // confirm status flag
//Hauptschleife in der Routine
do
{
if (scantouch == TOUCH)
{
Menu_Scan (); //This routine manages menu_state variable
scantouch = NOTOUCH;
}
} while (!(menu_state & (1<<menu_state_changed)));
}
//Hauptmenue: Shutdown
void Shutdown (void)
{
DrawRect_BrushColorFill (0, 0, 480, 272-72); // Clear Application Screen
DisplayImagePackage_Image (0, 0, 2, 0);
menu_state &= ~(1<<menu_state_changed); // confirm status flag
//Hauptschleife in der Routine
do
{
if (scantouch == TOUCH)
{
Menu_Scan (); //This routine manages menu_state variable
scantouch = NOTOUCH;
}
} while (!(menu_state & (1<<menu_state_changed)));
}
Gruß
Fabi