Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[atmega8] [C] - Ustawianie bitów na porcie D a niechciane przerwania.

pbuhne 24 Lis 2012 19:27 1056 4
  • #1 24 Lis 2012 19:27
    pbuhne
    Poziom 14  

    Witam, jakiś czas temu zacząłem zabawę z AVR no i w końcu natrafiłem na problem, którego nie mogę rozgryźć.

    Mam w programie (multipleksowany wyswietlacz 7 seg) linijkę o treści :

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod ten ma ustawić 0 na PD0, PD1, PD4, PD5 oraz PC3 i PC2 ; a 1 na PD6. Zapis ten teoretycznie nie powinien ruszać PD2 i PD3.
    I teraz, na PD2 i PD3 mam przerwania (stanem) , powyższy zapis nie powinien ich ruszyć, ale jednak wywołuje przerwania :/ Wiem że, nie można ustawiać pojedynczych bitów, dlatego używa się &= , |= oraz masek.

    Gdy użyję:
    Kod: c
    Zaloguj się, aby zobaczyć kod
    wszystko jest ok, ale ustawiam tu za kazdym razem konkretnie cały bajt PORTD oraz cały bajt PORTC, a tego nie koniecznie chcę...

    Żeby nie gmatwać, chodzi mi DOKŁADNIE o ten zapis, wiem ze lepiej uzyć całego portu a nie mieszać jak powyżej D i C, ale nie rozumiem DLACZEGO zapis, który nie powinien ruszać bitów PD2 i PD3 generuje przerwanie.

    Pozdrawiam, Piotrek.

    PS. Program tworzę w Eclipse w C.

    0 4
  • Pomocny post
    #2 24 Lis 2012 19:49
    dgajew
    Poziom 18  

    W drugim przykładzie ustawiasz jednocześnie PD6 i PD7, w pierwszym przykładzie tylko PD6, być może masz włączone przerwanie od komparatora AIN0/AIN1, wklej cały schemat, być może stan linii PD6 i PD7 wpływa na wejścia PD2 i PD3.

    0
  • #3 24 Lis 2012 21:06
    pbuhne
    Poziom 14  

    Wkleję cały program:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    W pierwszym zapisie
    Kod: c
    Zaloguj się, aby zobaczyć kod

    samo usunięcie & czyli "PORTD = 0x33" naprawiło problem, więc gdzieś tu tkwi szkopuł.

    Bo jeśli dobrze rozumuję , to:

    bajt XX10 XX11
    & ~0x33 1100 1100 ( czyli ~(0011 0011))
    bajt XX00 XX00

    PD7 jest niepodłączone. PD6 to wyjście na tranzystor (przez rezystor). Nie mam schematu, ale układ elektrycznie działa ok.
    PD2 i PD3 to switch'e zwierające do masy.


    Drugi zapis
    Kod: c
    Zaloguj się, aby zobaczyć kod

    daje: PORTD = 1100 1100

    A pierwszy
    Kod: c
    Zaloguj się, aby zobaczyć kod

    daje: PORTD = X100 XX00 racja?


    Dodano po 27 [minuty]:



    Znalazłem błąd.



    Cały czas miałem w głowie, że przerwanie wywoływane jest stanem wysokim. Natomiast prawda jest nieco inna ;) Przerwanie wywoływane jest 0.

    i teraz:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    daje: PORTD = 1100 1100 czy stan wysoki - nie ma przerwania.

    A
    Kod: c
    Zaloguj się, aby zobaczyć kod

    daje PORTD = X100 XX00 no i co? Jaką wartość ma domyślnie PD2 i PD3 ? 0 !
    Wiec wychodzi: X100 0000 czyli przerwanie.

    Logiczne.

    Pozdro :)

    0
  • Pomocny post
    #4 24 Lis 2012 21:53
    dgajew
    Poziom 18  

    Domyślny stan 0 pomnożony przez 1 nadal daje 0. Wydaje mi się że to nie pierwszy kod był błędny, tylko drugi "prawidłowy" uruchamiał rezystory pullup dla wejść PD2 i PD3 i dlatego przerwania przestały się wywoływać. W całym kodzie brakowało po prostu linii w której wpisujesz 1 do PD2 i PD3, przed włączeniem przerwań.

    0
  • #5 24 Lis 2012 22:20
    pbuhne
    Poziom 14  

    Dokładnie jak kolega pisze, ustawienie przez drugi kod 1 na PD2 i PD3 uruchamiało pull-up (o tym nie pomyślałem) czyli była tam logiczna jedynka (kod nadpisał cały bajt), natomiast pierwszy przepisywał domyślne 0 (skopiował bajt, ustawił zera i jedynki gdzie mu kazano i zapisał, z niezmienionymi PD2, PD3 i PD7) skutkiem tego nie uruchamiał pull-up'u.

    Dzieki serdeczne za pomoc :)

    Pozdrawiam, Piotrek.


    PS. Tak, dodałem też linię ustawiającą 1 na PD2 i PD3 przed włączeniem przerwań.

    0