logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Przełącznik INT.. Prośba o sprawdzenie funkcji [AVR][WinAVR]

AVRowiec 26 Mar 2010 19:58 1200 0
REKLAMA
  • #1 7883465
    AVRowiec
    Poziom 18  
    Witam, napisałem funkcje której zadaniem jest zmiana reakcji przerwań zewnętrzynch w atmega128.

    Funckje wywołuje się z parametrem NUMER_PRZERWANIA i STAN_PO_JAKIM_MA_NASTĄPIĆ_PRZERWANIE :)

    Podejrzewam że wszystko jest ok a ciężko to sprawdzić. Tak naprawde interesuje mnie tylko zaznaczona część - proszę powiedzcie czy jest ok.
       EICRA &= ~_BV((przerwanie+1)<<ISC01);
       EICRA &= ~_BV(przerwanie<<ISC00);  
    

    Czy te operacje na bitach są ok?

    #define LOWLEVEL 0
    #define CHANGE   1
    #define FALLING  2
    #define RISING   3
    void ExIntReact(char przerwanie, char stan)
    {
      // przed zmianą stanu należy wyłączyć przerwanie
      // w rejestrze EIMSK numer bitu odpowiada numerowi przerwania 
       EIMSK &= ~_BV(przerwanie);   
     
      // EICRA0:3 
      //             ISCn1  |   ISCn0
      //               0    |     0        low level generates an interrupt
      //               0    |     1        reserwed
      //               1    |     0        falling edge
      //		       1    |     1        rising edge
      // EICRB4:7 
      //             ISCn1  |   ISCn0
      //               0    |     0        low level generates an interrupt
      //               0    |     1        any logical change
      //               1    |     0        falling edge
      //		       1    |     1        rising edge
     
     if (przerwanie<4) // rejestr EICRA
     {
       przerwanie *= 2;// ponieważ są dwa bity do ustawienia i co tyle należy się przesówać
       switch (stan)
       {
          case LOWLEVEL:  EICRA &= ~_BV((przerwanie+1)<<ISC01);  // 0 -- TUTAJ
    					  EICRA &= ~_BV(przerwanie<<ISC00);  // 0  -- I TUTAJ
    					  break;
          case FALLING :  EICRA |=  _BV((przerwanie+1)<<ISC01);  // 1
    					  EICRA &= ~_BV(przerwanie<<ISC00);  // 0
    					  break;
          case RISING  :  EICRA |=  _BV((przerwanie+1)<<ISC01);  // 1
    					  EICRA |=  _BV(przerwanie<<ISC00);  // 1
    					  break;
       
       }
     } 
     else // rejestr EICRB
     {
    	switch (stan)
    	{
        przerwanie -= 4; // zmniejszcze numeru przerwania (np INT6 to bit 4 i 5 w EICRB)
    	przerwanie *= 2; // ponieważ są dwa bity do ustawienia i co tyle należy się przesówać
          case LOWLEVEL:  EICRA &= ~_BV((przerwanie+1)<<ISC01);  // 0
    					  EICRA &= ~_BV(przerwanie<<ISC00);  // 0
    					  break;
    	  case CHANGE  :  EICRA &= ~_BV((przerwanie+1)<<ISC01);  // 0
    					  EICRA |=  _BV(przerwanie<<ISC00);  // 1
    					  break; 
          case FALLING :  EICRA |=  _BV((przerwanie+1)<<ISC01);  // 1
    					  EICRA &= ~_BV(przerwanie<<ISC00);  // 0
    					  break;
          case RISING  :  EICRA |=  _BV((przerwanie+1)<<ISC01);  // 1
    					  EICRA |=  _BV(przerwanie<<ISC00);  // 1
    					  break;
    	}
     }
     
      // ponowne włączenie przerwania dla danego INT'a
       EIMSK |= _BV(przerwanie);   
       
       return ;
    }


    Jeśli oprócz tego są jakieś uwagi to chętnie posłucham.

    Dzięki.
  • REKLAMA
REKLAMA