-         

Ergebnis 1 bis 10 von 10

Thema: Pin-Change ATtiny45

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

    Pin-Change ATtiny45

    Anzeige

    Hallo alle, ich habe ein Problem mit meinem ATtiny45.
    Ich möchte gerne zu Testzwecken, dass er, sobald Pin PB1 den Zustand ändert, PB0 auf low (0) setzt.
    kann sich mal jemand den code ansehen?

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #ifndef F_CPU
    #define F_CPU 8000000
    #endif
    #include <stdint.h>
    #include <util/delay.h>
    #include <inttypes.h>

    int main(void)
    {
    SREG |=(1<<7);
    GIMSK |=(1<<5);
    PCMSK |= (1<<1);


    DDRB = 0x00;
    PORTB = 0xFF;


    }


    ISR(PCINT1_vect)
    {

    DDRB = 0x01;
    PORTB = 0xFE;
    }

    danke im Voraus, marco
    Nur tote Fische schwimmen immer mit dem Strom!

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Warum nicht so?
    ...
    sei();
    GIMSK |=(1<<PCIE);
    PCMSK |= (1<<PCINT1);
    ...

    Und wo liegt jetzt das Problem? Passiert nicht? Oder geht PB0 sofort auf low? Das könnte daran liegen, dass durch das PORTB=0xFF in der Main sich der Pegel an PB1 schon ändert. Dann wird sofort der Interrupt ausgelöst.
    Lösung: erst PORTB auf high, dann erst Interrupt konfigurieren und freigeben.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    also, ich habe den code geändert, auf:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #ifndef F_CPU
    #define F_CPU 8000000
    #endif
    #include <stdint.h>
    #include <util/delay.h>
    #include <inttypes.h>

    int main(void)
    {
    DDRB = 0x00;
    PORTB = 0xFF;
    sei();
    GIMSK |= (1<<PCIE);
    PCMSK |= (1<<PCINT1);
    }

    ISR(PCINT1_vect)
    {
    DDRB = 0x01;
    PORTB = 0xFE;
    }

    das Problem ist, das ich den Schalter drücken kann, wie ich will und die LED bleibt dunkel. Sie sollte allerding leuchten, wenn PB0 =0 ist.
    Hardware dürfte OK sein, ich habe es vorher mit einer schleife probiert und dort hat es funktioniert
    Nur tote Fische schwimmen immer mit dem Strom!

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Gibt es bei
    ISR(PCINT1_vect)
    keine Warning?
    So einen Interruptvektor gibt es beim T45 nämlich nicht!
    Daher wird die Interruptroutine nicht in der Interrupttabelle eingetragen (sieht man im .lss-File), und beim Auslösen der Interrupts erfolgt ein Reset.
    PCINT0_vect wäre richtig.


    Das ist ne etwas gewöhnungsbedürftige Sache: es gibt für alle Pins nur einen gemeinsamen Interruptvektor! Bei größeren AVRs teilen sich immer acht Pins einen Interrupt, darum werden die Interrupts von PCINT0 an durchnummeriert. Die 0 hätte Atmel beim T45 auch weglassen können, aber so ist es konsistenter.
    PCINT0_vect bedeutet also NICHT, dass es der Interruptvektor für den Pin PCINT0 ist, sondern dass es der erste (= nullte in Informatiker-Zählweise) der Pinchange-Interrupts ist, die jeweils acht Pins umfassen.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    danke vielmals!! Ich glaube ich verstehe jetzt. Aber gibt es denn eine möglichkeit, dass "pcint0_vect" nur auf bestimmte ports reagiert? Sonst müsste ich ja in der interrupt-routine jeden port abfragen?!
    Nur tote Fische schwimmen immer mit dem Strom!

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Welche Pins den Interrupt auslösen, stellst du in PCMSK ein. Aber du hast es schon richtig verstanden: wenn mehrere Pins aktiv sind, musst du in der ISR erst mal abfragen, welchen Pin denn nun wirklich seinen Pegel geändert hat.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    na also, jetzt läufts ja. Danke vielmals.
    und soo schlimm ist das mit dem abfragen ja auch wieder nicht...
    Nur tote Fische schwimmen immer mit dem Strom!

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    also eine frage habe ich doch noch:
    ich habe es jetzt in meinem programm anders gelöst, aber ist es PRINZIPIELL NICHT möglich, dass man ein I/O-register in einer interrupt-routine ändert? also so funktioniert es bei mir nicht:

    ISR(PCINT0_vect)
    {
    DDRB = 0x01;
    PORTB = 0xFE;
    }

    wenn ich es mit einer abfrage im hauptprogramm mache (variablen-abfrage), dann geht es.
    wo ist also das problem?
    mfg
    Nur tote Fische schwimmen immer mit dem Strom!

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    könnte es sein, dass, wenn ich sei(); vor PCMSK ausführe, andere Interrupts "dazwischenkommen"? oder GIMSK vor PCMSK?
    dann gäbe es einen interrupt ohne ISR was ja bekanntlich zum Reset führt...
    was glaubt ihr?
    Nur tote Fische schwimmen immer mit dem Strom!

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    14.09.2007
    Ort
    Na Zuhause!
    Alter
    24
    Beiträge
    99
    achja, für alle, die es interessiert oder das gleiche problem haben, ich habs.
    also, ich "sei();" und "GIMSK" vor "PCMSK" getippt. das hat dazu geführt, dass einen kurzen augenblick wohl alle interrupts aktiv waren. und offenbar wurde genau zwischen diesen drei befehlen ein interrupt ausgelöst. und wie man weiss, löst jeder interrupt, der keine ISR (interruptroutine) hat, einen reset aus. tataaa, bug a la carte.
    aber danke trotzdem für die hilfe!
    mfg
    Nur tote Fische schwimmen immer mit dem Strom!

Berechtigungen

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