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łączanie źródeł napięcia atmega8515L

bilbo1 16 Mar 2011 09:35 1724 15
REKLAMA
  • #1 9282639
    bilbo1
    Poziom 10  
    Witam. Już od kilku godzin siedzę nad prostym programem i nie mogę zrozumieć w czym problem. W programie chodzi o to, że na pin 1 portu B podawany jest stan wysoki kiedy na pinie 6 portu A (przetwornica) jest stan wysoki. Jeśli na tym pinie jest stan niski a na pinie 7 ( agregat) stan wysoki to pin 0 portu B ustawiany jest w stan wysoki. Jeśli obydwa są w stanie niskim na wyjściach nie ma nic. Podłączenie źródła zewnętrznego na pin 5 portu A (połączonego z INT0) ustawia przerwaniem pin 2 portu B.

    
     #include <avr/io.h> 
    #include <util/delay.h>  
    #include <avr/interrupt.h>   
    
    ISR (INT0_vect)
    {
    PORTB |= _BV(2);
    PORTB &=~(_BV(1));	//wylacza inne zrodla
    PORTB &=~(_BV(3));
    _delay_ms(1);
    while (PINA & 0b00100000){};
    }
    
    
    int main(void) 
    { 
    //wyjscia
    _delay_ms(1);
    DDRB |= _BV(3);
    DDRB |= _BV(1);  
    DDRB |= _BV(2);
    PORTB = 0b00000000;
    
    //wejscia
    DDRA &=~(_BV(5)); 	//zewnetrzne	
    DDRA &=~(_BV(6));	//przetwornica
    DDRA &=~(_BV(7));	//agregat
    DDRD &=~(_BV(2)); 	//INT0
    
    // konfiguracja przerwania int0
    
    GICR |= _BV(INT0);
    MCUCR |= _BV(ISC00);
    MCUCR |= _BV(ISC01);
    sei();
    while (1)
    {
    
    
    if (PINA & 0b01000000)
    {
    PORTB |= _BV(1);
    PORTB &=~(_BV(0));	//wlacza przetwornice i wylacza inne
    PORTB &=~(_BV(2));
    _delay_ms(100);
    
    }
    while (PINA & 0b01000000){};
    	
    	
    if(PINA & 0b10000000)
    {
    PORTB |= _BV(0);
    PORTB &=~(_BV(1));	//wlacza agregat i wylacza inne
    PORTB &=~(_BV(2));
    _delay_ms(100);
    }while (PINA & 0b10000000){};
    
    
    }
    }
    

    Program prosty, w avr studio przy symulacji działa jak należy. Po zaprogramowaniu atmegi 8515L i podłączeniu diod LED do wyjść zaczynają się problemy. Diody mimo, że nie powinny świecić się wcale kiedy na wejściach nie ma nic- migają w różnym tempie. Zgłaszając przerwanie zapala się nie ta dioda co powinna. Dodam tylko, że po wyjęciu procesora z podstawki i podłączeniu wszystkiego "na krótko" problem nie znika, więc to nie jest wina, źle zlutowanych ścieżek.

    Proszę o umieszczenie kodu w znacznikach code.
    Robak
  • REKLAMA
  • #2 9283180
    rmk
    Poziom 12  
    Według tego co napisałeś sterujesz pinami 0,1,2 na porcie B ale w przerwaniu i konfiguracji wyjść ustawiasz piny 1,2,3 portu B
  • #3 9283430
    bilbo1
    Poziom 10  
    Pomyłka w opisie:D Steruje bitami 1,2,3 portu B. Nie zmienia to faktu, że diody dalej żyją własnym życiem
  • Pomocny post
    #4 9283478
    rmk
    Poziom 12  
    Jeżeli sterujesz pinami 1,2,3 to czemu w listingu masz 0,1,2?
    if (PINA & 0b01000000) 
    { 
    PORTB |= _BV(1); 
    PORTB &=~(_BV(0)); //wlacza przetwornice i wylacza inne 
    PORTB &=~(_BV(2)); 
    _delay_ms(100); 
    } 
    if(PINA & 0b10000000) 
    { 
    PORTB |= _BV(0); 
    PORTB &=~(_BV(1)); //wlacza agregat i wylacza inne 
    PORTB &=~(_BV(2)); 
    _delay_ms(100); 
    }

    Nie powinno być:
    if (PINA & 0b01000000) 
    { 
    PORTB |= _BV(2); 
    PORTB &=~(_BV(1)); //wlacza przetwornice i wylacza inne 
    PORTB &=~(_BV(3)); 
    _delay_ms(100); 
    } 
    if(PINA & 0b10000000) 
    { 
    PORTB |= _BV(3); 
    PORTB &=~(_BV(1)); //wlacza agregat i wylacza inne 
    PORTB &=~(_BV(2)); 
    _delay_ms(100); 
    }
    ?

    To by wyjaśniało dlaczego po zgłoszeniu przerwania pali się inna dioda
  • REKLAMA
  • #5 9283510
    bilbo1
    Poziom 10  
    Faktycznie taka bzdura:D Przerwanie działa jak należy i nawet kiedy poda się stan wysoki zapala się odpowiednia dioda. Jednak kiedy nie ma nic na wejściach diody 2 i 3 świecą się na przemian
  • #6 9283632
    rmk
    Poziom 12  
    Spróbuj przy if dać takie coś:
    if ( ( PINA & 0b01000000 ) != 0 )
    {
    }
    i analogicznie w drugim. I możesz też spróbować taki warunek w while dać.
  • #7 9283669
    bilbo1
    Poziom 10  
    No niestety diody dalej migają na przemian:/
  • REKLAMA
  • #8 9283686
    rmk
    Poziom 12  
    A w while też dałeś taki warunek? Masz coś podłączone do tych wejść PA5,6,7?
  • #9 9283718
    bilbo1
    Poziom 10  
    dałem warunek w while. Do wejść nie mam nic podłączone. Ustawiam je dotykając końcówką z zasilacza
  • #10 9283742
    rmk
    Poziom 12  
    Spróbuj while zmienić na
    while(!(PINA & 0b01000000)) {}
    A w przypadku przerwania jest ono tak długo aktywne, jak długo trzymasz na wejściu INT (i pa5) stan wysoki?
  • REKLAMA
  • #11 9283857
    bilbo1
    Poziom 10  
    Próbowałem już z takim warunkiem. Tak jest aktywne tak długo jak na wejściu jest stan wysoki. Co najdziwniejsze wszystko działa dobrze jeżeli chociaż na jednym wyjściu jest stan wysoki. Jak nie ma nic to zaczynają wariować
  • #12 9283879
    rmk
    Poziom 12  
    Czyli 'wiszą' w powietrzu i dzieje się z nimi co chce. Powinno działać dobrze, jeśli będzie na nich jakiś stan. Czy wysoki, czy niski. Ale musi być podłączony. Spróbuj zewrzeć wejścia z masą. Powinno przestać wariować.
  • #13 9283904
    bilbo1
    Poziom 10  
    No racja. Komplikuje mi to trochę sprawę bo muszę coś zrobić na płytce, żeby wejścia nie wisiały w powietrzu. Może pomoże jak podepnę wewnętrznym rezystorem do Vcc i ustawiać będę dotknięciem końcówki masy. Później wypróbuje i dam znać jak poszło
  • #14 9286782
    bilbo1
    Poziom 10  
    Podpiąłem wejścia do Vcc przez wewnętrzny rezystor. Wyjścia przestały wariować jednak stało się coś z przerwaniem. Kiedy zgłąszane jest przerwanie ( w tym wypadku polega na odcięciu INT0 od masy) zapala się dioda na pin 0, czyli tak jak powinno być, jednak nie ma zamiaru zgasnąć. I nie pomaga tu zmiana stanu wejść. Zmieniony kod:
    
    #include <avr/io.h> 
    #include <util/delay.h>  
    #include <avr/interrupt.h>   
    
    
    ISR (INT0_vect)
    {
    PORTB |= _BV(0);
    PORTB &=~(_BV(1));	//wylacza inne zrodla
    PORTB &=~(_BV(2));
    while (!(PINA & 0b00100000)){};
    }
    
    
    int main(void) 
    { 
    //wyjscia
    _delay_ms(500);
    DDRB |= _BV(0);
    DDRB |= _BV(1);  
    DDRB |= _BV(2);
    PORTB = 0b00000000;
    
    //wejscia
    DDRA &=~(_BV(5)); 	//zewnetrzne	
    DDRA &=~(_BV(6));	//przetwornica
    DDRA &=~(_BV(7));	//agregat
    DDRD &=~(_BV(2)); 	//INT0
    PORTA |= _BV(5);
    PORTA |= _BV(6);
    PORTA |= _BV(7);
    PORTA |= _BV(2);
    // konfiguracja przerwania int0
    
    GICR |= _BV(INT0);
    MCUCR |= _BV(ISC00);
    MCUCR |= _BV(ISC01);
    sei();
    
    while (1)
    {
    
    if (!(PINA & 0b01000000))
    {
    PORTB |= _BV(1);
    PORTB &=~(_BV(0));	//wlacza przetwornice i wylacza inne
    PORTB &=~(_BV(2));
    _delay_ms(500);
    
    }
    while (!(PINA & 0b01000000)){};
    	
    	
    if(!( PINA & 0b10000000))
    {
    PORTB |= _BV(2);
    PORTB &=~(_BV(0));	//wlacza agregat i wylacza inne
    PORTB &=~(_BV(1));
    _delay_ms(500);
    }while (!(PINA & 0b10000000)){};
    
    
    }
    }
    
  • Pomocny post
    #15 9287360
    rmk
    Poziom 12  
    Cytat:
    Kiedy zgłąszane jest przerwanie ( w tym wypadku polega na odcięciu INT0 od masy)

    Trzeba było zostawić jak wcześniej, że stan niski powoduje przerwanie (bo jak rozumie to teraz stan wysoki powoduje zgłoszenie przerwania).
    I chyba masz konfiguracje przerwania złą. nie powinno być:
    MCUCR &= ~_BV(ISC00);
    MCUCR &= ~_BV(ISC01);
    Cytat:

    ISC01 ISC00 Description
    0 0 The low level of INT0 generates an interrupt request.
    0 1 Any logical change on INT0 generates an interrupt request
    1 0 The falling edge of INT0 generates an interrupt request.
    1 1 The rising edge of INT0 generates an interrupt request.

    A poza przerwaniem jest ok?
  • #16 9292047
    bilbo1
    Poziom 10  
    Wszystko działa jak powinno. Problemem były "wiszące wejścia". Dzięki rmk. Zamykam temat
REKLAMA