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

[C][vin-avr]problem z define

Marcin_xx1 29 Cze 2009 14:28 1426 14
  • #1 6717779
    Marcin_xx1
    Poziom 21  
    Nie wiem jak zapisać #define by przyporządkować zmiennej trzy pierwsze bity danego portu z pominięciem pozostałych przy operacji na zmiennej,
    potrzebuję trzech bitów jako wyjścia i trzech jako wejścia z podciąganiem
    na tym samym porcie, nie zależnie od liczby jaka wpisze do portu.

    #define ABC PORTD =0b00000111 ?

    DDRD=0b00000111;// wyjścia ABC
    PORTD=0b11100000;//wejścia z podciąganiem



    na przykład:
    ABC = 0X01;...
  • #2 6717829
    _Robak_
    Poziom 33  
    Nie wiem dokladnie o co ci chodzi ale, definem definijujesz makro, czyli zamiast twojego ABC kompilator wkleja kod wczesniej zdefiniowany. A jesli chcesz za pomoca jednej komendy ustawiac wejscia/wyjscia i podciaganie to zrob funkcje.
  • #3 6717885
    Marcin_xx1
    Poziom 21  
    Chodzi mi po prostu oto by przyporządkować do zmiennej ABC operacje tylko na trzech portu D ustawionych jako wyjścia, trzy inne bity tego portu maja być wejściami z podciąganiem, aktualnie gdy ustawie porty tak:


    DDRD=0b00000111;// wyjścia
    PORTD=0b11100000;//wejścia z podciąganiem

    Gdy na przykład w programie PORTD = 0b10101010
    to podciąganie się wyłącza. Nie wiem jak to zrobić
    by operować tylko na tych bitach które są ustawione jako wyjścia.
  • Pomocny post
    #4 6717921
    _Robak_
    Poziom 33  
    No to uzywasz makra _BV np tak,
    
    PORTD|=_BV(PD5) - pin 5 ma stan wysoki, reszta bez zmian
    PORTD&=~_BV(PD5) - pin 5 ma stan niski reszta bez zmian.
    

    Jesli wczesniej ustawiles jako wejscia to oczywiscie ustawisz pull upy.
  • #5 6718189
    Marcin_xx1
    Poziom 21  
    Dzięki. popróbuje z makrami.
  • Pomocny post
    #6 6718957
    Brutus_gsm
    Poziom 25  
    W WinAVR możesz też robić operacje logiczne na bitach. ;)

    Jeśli chcesz ustawić bit, to musisz do niego dodać 1. Jeśli chcesz bit wyzerować, to musisz go pomnożyć przez 0, czyli np.

    PORTD |= (1<<2) // pin 2 w stanie wysokim
    PORTD &=~(1<<3) // pin 3 w stanie niskim


    Jak czegoś nie rozumiesz to pytaj. ;)

    Edit:

    Nie zauważyłem, że kolega _Robak_ podał podobny przykład, lecz z użyciem makr. Właściwie jest to ten sam kod ;)
  • #7 6719147
    Marcin_xx1
    Poziom 21  
    Dzięki, już sobie z tym poradziłem, mam za to problem z timerami w atmedze 168. Mogę włączyć tylko jeden timer, gdy ustawiam drugi
    TIMSK to żaden nie wykonuje przerwania .Pewnie coś przeoczyłem w datasheet , z tego co wiem imer 0 i 2 sa od siebie nie zależne i mają oddzielne preskalery.
    
    ISR(TIMER0_OVF_vect)
    {
    
    }
    ISR(TIMER2_OVF_vect)
    {
    
    }
    
    int main(void)
    {
       //timer 0
        TCCR0B=0X02;//clk / 8
        TIMSK0=0X01;// overflow interrupt enable
       //timer2
        TCCR2B=0X02;//clk / 8
        TIMSK2=0X01;// overflow interrupt enable
    }
  • #8 6719172
    _Robak_
    Poziom 33  
    ISR(TIMER0_OVF_vect) 
    { 
    
    } 
    ISR(TIMER2_OVF_vect) 
    { 
    
    } 
    
    int main(void) 
    { 
       //timer 0 
        TCCR0B|=0X02;//clk / 8 
        TIMSK0|=0X01;// overflow interrupt enable 
       //timer2 
        TCCR2B|=0X02;//clk / 8 
        TIMSK2|=0X01;// overflow interrupt enable 
      sei();
    
    
    }

    Daj tak ;)
  • #9 6719220
    Marcin_xx1
    Poziom 21  
    mam sei(); ;(, tylko zapomniałem go dodać w przykładzie.


    
    ISR(TIMER0_OVF_vect)
    {
    TCNT0=64;
    }
    ISR(TIMER2_OVF_vect)
    {
    
    }
    
    int main(void)
    {
       //timer 0
        TCCR0B=0X02;//clk / 8
        TIMSK0=0X01;// overflow interrupt enable
       //timer2
        TCCR2B=0X02;//clk / 8
        TIMSK2=0X01;// overflow interrupt enable
    
    sei();
     	
    	while(1)
    	{
    
    	}
    }
    
  • #10 6719539
    _Robak_
    Poziom 33  
    Tak patrze i widze ze masz dwa rejestry timsk, jak to ci sie kompiluje ;) Rejestr timsk jest wspolny dla wszystkich licznikow. Poczytaj w datasheecie.
  • Pomocny post
    #11 6719576
    Brutus_gsm
    Poziom 25  
    Nie rób pustych przerwań. Wstaw w nie coś i spróbuj. ;)

    I zmień kod na to:
    // timer 0
    TCCR0B = 1<<CS01;   // clk/8
    TIMSK0 = 1<<TOIE0;  // overflow interrupt enable
    
    // timer2
    ASSR &= ~(1<<AS2);  // timer 2 clock source
    TCCR2B = 1<<CS21;   //clk / 8
    TIMSK2 = 1<<TOIE2;  // overflow interrupt enable
  • #12 6719636
    Marcin_xx1
    Poziom 21  
    Nie znajdę tego info że wszystkie liczniki mają wspólny rejestr, tego jest za dużo.
    Czyli używając przerwań z przepełnienia timera0
    nie mogę używać timera 2?.
  • #13 6719690
    snow
    Poziom 31  
    Możesz. Generalnie w procesorze jest priorytet przerwań więc może się zdarzyć że coś ci zginie jeżeli przerwanie o wyższym priorytecie nadejdzie w tym samym czasie co drugie. Opis rejestru TIMSK jest w PDF'ie przy każdym liczniku zatem łatwo znaleść o nim informacje.
  • Pomocny post
    #14 6719699
    Brutus_gsm
    Poziom 25  
    Możesz, te dwa timery nie mogą się gryźć. Spróbuj zrobić tak, jak napisałem jeden post nad tobą. ;) I wstaw coś w obsługę przerwać, cokolwiek, byle zajęło parę cykli zegara ;)

    Dodano po 1 [minuty]:

    Przeglądałem datacheet i w tym procesorze są dwa przynajmniej dwa rejestry ;) TIMSK0 i TIMSK2 ;) Wg datacheet'u ATMEL'a ;)

    Dodano po 3 [minuty]:

    I spróbuj jeszcze zamiast ISR użyć SIGNAL, np

    SIGNAL(TIMER0_OVF_vect)
    {
    TCNT0=64;
    }
  • #15 6719773
    Marcin_xx1
    Poziom 21  
    WIELKIE DZIĘKI BRUTUS_GSM.
    Uzupełnienie przerwania pomogło na ISR JEST ok.
REKLAMA