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

AT90S2313 w "C" - pomoc przy obsłudze enkodera

insectteam 03 Lut 2009 22:14 1824 6
REKLAMA
  • #1 6099100
    insectteam
    Poziom 11  
    Witam wszystkich !

    Wiem że temat był parę razy poruszany, ale nie wiem jak to ugryźć mimo że przeczytałem kilka postów ...

    Potrzębuję banalnego programu obsługi enkodera który spowodowałby że kręcąć enkoderem w jedną stronę, impulsy wysyłane byłyby na portx.1 a w drugą stronę na portx.2 - najgorsze jest to że ślęczę nad tym kilka dni a nic nie wymyśliłem, a termin wstępnego pokazu pracy dyplomowej już za chwilę i z tego stresu idzie mi coraz gorzej ...

    pomóżcie proszę ....
  • REKLAMA
  • REKLAMA
  • #3 6102679
    insectteam
    Poziom 11  
    dziękuję za linka - trochę popróbowałem, wklepałem z tej stronki program który podobno chodzi i d...

    Oto ten programik

    signed char
    encoder(void)
    {
    static unsigned char a, b;
    if (!a & !b) {
    if (PIND.2) {
    a = PIND.2;
    return (-1);
    }
    if (PIND.5) {
    b = PIND.5;
    return (1);
    }
    }
    if (a & !b) {
    if (!PIND.2) {
    a = PIND.2;
    return (1);
    }
    if (PIND.5) {
    b = PIND.5;
    return (-1);
    }
    }
    if (a & b) {
    if (!PIND.2) {
    a = PIND.2;
    return (-1);
    }
    if (!PIND.5) {
    b = PIND.5;
    return (1);
    }
    }
    if (!a & b) {
    if (PIND.2) {
    a = PIND.2;
    return (1);
    }
    if (!PIND.5) {
    b = PIND.5;
    return (-1);
    }
    }
    return (0);
    }


    Niestety kręcąc czy w jedną , czy w drugą stronę zawsze działa to samo wyjście ...

    P.S dodam że mam enkoder wymontowany ze skrola z myszki ( 3 wyjściowy )

    Może ma ktoś taki gotowiec - nawet w Bascomie - to se rozbije całość urządzenia na 2 procki ( bo tego mam sporo )


    HELP... !!!
  • REKLAMA
  • Pomocny post
    #4 6104104
    MarcinKawka
    Poziom 12  
    Ja coś podobnego zrobiłem na ATmedze16. Podłączyłem enkoder pod wejścia generujące przerwania zewnętrzne i odpaliłem tajmer, zliczam różnice czasu między przerwaniami. W AT90S2313 masz przerwania zewn z PD2 i PD3.

    w obsłudze przerwania zewn. robisz:

    prędkość = (obwód_koła / rozdzielczość_tarczy_enkodera) / różnica_czasu_między_przerwaniami

    lub pomiar całkowy:

    dystans += obwód_koła / rozdzielczość_tarczy_enkodera

    oto kawałek kodu z Atmegi16, pewnie trzebaby pozmieniać nazwy/bity rejestrów i bedzie działac na AT90S2313:
    
    ISR(TIMER2_OVF_vect){ //przerwanie co 1.024 ms
    licznik++;
    }
    
    ISR(INT1_vect){
    	curr_l_speed = DROGA_NA_PRZERWANIE / (licznik -old_licznik_l);
    	old_licznik_l = licznik;
    	odometry_l += DZIALKA;
    }
    init()
    {
    	TIMSK |= _BV(TOIE2);	//wlacz przerwanie od Timera2
    	TCCR2 = 0x05;			//włącz Timer0 z prescalerem /1024
    	//Inicjalizacja przerwan od enkoderów silników 1 i 2
    	MCUCR |= _BV(ISC10) | _BV(ISC00);	//każda zmiana sygnału na wejściach INT0 i INT1 generuje przerwanie
    	GICR |= _BV(INT0) | _BV(INT1);		//włącz prerwania
                sei();
    }
    
    
  • REKLAMA
  • #5 6110206
    insectteam
    Poziom 11  
    Witam !

    Poradziłem sobie z tym ( no może nie do końca ) - od czasu do czasu kręcąc w jedną ze stron sygnalizowany jest obrót w przeciwną, no i przy dużych prędkościach nie najlepiej idzie, ale na początek wystarczy ...
  • #6 6661791
    Sparrowhawk
    Poziom 22  
    Napiszę tutaj, zamiast zaczynać nowego wątku. Mam układ ATmega32. Do niego podłączone są przez demultiplekser 3 wyświetlacze LED i 3 enkodery. Całość ma odświeżanie 100Hz z wypełnieniem 1/10. Wyjścia enkoderów są połączone i jedno z nich dołączone jest do PD3 (INT1), a drugie do PD7. Program, który ma obsługiwać całość wygląda tak:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    volatile uint8_t ADRES;
    int LED[3] = {2,3,4};
    
    
    int WYSW(int LEDS[3])
    {
    	DDRA = 0xFF;
    	PORTA = LEDS[ADRES];
    	return 0;
    }
    
    
    SIGNAL (SIG_OVERFLOW0)
    {
    	TCNT0 = 10;
    	if(ADRES>0)
    	{
    		ADRES--;
    	}
    	else
    	{
    		ADRES = 10;
    	}	
    	if(ADRES<3)
    	WYSW(LED);
    }
    
    ISR(INT1_vect)
    {
    	{
    		unsigned char TEMP = PIND & (_BV(7)|_BV(3));
    		unsigned int ADRESS = ADRES;
    
    		ADRESS = ADRESS-3;
    		
    		if(TEMP==0 || TEMP == (_BV(7)|_BV(3)))
    		{
    			LED[(ADRESS)-3]++;
    			if(LED[ADRESS] == 10)
    			LED[(ADRESS)-3] = 0;
    		}
    		else
    		{
    			LED[ADRESS]--;
    			if(LED[ADRESS] == 0)
    			LED[ADRESS-3] = 10;
    		}		
    	}
    }
    
    int main(void)
    {	
    	TIMSK = _BV(TOIE0);
    	TCCR0 = _BV(CS00)|_BV(CS01);
    	TCNT0 = 10;
    	MCUCR |=_BV(ISC11);
    	MCUCR &=~_BV(ISC10);
    	GICR |= (_BV(INT1)); 
    	sei();
    	while(1)
    	{
    	DDRD &=~(_BV(7) | _BV(3));
    	PORTD |=(_BV(7) | _BV(3)); 
    	DDRC = 0xFF;
    	PORTC = ADRES;
    	}
        return 0;
    
    }
    
    Niestety enkodery nie działają.


    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
  • #7 6664431
    Konto nie istnieje
    Poziom 1  
REKLAMA