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

Jak ustawić i wysłać sygnał PWM z ATMega8 do L293D w języku C?

valarian 08 Sie 2005 23:39 15177 12
REKLAMA
  • #1 1718354
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    Pisze wlasnie program do swojego robota i mam problem... Otoz nigdy przedtem nie uzywalem w ATMega8 PWM... I nie wiem, jak wyslac taki zmodulowany sygnal do L293D... Pisze w C, moze ktos moglby mi pomoc ... Szukalem na Google, w dokumentacji.. Ale za wiele nie znalazlem...
  • REKLAMA
  • #2 1718374
    zerpo
    Poziom 22  
    Posty: 463
    Pomógł: 50
    Ocena: 134
    Zmudulowany sygnał wysłać jest najlepiej na wejscie ENABLE scalaka L293D...
    A jak uruchomić PWM, to juz nie ta grupa, ale generalnie nalezy posluzyc sie rejestrami: TCCRnx oraz OCRnxH/L (gdzie n - liczba(1,2), x- litera(A,B)
    W dokumantacji jest to opisane dość szczegółowo. Więcej szczegółów na grupie Mikrokontrolery
    Powodzenia :-)
  • #3 1718403
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    Dzieki... Poszukam i pokombinuje...
    A moderatora prosze o przeniesienie posta na forum uC...
    Pozdro...

    Dodano po 1 [godziny] 6 [minuty]:

    Hmm... Dlaczego to nie chce dzialac? Powinno byc OK... Sparawdzam napiecie woltomierzem na nozce PB1 i nic... Moze cos jest w tym kodzie nie tak?

    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    #include <inttypes.h> 
    
    void PWM_Init (void)
    {
    TCCR1A = 130;
    TCCR1B = 27;
    ICR1H = 4;
    ICR1L = 226;
    OCR1AH = 4;
    OCR1AL = 225;
    }
    
    int main (void) 
    {
     unsigned int pwm=1249;
     cbi(DDRD,PD0);
     cbi(DDRD,PD1);
     sbi(DDRB,PB1);
     PWM_Init();
     for(;;)  
     {
      OCR1A = pwm;
     } 
     return (0);     
    }
  • #4 1718574
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 138
    Ocena: 31
    Witam...

    Na początek może spróbuj zmienić zapis
    TCCR1A = 130; na TCCR1A = 0b10000010; lub TCCR1A = (1 << COM1A1) | (1 << WGM11); łatwiej ci będzie połapać się co ustawiłeś...

    A co do samego problemu z działaniem programu to sprawdz tak
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h> 
    #include <inttypes.h> 
    
    volatile uint16_t pwm=1249;
    
    void PWM_Init (void) 
    { 
    TCCR1A = 130; 
    TCCR1B = 27; 
    ICR1H = 4; 
    ICR1L = 226; 
    OCR1A = pwm; 
    TIMSK |= (1 << TOIE1);
     sei();
    } 
    
    int main (void) 
    { 
     cbi(DDRD,PD0); 
     cbi(DDRD,PD1); 
     sbi(DDRB,PB1); 
     PWM_Init(); 
     for(;;)  
     { 
      
     } 
     return (0);      
    }
    
    // Jeśli chcesz w trakcie działania zmieniać wypełnienie
    // To wartość rejestru OCR1A zmieniasz przy przepełnieniu 
    SIGNAL (SIG_OVERFLOW1)
    {
     OCR1A = pwm;
    }
    
    
  • REKLAMA
  • #5 1720639
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    Hmmmm... Juz dziala.. Ale problem lezal w czym innym.. Natoimast nie wiem, dalczego dioda podlaczona pod PB1 miga, zamiast swiecic swiatlem ciaglym...

    Dodano po 27 [minuty]:

    Przejrzalem sobie dokumentacje ATMega8, ale nie moge rozszyfrowac takiego zapisu, jaki znalazlem w jednym z kodow w necie [odnosnie tego samego problemu, PWM]

    
     TCCR1A =  (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0) |(1<<COM1B1) | (1<<COM1B0); //8bit PWM, phase correct
     TCCR1B = (1<<CS11) | (1<<WGM12);				//MCU clock / 8
    


    Tylko to wpisuje do PWM_init i dziala...
  • Pomocny post
    #6 1720748
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 138
    Ocena: 31
    (1 << NAZWABITUWREJESTRZE) oznacza ustawienie go na "1"...
    Nazwy poszczególnych bitów znajdziesz w dokumentacji...
    Taka metoda ma spory plus...
    Zdecydowanie łatwiej połapać się co się ustawiło...
    Może częstotliwość jest za niska...
    Przeglądnij sobie dokładnie fragment dokumentacji dotyczący timera1...
    O ile dobrze pamiętam przy 50Hz już nie będzie migać...
  • #7 1720767
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    Dzieki, juz kumam... Z tymi dwoma linijkami wszystko jest juz OK.. Dziala jak trzeba :-)

    Dodano po 9 [minuty]:

    Aha, moze jeszcze mi ktos podpowiedziec, jak w tym uC ustawia sie dane wejscie [np. PD2] tak, aby reagowalo na narastajace zbocze, a nie na stan wysoki [tak jest chyba ustawione domyslnie]...?
  • #8 1721577
    zerpo
    Poziom 22  
    Posty: 463
    Pomógł: 50
    Ocena: 134
    Apropo wejść.. Z tego co do tej pory się bawiłem, to zwykły pin reaguje tylko na dany stan, nie na zbocze... Funkcje taką mogą mieć dopiero wejścia specjalne, np.: zew. przerwanie (INT0, 1...), oraz timery. Można je ustawić tak, żeby reagowały na dane zbocze, lub stan. Chyba, że czegoś jeszcze nie wiem... ;)
  • REKLAMA
  • #9 1722659
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    Wlasnie nie wiem... Gdzies przeczytalem cos o reakcji portu na narastajace zbocze, ale nie pamietam, do czego to dotyczylo... A tej stronki juz znalezc nie moge :-)
  • #10 1722782
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    Zwykłe piny reagują tylko na poziomy napięć. Ale fakt mogłeś takie coś przeczytać i powinno to być w nocie katalogowej, a dotyczyć może np. czasu reakcji wewnętrznej logiki, znaczy po jakim czasie od wystąpienia narastającego zbocza procesor zobaczy na tym wejściu jedynkę logiczną.

    A obsługa zboczy na pinach jest raczej mało sensowna z punktu widzenia programu, bo sprowadza się dokładnie tdo tego samego, co obsługa poziomów, czyli do wykrycia przez program zmiany poziomu na pinie.
    Ma to sens wyłącznie w wypadku przerwań, czy liczników, gdzie zbocze jednoznacznie określa moment w którym dany układ ma być wyzwolony.
  • #11 1722812
    valarian
    Poziom 22  
    Posty: 647
    Pomógł: 33
    Ocena: 112
    A jakie piny mozna ustawic w tryb reakcji na zbocze?
  • REKLAMA
  • #12 1723205
    sepher
    Poziom 19  
    Posty: 301
    Pomógł: 21
    Ocena: 4
    Piny, które jednocześnie służą jako źródło przerwań zewnętrznych. Oznaczane są INT0, INT1, .... itd. ATmega8 ma o ile pamiętam 2 takie wyprowadzenia. Aby móc z nich korzystać trzeba oczywiście wszystko odpowiednie pokonfigurować. Powodzenia! ;)
  • #13 1748173
    migod
    Poziom 21  
    Posty: 462
    Pomógł: 29
    Ocena: 8
    valarian napisał:
    A jakie piny mozna ustawic w tryb reakcji na zbocze?


    piny oznaczone jako INT0,1

    Jak?

    
      outp((1<<INT0), GIMSK);
      outp( (1<<ISC01)|(1<<ISC00) | (1<<ISC10)|(1<<ISC11), MCUCR);
       ...
      sei();
    


    o ile pamiętam - ustawia wywołanie przerwania zarówno przy opadającym, jak i narastającym zboczu, dla obu przerwań - INT0 i INT1

    zaś w kodzie definiujesz obsługę przerwania jako np.

      
       SIGNAL(SIG_INTERRUPT0)  {
        ...
       }
    


    oczywiście powinna być możliwie 'krótka' ;-)

    obowiązkowe include-y:
      
     <avr/interrupt.h>, <avr/signal.h>
    


    PS. fragmenty kodu dla at90s4433, być może pewne wymaga drobnych modyfikacji dla atmega8

    pozdro,
    --
    migod

Podsumowanie tematu

✨ Dyskusja dotyczy generowania sygnału PWM na mikrokontrolerze ATMega8 w języku C oraz jego sterowania układem L293D. Sygnał PWM powinien być podawany na wejście ENABLE układu L293D. Konfiguracja PWM w ATMega8 wymaga ustawienia odpowiednich rejestrów timerów, głównie TCCR1A, TCCR1B, OCR1A oraz ICR1. Zalecane jest używanie zapisu bitowego (np. (1
Wygenerowane przez model językowy.
REKLAMA