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

[c][atmega8] Sterownik silnika krokowego pod EMC2

syntetyczn dran 17 Wrz 2010 19:08 4232 7
REKLAMA
  • #1 8521449
    syntetyczn dran
    Poziom 12  
    Witam,
    Cały dzień męczę się z programem do uc na przerwaniach. Ponieważ jestem początkujący, narobiłem masę błędów. No ale...
    Na pinach 0,1,2,4 portu D są tranzystory w układzie darlingtona
    na int1 jest wejście step z EMC2
    a na pinc1 jest sygnał lewo , prawo.
    Niby wszystko się świeci, ale silnik się nie kręci. Steruję halfstepem.
    
    //#define F_CPU 1000000L
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    
    volatile unsigned int flaga = 0;
    
    void Inicjalizacja(void)
    {
        sei();                            //Włączenie obsługi przewań   
       
    // INT1 - zbocze opadające, INT0 - brak
    MCUCR = _BV(ISC11);
    // załączenie przerwania od INT1
    GICR = _BV(INT1);
    }
    
    SIGNAL (SIG_INTERRUPT1)
    {
       flaga++;
    }
    
    int step(int i)
    {int krok[8]={0x01,0x05,0x04,0x06,0x02,0x12,0x10,0x11};
    if(i<0){i=7;}
    if(i>7){i=0;}
    PORTD=krok[i];
    
    return i;
    }
    
    
    
    int main( void )
    {
       Inicjalizacja();
       
    int i=0;
    /* Wszystkie linie portu D sa wyjsciami */
       DDRD = 0x17;  
    /* Wszystkie linie portu C sa wejściami */
       DDRC= 0x00;
       PORTC=0x00;
    
       while(1)
       {
    if(flaga==1)
    {if(!(PINC&0x02)){i--;step(i);}else{i++;step(i);}
    i=step(i);flaga=0;
    }
    PORTD=0;
    }
    
    } 
    

    Prosiłbym o pomoc!
  • REKLAMA
  • #2 8521564
    danthe
    Poziom 30  
    Skoro ustawiasz cały port D jako wyjścia to nie dziwię się że nie działa int1 - pin D.3 .

    Sorki, nie zauważyłem że ddrd masz ustawiony właściwie, zasugerowałem się opisem.
  • REKLAMA
  • #3 8522105
    janbernat
    Poziom 38  
    Chyba w C to się każdą bzdurę da skompilować.
    Uporządkuj ten kod i dodaj komentarze- co chcesz w danej linii dostać.
    I nawiasy.
    I schemat.
  • #4 8522155
    Andrzej__S
    Poziom 28  
    syntetyczn dran napisał:

    
    ...
       while(1) 
       { 
    if(flaga==1) 
    {if(!(PINC&0x02)){i--;step(i);}else{i++;step(i);} 
    i=step(i);flaga=0; 
    } 
    PORTD=0; // proponuję usunąć
    }
    ...
    


    Najpierw wewnątrz funkcji 'step()' ustawiasz PORTD, po czym zerujesz go w pętli 'while' w funkcji 'main'. Jak go ustawisz, to chyba tak powinien zostać do następnego impulsu (kroku).

    Poza tym niepotrzebne kombinacje z tym ograniczaniem wartości zmiennej 'i'.
    syntetyczn dran napisał:

    
    int step(int i) 
    {int krok[8]={0x01,0x05,0x04,0x06,0x02,0x12,0x10,0x11}; 
    if(i<0){i=7;} // proponuję usunąć
    if(i>7){i=0;} // proponuję usunąć
    PORTD=krok[i]; 
    
    return i; // proponuję usunąć i zmienić deklarację funkcji na 'void step(int i)'
    }
    


    Usuń zaznaczone linie z funkcji step(), a zamiast tego zrób np. tak w funkcji 'main':
    
       while(1) 
       { 
          if(flaga==1) 
          {
             if( !(PINC & 0x02) ) i--;
             else i++;
             i &= 0x07;
             step(i);
             flaga=0;
          }
       }
    


    No i zwróć uwagę na różnicę w formatowaniu kodu, o czym już napisał janbernat :), bo Twój kod jest mało czytelny.
  • REKLAMA
  • #5 8522353
    syntetyczn dran
    Poziom 12  
    Dzięki za odzew. Z tym zerowaniem portu D to może być główna przyczyna błędu. Jutro z rana zajmę się schematem i uporządkowaniem wszystkiego(jakoś w winavr to wszystko wydawało się czytelniejsze).
  • #6 8523399
    janbernat
    Poziom 38  
    Sekwencja przy pracy półkrokowej powinna być chyba taka:
    100x0 0x10
    110x0 0x18
    010x0 0x8
    011x0 0xC
    001x0 0x4
    001x1 0x5
    000x1 0x1
    100x1 0x11
    gdzie x jest pinem przerwania- więc powinno być 0.
  • REKLAMA
  • #7 8523609
    Andrzej__S
    Poziom 28  
    janbernat napisał:

    Sekwencja przy pracy półkrokowej powinna być chyba taka:
    100x0 0x10
    110x0 0x18
    010x0 0x8
    011x0 0xC
    001x0 0x4
    001x1 0x5
    000x1 0x1
    100x1 0x11
    gdzie x jest pinem przerwania- więc powinno być 0.

    Pinem przerwania INT1 w ATmega8 jest PD3, a nie PD1.

    Autor użył kombinacji:
    
    0bxxx0x001 = 0x01
    0bxxx0x101 = 0x05
    0bxxx0x100 = 0x04
    0bxxx0x110 = 0x06
    0bxxx0x010 = 0x02
    0bxxx1x010 = 0x12
    0bxxx1x000 = 0x10
    0bxxx1x001 = 0x11
    

    więc wydaje się, że wszystko OK, tylko jakby PD2 jest zamienione z PD1. Wszystko zależy od schematu. Zakładając, że schemat połączeń silnika jest odpowiedni do tego sterowania (tego nie wiemy), imho - powinno działać.
  • #8 8525014
    syntetyczn dran
    Poziom 12  
    Po usunięciu PORTD=0; wszystko zaczęło działać jak należy.

    Oto działający kod:
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    
    volatile unsigned int flaga = 0;
    
    void Inicjalizacja(void)//inicjalizacha przerwań na porcie int1
    {
        sei();  //Włączenie obsługi przewań   
       
        // INT1 - zbocze opadające
        MCUCR = _BV(ISC11);
        // załączenie przerwania od INT1
        GICR = _BV(INT1);
    }
    
    SIGNAL (SIG_INTERRUPT1)//zwiększenie flagi o 1 przy wystąpieniu przerwania
    {
       flaga++;
    }
    
    //funkcja z zabezpieczeniami dla kroku, podająca wartości załączanych cewek
    int step(int i)
    {int krok[8]={0x01,0x05,0x04,0x06,0x02,0x12,0x10,0x11};
    if(i<0){i=7;}
    if(i>7){i=0;}
    PORTD=krok[i];
    
    return i;
    }
    
    
    
    int main( void )
    {
       Inicjalizacja();
       
    int i=0;
    /* Linie 0,1,2,4 portu D sa wyjsciami */
       DDRD = 0x17;  
    /* Wszystkie linie portu C sa wejściami */
       DDRC= 0x00;
       PORTC=0x00;
    
       while(1)
       {
    if(flaga==1)
    {
        if(!(PINC&0x02))
        {
            i--;step(i);
        }else{
            i++;step(i);
            }
    i=step(i);flaga=0;
    }
    }
    
    } 
    
REKLAMA