-         

Ergebnis 1 bis 10 von 10

Thema: Attiny2313 INTF1 nicht gesetzt

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99

    Attiny2313 INTF1 nicht gesetzt

    Anzeige

    Hallo zusammen

    Ich habe ein Problem mit meinem "Programm".
    Wenn ich an meinem Attiny2313 den INT1 triggere, wird
    das INTF1-flag nicht gesetzt, obwohl die Interrupt-routine ausgeführt wird.
    Sie wird sogar etwa 3mal hintereinander ausgeführt, das Ganze is ziemlich dubios und unvorhersehbar. Könntet ihr mal meinen Code anschauen? Bin noch Anfänger und auch für andere Verbesserungsvorschläge offen. Wenn es hilft, könnte ich auch noch ein Schaltplan liefern, da die Taster ungewöhnlich verdrahtet wurden, um Eingänge zu sparen.

    <code>

    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include "lcd.h"
    #include <avr/interrupt.h>
    #include <inttypes.h>
    #include <stdint.h>
    #include <util/delay.h>

    #ifndef F_CPU
    #define F_CPU 10700000UL //clock = 10,7Mhz (external)
    #endif

    volatile uint8_t button_state = 0; //button status
    volatile uint8_t button_pressed = 0; //set if button pressed


    int main()
    {

    DDRD = 0x33; //a,b,c & beeper = out
    PORTD = 0x17; //a,b,c = 1, beeper = 0

    lcd_init(LCD_DISP_ON); //initialize display
    lcd_clrscr(); //clear display and cursor home
    DDRB |= (1<<PB7); //LED-light = output
    PORTB |= (1<<PB7); //LED-light on
    lcd_puts_P("XX XX.XX.XXXX XX:XX\n"); //send string to display (ROM)
    lcd_puts_P("Next Alarm:"); //send string to display (ROM)

    MCUCR = 0x0E; //INT0 = falling, INT1 = rising, sleep mode = idle
    GIMSK = 0xC0; //INT1 & INT0 = enabled, PCIE = disabled
    sei(); //set global interrup enable flag


    while(1 == 1) //forever
    {

    if(button_pressed == 1) //any button pressed (read flag)
    {

    if(button_state == 1) //button value == 1
    {
    lcd_clrscr(); //clear display and cursor home
    lcd_puts_P("<-"); //send string to display (ROM)
    }

    else if(button_state == 2)
    {
    lcd_clrscr();
    lcd_puts_P("->");
    }

    else if(button_state == 3)
    {
    lcd_clrscr();
    lcd_puts_P("+");
    }

    else if(button_state == 16)
    {
    lcd_clrscr();
    lcd_puts_P("-");
    }

    else if(button_state == 17)
    {
    lcd_clrscr();
    lcd_puts_P("MENU");
    }

    else if(button_state == 18)
    {
    lcd_clrscr();
    lcd_puts_P("should not be seen");
    }

    button_pressed = 0; //reset flag

    }


    }

    }


    ISR(INT1_vect)
    {
    DDRD &=~ (1<<PD0) | (1<<PD1) | (1<<PD4); //set a,b,c to input
    DDRD |= (1<<PD3); //set INT1 to output
    button_state =~ (PIND | 0xEC); //button != abc
    button_pressed =1; //set button_pressed-flag
    DDRD |= (1<<PD0) | (1<<PD1) | (1<<PD4); //set a,b,c to output
    DDRD &=~ (1<<PD3); //set INT1 to input
    }

    </code>

    Vielen Dank!

    Marco
    Nur tote Fische schwimmen immer mit dem Strom!

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Hallo Marco,

    Punkt 1: Ich sehe nicht, wo du auf das Flag INTF1 zugreifst.
    Punkt 2: Wenn du einen Taster angeschlossen hast, ist der Versuch, den Taster mit Interrupts auszuwerten von vornherein zum Scheitern verurteilt. Taster "prellen" beim Betätigen, es gibt kein sauberes Signal sondern abhängig vom Taster sowohl in der Menge als auch in der Stärke unterschiedlich ausgeprägte Störungen.
    Du solltest dich diesbezüglich Mal über das Thema "Debouncing" Informieren.

    mfG
    Markus

    Edit: Bezüglich einer "ungewöhnlichen" Tasterverdrahtung - hast du mehr gemacht als die normale "ein-Pin-je-Taster"-Lösung? Matrixverschaltungen o.ä.? Das sollte aber eigentlich nicht direkt am Fehler beteiligt sein.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Hallo Markus

    Ich greife auch nicht im code auf das flag zu. Im Datenblatt steht, es sollte vor dem Sprung in den betreffenden Interruptvektor gesetzt werden. Beim debuggen habe ich jedoch gesehen, dass es nicht gesetzt wurde.
    Könnte es sein, dass der Interrupt deshalb mehrmals abgearbeitet wird, weil mehrere Impulse vom Taster kommen? Wäre mir neu, dass der AVR Interrupts "speichert". Aber auch das würde immer noch nicht erkären, wieso das INTF1-flag nicht gesetzt wird.
    Ja, ich habe eine kleine Eigenkreation angehängt. Dies sollte jedoch kein Problem sein, die Tastendrücke wurden alle erkannt.
    Die Funktion dieser Schaltung ist wie folgt: zuerst sind A, B und C auf 1. Ein Tastendruck bewirkt nun einen Interrupt an INT1. In der Interrupt-routine wird nun INT1 auf Ausgang und 0 geschaltet und A, B und C als Eingänge mit Pull-ups. Der code der gedrückten Tasten liegt nun in negativer Logik an A, B und C an. Es müssen nur noch die anderen Ports von PORTD mit einer Maske ausgefiltert werden und schon hat man einen schönen Wert.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken taster_125.jpg  
    Nur tote Fische schwimmen immer mit dem Strom!

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von X-917
    Im Datenblatt steht, es sollte vor dem Sprung in den betreffenden Interruptvektor gesetzt werden
    Dann ist das eine Fehlinterpretation des Datenblatts deinerseits. Es wird gesetzt bei dem entsprechenden Event (also z.B. Flanke an dem Pin). Beim Sprung zur ISR wird es dann wieder gelöscht.

    Zitat Zitat von X-917
    Beim debuggen habe ich jedoch gesehen, dass es nicht gesetzt wurde.
    Wenn zum Zeitpunkt des Events gerade keine ISR ausgeführt wird (oder Interrupts anderweitig gesperrt sind), ist der Zeitraum, in dem das Flag gesetzt ist, auch extrem kurz. Du musst schon auf ASM-Level im Einzelschritt debuggen, um das gesetzte Flag zu Gesicht zu bekommen (wenn überhaupt).

    Zitat Zitat von X-917
    Wäre mir neu, dass der AVR Interrupts "speichert".
    Ist aber so. Während die ISR bearbeitet wird, kann ein weiterer Event das Flag wieder setzen, so dass also ein Interrupt (pro Quelle) "gespeichert" wird.
    MfG
    Stefan

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Hallo Stefan

    Ah, ok. Ich dachte das flag wird gelöscht, wenn die ISR verlassen wird.

    Dann würde ich es also auch nicht sehen wenn ich ein JTAGICE mkII und die Funktion "step-into-next-statement" benutzen würde?

    Ja klar kann das flag wieder gesetzt werden, aber es kann nicht sein, dass meine ISR 3mal oder mehr abgearbeitet wird, nur weil ein taster prellt. der AVR speichert eben maximal einen weiteren Interrupt derselben Quelle.
    Klar kann es sein, dass durch das prellen der Interrupt immer wieder getriggert wird, doch ich denke nicht, dass das beim debuggen vorkommen würde. Die Ausführzeiten der ISR liegen dort ja weit über der Prellzeit der Taster.

    MfG
    Nur tote Fische schwimmen immer mit dem Strom!

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wenn man ohne Debugger arbeitet, wird die Zeit zum Ausführen der ISR kürzer sein als die typische Prelzeit (ca. 1 ms), außer bei 32 kHz Takt. Vo daher kann die ISR Schon mehrfach ausgeführt werden.

    Das Interrupt Flag wird schon beim Aufrufen der ISR gelöscht, nicht erst am Ende. Man sieht als in der ISR das Flag nicht mehr, da hift es auch nicht auf ASM Ebene zu debuggen. Nur wenn man ein sehr schnelles Prellen hat, könnte das Flag schon wieder ein 2tes mal gesetzt werden.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Hmm, aber die ISR wird WÄHREND DEM DEBUGGEN 3 mal ausgeführt...
    Sie sollte aber, falls die Taster prellen, maximal 2 mal ausgeführt werden.
    (1mal druck + 1 mal flag während der Abarbeitung der ISR durch prellen)
    Nur tote Fische schwimmen immer mit dem Strom!

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Achja, am Ende werde ich tatsächlich mit 32khz Takt arbeiten. Habe jedoch im Moment einen 10.7Mhz Quarz in Gebrauch, da der 32khz für debugwire zu langsam ist. Ich werde das Programm noch mit dem 32khz Quarz testen und dann berichten, ob das Problem immer noch vorhanden ist.
    Nur tote Fische schwimmen immer mit dem Strom!

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Ich kapiers nicht...

    Es scheint, als würde der Interrupt getriggert, SOLANGE der Schalter gedrückt wird. Dabei habe ich doch auf "rising edge" konfiguriert...
    Kann mir das mal jemand erklären? Unter Errata habe ich nichts gefunden was auf einen Designfehler des Controllers hindeutet, ich verzweifle langsam.

    Ausserdem wird mein button_state bei folgender Zeile auf 0 gesetzt!!

    if(button_pressed == 1) //any button pressed (read flag)

    Weiss den niemand, was ich falsch mache?
    Nur tote Fische schwimmen immer mit dem Strom!

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    23
    Beiträge
    99
    Aaah!
    Ich habe den Fehler gefunden. Hoch lebe das debuggen!
    Wenn man sich die Zustände des INT1-Pin ansieht, fällt einem vielleicht etwas auf... Wenn ich nämlich den INT-pin auf 0 ziehe, um die Taster auszulesen, wird danach ein Interrupt ausgelöst, wenn ich ihn wieder auf Eingang schalte, da er dann wieder vom gedrückten Taster auf 1 gezogen wird. So entsteht bei jedem Interrupt ein neuer.
    Nur tote Fische schwimmen immer mit dem Strom!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •