• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Niskie taktowanie na PWM Atmega8

Object Storage Arubacloud
0 głosów
703 wizyt
pytanie zadane 6 lutego 2020 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)
Chcę aby uC był taktowany na 8MHz, a jednocześnie potrzebuję uzyskać taktowanie 50Hz na zegarze PWM (programowanie serwomechanizmu). Nie mam pomysłu jak mogę zyskać taki efekt, pomógłby ktoś?

2 odpowiedzi

0 głosów
odpowiedź 6 lutego 2020 przez mokrowski Mędrzec (155,460 p.)
Masz 3 wyjścia:

1. Timery programowe

2. Timery sprzętowe

3. Zewnętrzny kontroler PWM

Ostatnie pewnie odpada bo to dodatkowy koszt. Najłatwiej będzie programowym.

Leciwe ale przydatne: http://hobby.abxyz.bplaced.net/index.php?pid=3&aid=20

Jeśli dalej nie zrozumiesz, zapytaj.
0 głosów
odpowiedź 6 lutego 2020 przez adrian17 Ekspert (344,860 p.)
edycja 6 lutego 2020 przez adrian17

Na przykład (w tym stylu skonfigurowałem to w swoim projekcie lata temu, na oba kanały na raz, atmega16, 1MHz zegar):

// piny PWMa
DDRD = (1<<PD5) | (1<<PD4);

// PWM
TCCR1A =(1<<COM1A1)|   //tryb komparatora bez inwersji kanału OC1A
        (1<<COM1B1)|   //tryb komparatora bez inwersji kanału OC2B
        (1<<WGM10);    //wybor trybu (Fast PWM 8-bit)
TCCR1B =(1<<WGM12)|    //wybor trybu (Fast PWM 8-bit)
        (1<<CS10)|     //uruchomienie timera z prescalerem 64
        (1<<CS11);
        
OCR1A = 60; // 60/256 duty cycle -> ~25% dłgość pulsu
OCR1B = 120; // 120/256 duty cycle -> ~50% długość pulsu

U mnie z taktowaniem 1MHz to dawało 1MHz / 64 prescaler / 256 (bo 8-bit PWM) == 61Hz. Nie równo 50Hz, ale współczesne serwa akceptują duże zakresy częstotliwości (bardziej interesuje je szerokość pulsu).

Wrzuciłem ten kod u siebie na początek programu i potem tylko edytowałem OCR1A i OCR1B żeby kontrolować moc silników.

Z 8MHz można na przykład użyć prescaler 256 i tryb 9-bitowy PWMa żeby dostać analogicznie 61Hz. Albo można użyć Fast PWM z "customowym" maxem i ustawiając ICR1 dostać niemal dokładnie 50Hz (np: 8MHz / prescaler 8 / 20000 ICR1 == 50MHz). Jak chcesz to mogę Ci spróbować na sucho napisać konfigurację do tego.

Po szczegóły polecam zajrzeć do specyfikacji atmegi, rozdział "16-bit Timer/Counter1", przede wszystkim podrozdziały "Modes of Operation" i "16-bit Timer/Counter Register Description"; ładnie opisują wszystkie tryby w których może działać PWM i jak je włączyć.

komentarz 6 lutego 2020 przez Mavimix Dyskutant (8,390 p.)
edycja 6 lutego 2020 przez Mavimix
I serwo podłączam do PD4 lub PD5 tak? A to: OCR1A = 60; oznacza, że dziele OCR1A na 60, tak?
komentarz 6 lutego 2020 przez adrian17 Ekspert (344,860 p.)
edycja 6 lutego 2020 przez adrian17

Tak jak mówiłem, to był przykład na atmegę16, więc dla atmegi8 trzeba by go trochę zaadaptować - na przykład pin OC1A jest na porcie B, nie D.

A to: OCR1A = 60; oznacza, że dziele OCR1A na 60, tak?

A tego tak szczerze to nie zrozumiałem. W trybie Fast PWM to działa tak, że, że dla wartości rejestru timera od 0 do 60 na pinie jest wysoki sygnał, a potem spada na niski sygnał. W trybie 8-bitowym rejestr liczy do 255 i się zawija, więc wysoki sygnał masz przez 60/256 czasu. W trybie "elastyczniejszym" (#14 na tabeli 39 z datasheetu) rejestr liczy do wartości ICR1.

komentarz 6 lutego 2020 przez adrian17 Ekspert (344,860 p.)

Przykład bardziej zaadaptowany pod Twój use case - na sucho, więc może nie działać ;)

