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

ATmega128 PCF8583 Brak wyzwalania przerwania z PCF

17 Lut 2011 21:19 1907 16
  • Poziom 9  
    Witam forum.
    1. Sytuacja
    PCF8583 podłączony do ATMega128 za pomocą I2C, wyjście INT z PCF podłączone go wejścia PE4 (INT4) mikrokontrolera za pomocą 4k7 pull-up resistor, zwartego do zasilania. Zegar działa bez zarzutu gdy czas/data jest odczytywany za pomocą odpowiedniej procedury.
    2. Wyzwanie jest następujące:
    problem pojawia się w momencie gdy odczyt czasu/daty ma być wyzwalany z wnętrza procedury obsługi przerwania INT4. Wygląda na to, że sygnał generowany przez PCF nigdy nie opada do zera (nie mam oscyloskopu - więc nie mam pewności) co wyzwalałoby przerwanie. Próbowałem różne wejścia (INT7-INT4) z różnymi warunkami wyzwalania przerwania. Niestety bez skutku.

    Do INT 6 jest podpięta klawiatura - działa OK.

    Za ewentualne propozycje/sugestię będę wdzięczny.
    Pozdrawiam
    Michał
    Code:
     // inicjalizacja przerwan
    

     EIMSK = (1<<INT4)|(1<<INT6);

     EICRB = 0x02;  // INT4 trigger by falling edge, INT6 low level
     
    oraz

    SIGNAL(SIG_INTERRUPT4)
    {
       read_time = 1;        // Ustaw flage zegara
    }
    Darmowe szkolenie: Ethernet w przemyśle dziś i jutro. Zarejestruj się za darmo.
  • Poziom 29  
    Witam,

    Sprawdź przy pomocy miernika (voltomierza) czy masz sygnał 1Hz na linii INT.
    Napięcie powinno się zmieniać.

    Jaką wartość wpisujesz do "Status/Control Register" w PCF8583?

    Pozdrawiam
    JarekC
  • Moderator na urlopie...
    Usuń ten pull up na przerwaniu i załącz wewnętrzny w up,
    Podepnij pod pcf a diodę led z rezystorem i sprawdź czy miga przy stanie niskim
  • Poziom 9  
    Witam,

    Dzięki za sugestie.

    1. Do wyjścia INT w PCF został podpięty LED z rezystorem 1k zwarty do zasilania. Dioda pięknie pulsuje z częstotliwością 1Hz (na oko).

    2. Wewnętrze pull-up w uC były wcześniej załączone.

    Sygnał z PCF nadal nie wyzwala przerwania. Ciekawa obserwacja> jeżeli uC jest odłączony od wyjścia zegara, dioda świeci się znacznie mocniej? Czyli we wnętrzu uC musi odkładać się napięcie? Inne przerwania (Timer, TWI, keyboard) działają bez zarzutu. Czytam Datasheet-a ale bez sukcesu.

    Pozdrawiam,

    Michał
  • Moderator na urlopie...
    hmm, a sprawdź samo przerwanie przyciskiem i powiedz jakie zbocze je aktywuje, może jakiś błąd w programie?
  • Poziom 38  
    read_time jest oczywiście volatile?
  • Poziom 9  
    Klawisze są podpięte do zasilania poprzez rezystor 10k oraz do masy (klasyczne rozwiązanie). Procedura obsługi przerwania uruchamia się bez wzgledu na warunek tzn.> niski stan, opadające/wzrastające zbocze podczas naciśnięcia/zwolnienia klawisza. Gdy podepnę do tego samego pinu w uC wyjście INT z PCF , zamiast klawiszy, przerwanie się już nie uruchamia.

    Do obsługi przerwania wstawiłem komendę zapalania diody.

    Nie rozumiem> wyjście z PCF powinno mieć podobny przebieg, do tego generowanego w czasie przyciśnięcia/zwolnienia klawisza - przecież dioda gaśnie - wtedy kiedy na wyjściu INT zegara jest podawany stan niski??

    Coś tu nie halo??
  • Poziom 29  
    Pokaż jak inicjujesz porty.

    JarekC
  • Poziom 9  
    OK, ale sam program po wyrzuceniu wszystkich dodatków to nadal prawie 500 linii.
    Więc zamieściłem tylko część inicjującą. Czy coś przeoczyłem?
    Code:
    static volatile unsigned char key1=0, key2=0, key3=0, key4=0;
    

    static volatile unsigned char odczyt_keys=0;

    static volatile unsigned char odczyt_time=0;

    SIGNAL(SIG_INTERRUPT6)
    {
       if(!(PINB&0x01))     
       key1=1;

       if(!(PINB&0x02))       
       key2=1;

       if(!(PINB&0x04))        // Swirch SW2
       key3=1;

       if(!(PINB&0x08))        // Swirch SW3
       key4=1;

       odczyt_keys = 1;        // Ustaw flage
    }

    SIGNAL(SIG_INTERRUPT4)
    {
       Led1 = 0;

       odczyt_time = 1;        // Ustaw flage zegara
    }

    int main(void)
    {

      odczyt_keys = 0;
      odczyt_time = 0;

      DDRE  = 0xFF;  // tutaj sa wejscia do przerwan w M128
      PORTE = 0xFF;

      DDRD  = 0xFF;
      PORTD = 0xFF;

      // inicjalizacja switch & LED

      PORTB = 0xFF;                         // activate all internal pull-up
      DDRB  = 0xFF;                         // PORTB as output
      DDRB  &= 0xF0;

      // INT4 from PCF8583
      // INT6 from Keybord

      EIMSK = (1<<INT4)|(1<<INT6);

      EICRB = 0x02;  // INT4 trigger by falling edge

       Led0 = 0;

       init_lcd();
       
       comm_lcd(CLEAR_DISPLAY);
       comm_lcd(CURSOR_OFF);

       sei();

       for ( ; ; ) {                         // loop forever

        if (odczyt_time)
        {
       
          time_read_pcf8583();

          write_lcd(" ");

          date_read_pcf8583();
       
          odczyt_time = 0;       // zeruj flage
        }
             
        if(odczyt_keys)
        {
          if(key1 == 1)
          {
         
             odczyt_keys=0;
             key1=0;

          }
          if(key2 == 1)
          {
             odczyt_keys=0;
             key2=0;
          }
          if(key3 == 1)
          {
             key3=0;
             odczyt_keys=0;
          }
          if(key4 == 1)
          {   
             key4=0;
             odczyt_keys=0;
          }
       
        }

               
     }   
    }
  • Poziom 29  
    mjk10 napisał:
    DDRE = 0xFF; // tutaj sa wejscia do przerwan w M128

    Coś tu się nie zgadza.
  • Poziom 29  
    Witam,

    Linie które maja być wykorzystywane jako inicjujące przerwania muszą być ustawione jako wejścia a Ty masz ustawione jako wyjście w stanie "1".

    Teraz gdy PCF próbuje ściągnąć linię do "0" udaje mu się to tylko częściowo, gdyż nie ma odpowiedniej wydajności prądowej. Tak sytuacja to próba "zwarcia" dwóch
    sygnałów "0" i "1".

    Klawisze działają bo naciśnięcie powoduje fizyczne zwarcie do masy.

    Zmień odpowiednie porty na wejścia i będzie działać.

    Pozdrawiam
    JarekC
  • Poziom 9  
    Oczywiście działa. Dzięki za pomoc.

    Tą zasadę znam (albo mi się tak wydaję) ze sterowania klawiszami podpiętymi do portu uC. Nie jestem w sensowny sposób wytłumaczyć dlaczego byłem pewny, że w momencie inicjalizacji zewnętrznych przerwań charakterystyka danego wejścia się zmienia na wejściowe??
  • Poziom 9  
    Witam,

    Na pewno zapamiętam tą lekcję.

    BTW. System co 1Hz próbkuje temperaturę z 1621, przy pomocy PCF, ale czasami nie odczytuje prawidłowej temperatury, zamiast np 21 odczytuje 5.5? Czy pomiędzy komendami wchodzącymi w skład procedury odczytu temperatury (temp, slope, count) powinny być umieszczone szczeliny czasowe (np. ok 5ms)?
  • Moderator na urlopie...
    a jaki czas przetwarzania pomiaru ma wymieniony czujnik?
    bo np. w przpadku ds18b20 trzeba czekać 750 ms,
  • Poziom 9  
    Witam,

    Do uC jest podłączony DS1820 oraz DS1621. Czas konwersji czujnika (DS1620) to poniżej 350Ms (na oko). W obu przypadkach sprawdzany jest faktyczny a nie ustawiony na sztywno czas czas konwersji (np. 750ms w przypadku DS1820). Temperatura jest próbkowana co 1 sek. W większości przypadków starcza. Jednkże, czasami wynik jest przekłamany z DS1621. Dlatego, program został zmodyfikowany tak aby co sekundę był sprawdzany tylko jeden czujnik tzn. na przemian. To podejście jednak nie wyeliminowału problemu - wynik z DS1621 jest sporadycznie przekłamywany?

    Pozdrowiam,

    Michał