Zarathustra
12.04.2007, 10:36
Hallo!
Ich habe ein Problem.
Ich bin dabei einen LCD- Kontroll-ATmega8 zu programmieren. Kann ihn über I2C erreichen und die Fleury Bibliothek von aussen ansprechen.
Nun will ich auch noch Eingaben über den mega8 ermöglichen. Dazu habe ich 4 Taster, wovon alle mit dem INT1, und 3 mit jeweils einem eigenen Port verbunden sind um die Interrupts zu identifizieren.
Das Problem:
Kombinationen von gedrückten Tasten werden anscheinend nicht richtig erkannt. Hier ein paar Beispiele:
1) START drücken -> Admin Modus (klappt)
2) LINKS oder RECHTS drücken -> alles hängt sich auf
- halte ich nach 1) START gedrückt passiert garnichts obwohl er den Prüfmodus starten müsste
- wenn ich statt 2) nochmal START drücke, MACHT er den Prüfmodus und:
- wenn ich DANACH LINKS oder RECHTS drücke, hängt er sich nicht mehr auf!
- LINKS und RECHTS zusammen: er geht nicht in den SUADMIN Modus sondern krebst fröhlich weiter im ADMIN Modus herum.
- Verlassen des Admin Modus durch SELECT, LINKS und RECHTS zusammen klappt auch nicht.
Ich poste einfach mal den Code hier hinein, Unwichtiges habe ich aus den Klammern herausgenommen:
die Interruptroutine:
// Pinbelegung der Buttons
// Start: INT1 (D3)
// Select: INT1 (D3) & D4
// Left: INT1 (D3) & D0
// Right: INT1 (D3) & D1
#define BUTTON_START (!(PIND&(1<<PD3))&&(PIND&(1<<PD0))&&(PIND&(1<<PD1))&&(PIND&(1<<PD4)))
#define BUTTON_SELECT (!(PIND&(1<<PD4)))
#define BUTTON_LEFT (!(PIND&(1<<PD0)))
#define BUTTON_RIGHT (!(PIND&(1<<PD1)))
ISR(INT1_vect)
{
if(mode == IDLE && BUTTON_START) // Admin Modus betreten
{
// I²C wird deaktiviert um Störung von aussen zu vermeiden
mode = ADMIN;
}
else if(BUTTON_RIGHT && BUTTON_LEFT && !BUTTON_SELECT) // SuAdmin Modus betreten/verlassen
{
if(mode == ADMIN)
{
mode = SUADMIN;
// Optionen werden angezeigt
}
else if(mode == SUADMIN)
{
mode = ADMIN;
}
}
else if(mode == SUADMIN && BUTTON_START) // SuAdmin: Auswahl
{
// Mit dem Cursor ausgewählte Optionen können hiermit bestätigt werden
}
else if(mode == ADMIN && BUTTON_START) // Selbsttest
{
// einige Registerinhalte werden ausgegeben
}
else if(mode != IDLE && BUTTON_LEFT && !BUTTON_RIGHT && !BUTTON_SELECT) // Display links
{
lcd_command(LCD_MOVE_DISP_RIGHT);
}
else if(mode != IDLE && BUTTON_RIGHT && !BUTTON_LEFT && !BUTTON_SELECT) // Display rechts
{
lcd_command(LCD_MOVE_DISP_LEFT);
}
else if(mode != IDLE && BUTTON_SELECT && BUTTON_LEFT && !BUTTON_RIGHT) // Cursor links
{
lcd_command(LCD_MOVE_CURSOR_LEFT);
}
else if(mode != IDLE && BUTTON_SELECT && BUTTON_RIGHT && !BUTTON_LEFT) // Cursor rechts
{
lcd_command(LCD_MOVE_CURSOR_RIGHT);
}
else if(mode == ADMIN && BUTTON_SELECT && BUTTON_LEFT && BUTTON_RIGHT) // Adminmodus verlassen
{
modus = IDLE;
}
// Entprellung & Zeitabstand, 150ms warten
warte_ds(15);
}
int main()
.... einige Zuweisungen und Initialisierungen ....
while(1)
{
switch(mode)
{
case IDLE:
ledSwitch(led_modus, led_color, led_aktion);
break;
case ADMIN:
ledSwitch(STANDBY, BLUEWHITE, 50);
break;
case SUADMIN:
ledSwitch(BLUE1, BLUE2, 40);
ledSwitch(STATIC, ALL, OFF);
ledSwitch(STATIC, DBLUE, ON);
warte_ds(40);
break;
}
Es passieren also Dinge, die an sich nicht passieren dürften weil es theoretisch geht, auch der AVR Simulator macht es so wie ich will.
Ist die INT Routine vielleicht zu voll?
Hoffe, jemand kann mir ne Antwort geben, Fehler finden oder Vorschläge machen,
Gruß,
Markus
Ich habe ein Problem.
Ich bin dabei einen LCD- Kontroll-ATmega8 zu programmieren. Kann ihn über I2C erreichen und die Fleury Bibliothek von aussen ansprechen.
Nun will ich auch noch Eingaben über den mega8 ermöglichen. Dazu habe ich 4 Taster, wovon alle mit dem INT1, und 3 mit jeweils einem eigenen Port verbunden sind um die Interrupts zu identifizieren.
Das Problem:
Kombinationen von gedrückten Tasten werden anscheinend nicht richtig erkannt. Hier ein paar Beispiele:
1) START drücken -> Admin Modus (klappt)
2) LINKS oder RECHTS drücken -> alles hängt sich auf
- halte ich nach 1) START gedrückt passiert garnichts obwohl er den Prüfmodus starten müsste
- wenn ich statt 2) nochmal START drücke, MACHT er den Prüfmodus und:
- wenn ich DANACH LINKS oder RECHTS drücke, hängt er sich nicht mehr auf!
- LINKS und RECHTS zusammen: er geht nicht in den SUADMIN Modus sondern krebst fröhlich weiter im ADMIN Modus herum.
- Verlassen des Admin Modus durch SELECT, LINKS und RECHTS zusammen klappt auch nicht.
Ich poste einfach mal den Code hier hinein, Unwichtiges habe ich aus den Klammern herausgenommen:
die Interruptroutine:
// Pinbelegung der Buttons
// Start: INT1 (D3)
// Select: INT1 (D3) & D4
// Left: INT1 (D3) & D0
// Right: INT1 (D3) & D1
#define BUTTON_START (!(PIND&(1<<PD3))&&(PIND&(1<<PD0))&&(PIND&(1<<PD1))&&(PIND&(1<<PD4)))
#define BUTTON_SELECT (!(PIND&(1<<PD4)))
#define BUTTON_LEFT (!(PIND&(1<<PD0)))
#define BUTTON_RIGHT (!(PIND&(1<<PD1)))
ISR(INT1_vect)
{
if(mode == IDLE && BUTTON_START) // Admin Modus betreten
{
// I²C wird deaktiviert um Störung von aussen zu vermeiden
mode = ADMIN;
}
else if(BUTTON_RIGHT && BUTTON_LEFT && !BUTTON_SELECT) // SuAdmin Modus betreten/verlassen
{
if(mode == ADMIN)
{
mode = SUADMIN;
// Optionen werden angezeigt
}
else if(mode == SUADMIN)
{
mode = ADMIN;
}
}
else if(mode == SUADMIN && BUTTON_START) // SuAdmin: Auswahl
{
// Mit dem Cursor ausgewählte Optionen können hiermit bestätigt werden
}
else if(mode == ADMIN && BUTTON_START) // Selbsttest
{
// einige Registerinhalte werden ausgegeben
}
else if(mode != IDLE && BUTTON_LEFT && !BUTTON_RIGHT && !BUTTON_SELECT) // Display links
{
lcd_command(LCD_MOVE_DISP_RIGHT);
}
else if(mode != IDLE && BUTTON_RIGHT && !BUTTON_LEFT && !BUTTON_SELECT) // Display rechts
{
lcd_command(LCD_MOVE_DISP_LEFT);
}
else if(mode != IDLE && BUTTON_SELECT && BUTTON_LEFT && !BUTTON_RIGHT) // Cursor links
{
lcd_command(LCD_MOVE_CURSOR_LEFT);
}
else if(mode != IDLE && BUTTON_SELECT && BUTTON_RIGHT && !BUTTON_LEFT) // Cursor rechts
{
lcd_command(LCD_MOVE_CURSOR_RIGHT);
}
else if(mode == ADMIN && BUTTON_SELECT && BUTTON_LEFT && BUTTON_RIGHT) // Adminmodus verlassen
{
modus = IDLE;
}
// Entprellung & Zeitabstand, 150ms warten
warte_ds(15);
}
int main()
.... einige Zuweisungen und Initialisierungen ....
while(1)
{
switch(mode)
{
case IDLE:
ledSwitch(led_modus, led_color, led_aktion);
break;
case ADMIN:
ledSwitch(STANDBY, BLUEWHITE, 50);
break;
case SUADMIN:
ledSwitch(BLUE1, BLUE2, 40);
ledSwitch(STATIC, ALL, OFF);
ledSwitch(STATIC, DBLUE, ON);
warte_ds(40);
break;
}
Es passieren also Dinge, die an sich nicht passieren dürften weil es theoretisch geht, auch der AVR Simulator macht es so wie ich will.
Ist die INT Routine vielleicht zu voll?
Hoffe, jemand kann mir ne Antwort geben, Fehler finden oder Vorschläge machen,
Gruß,
Markus