void setup() {
    // piny PWMa
    DDRB = (1<<PB1) | (1<<PB2);
     
    // PWM
    TCCR1A =(1<<COM1A1)|   //tryb komparatora bez inwersji kanału OC1A
            (1<<COM1B1)|   //tryb komparatora bez inwersji kanału OC2B
            (1<<WGM11);    //wybor trybu (Fast PWM, TOP w ICR1)
    TCCR1B =(1<<WGM12)|    //wybor trybu (Fast PWM, TOP w ICR1)
            (1<<WGM13)|    //wybor trybu (Fast PWM, TOP w ICR1)
            (1<<CS11);     //uruchomienie timera z prescalerem 8
    ICR1 = 19999; // 0-19999 -> 20000 cykli

    // 8MHz / 8 prescaler / 20000 == 50Hz
}

void set_power() {
    // przykłady mocy
    OCR1A = 0; // 0/19999 -> 0% długość pulsu
    OCR1A = 19999; // 19999/19999 -> 100% długość pulsu
    OCR1B = 2000; // 2000/19999 duty cycle -> ~10% długość pulsu
}

 

komentarz 6 lutego 2020 przez Mavimix Dyskutant (8,390 p.)
Powiem szczerze, że średnio rozumiem dlaczego takie wartości są przypisane do ICR1, OCR1A/B? Trzeba ustawiać 2 rejestry i TCRR1A i TCCR1B? Czy mógłbym 1.?
komentarz 6 lutego 2020 przez adrian17 Ekspert (344,860 p.)
edycja 6 lutego 2020 przez adrian17

Dlatego polecam mieć pod ręką datasheet atmegi8 ;)

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2486-8-bit-AVR-microcontroller-ATmega8_L_datasheet.pdf

Po kolei:

Strona 75 - tu zaczyna się opis działania timera. Pierwszych kilka stron jest mocno technicznych i mało ciekawych.

Strona 89 - pokazuje na diagramie jak działa tryb Fast PWM. Rejestr TCNT1 idzie od 0 do maksymalnej wartości i gdy po drodze przekroczy wartość OCR1, zmienia wyjście pinu na 0 aż do końca cyklu. W praktyce właśnie tak można wysyłać pulsy do serwa ze stałą częstotliwością i zmienną szerokością.

Strona 96 - zaczyna się opis, jak to ustawić w rejestrach.

Tablica 37 - ustawiam COM1A1 (i COM1B1), więc wybieram trzeci tryb, mówiący to co wyżej napisałem: "gdy po drodze przekroczy wartość OCR1, zmienia wyjście pinu na 0 aż do końca cyklu".

Strona 97/8, tablica 39 - ustawiam tryb 14, Fast PWM z konfigurowalną długością cyklu przez ICR1. W tym celu ustawiam WGM11, WGM12, WGM13. Tak się dziwnie składa, że te flagi są rozbite po dwóch rejestrach, TCRR1A i TCCR1B.

Strona 99, tablica 40 - te flagi dopiero włączają zegar timera. Przy okazji ustawiam prescaler 8 (czyli co 8 cykli zegara 8MHz wykonuje się jeden cykl timera).

dlaczego takie wartości są przypisane do ICR1

W ten sposób ustawiam częstotliwość 50MHz. Zegar 8MHz, z prescalerem 8, więc co 8 cykli podnosi timer o 1. Co 20000 cykli timera timer się resetuje, więc końcowa częstotliwość jest 8MHz/8/20000 == 50Hz.

OCR1A/B?

W sensie, dlaczego wartość 2000 to 10% długości pulsu? Wrócę do obrazka z strony 89, może to pomoże: https://puu.sh/F7PdG/fb4b6180bf.png A ogólnie tutaj wartości wpisujesz jakie chcesz, tym właśnie sterujesz serwem.

Ogólnie nie trzeba znać całego tego datasheetu znać żeby móc używać PWMy, sam znam tylko z 2-3 proste tryby które akurat potrzebowałem a z innymi nigdy nic nie robiłem ;)

Tu masz inny przykładowy tutorial po polsku (i raczej łatwiejszym językiem niż ja :P ) opisujący działanie PWMa w Atmedze, może pomoże: https://forbot.pl/blog/wszystko-co-musisz-wiedziec-aby-uruchomic-pwm-id5021

Podobne pytania

0 głosów
1 odpowiedź 246 wizyt
pytanie zadane 11 maja 2016 w C i C++ przez Dorota95 Nowicjusz (210 p.)
0 głosów
1 odpowiedź 397 wizyt
pytanie zadane 9 listopada 2018 w Mikrokontrolery przez Jezel123 Nowicjusz (120 p.)
0 głosów
1 odpowiedź 294 wizyt
pytanie zadane 30 marca 2022 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)

92,556 zapytań

141,404 odpowiedzi

319,560 komentarzy

61,942 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...