Skocz do zawartości

Sterowanie PWM AVR


Krawi92

Pomocna odpowiedź

Witam, dziś ruszyłem temat pwm. Udało mi się uruchomić na 2 kanałach tryb fast pwm 8 bit.  Doczytałem, że za wartość wypełnienia odpowiadają rejestry porównawcze OCR1A i OCR1B, do nich należy wprowadzić wartość. Myślałem, że jak wybieram pwm 8 bitowy to maksymalna wartość to będzie 255.(od 0 do 255). Jednak w te rejestry mogę wpisać o wiele większą liczbę,.. przy 1023 świeci maksymalnie, przy 1024 baardzo słabo.. napisałem prosty program, rozjasniajaco-ściemniający 2 diody i wszystko OK, działa... 

#include <avr/io.h>
#include <util/delay.h>
#include<avr/interrupt.h>

int main (){
	DDRB |= 0b00000110; // Ustawienie portów wyjscia PB1 i PB2
// =INICJALIZACJA PWM= //
	TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(1<<COM1A1); // tryb 8 bit i wlaczone 2 kanaly
	TCCR1B |= (1<<WGM12); // tryb 8bit fast PWM
	TCCR1B |= (1<<CS11); // prescaler 8

while(1) {
	for (int16_t i=0; i<1024; i++){ // pętla zwiekszająca wypelnienie
	OCR1A = i;
	OCR1B = i;
	_delay_ms(1);
}
	for (int16_t i=1023; i>=0; i--) { // pętla zmniejszająca wypełnienie
	OCR1A = i;
	OCR1B = i;
	_delay_ms(1);
}

}
}

Chciałbym jednak zrozumieć, gdzie mój błąd w rozumowaniu, że do OCRxx mozna wprowadzać takie a nie inne wartości... 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Napisze tylko "xD". Do zamknięcia, dzięki 😄

Albo dopytam jeszcze o jedną rzecz... Pamiętam z kursu arduino, że do sterowania servo potrzebujemy wygenerować sygnal o okresie 20ms.. czyli o częstotliwości 50Hz. Próbuje to podzielić jednak się nie udaje tak dokladnie 😛  Moj cpu taktuje 1MHz, więc najblizsza wartość 

1 000 000/prescaler 64/256(8bitowy pwm) i otrzymam ok 61Hz. czyli ok 16ms... Jak to dokladnie skalibrować.. ? 

Edytowano przez Krawi92
Link do komentarza
Share on other sites

Na arduinowym pwm (okolo 490 Hz) servo dziala normalnie...no ale tu sie akurat zakres mniej wiecej miesci w specyfikacji serva jak @ethanak wspomnial...czyli max okres "wlaczenia" to 2ms...gdzie serwo ma miec miedzy 1-2ms...i pozostaly czas do 20ms to przerwa...na tym trybie pwm nie zrobisz tego...musisz inaczej kombinowac..ja to zrobilem tak ze do 1ms dodawalem cos z zakresu 1-2ms i pozniej od 20ms odjalem ten czas wlaczenia i ustawialem pin na wylaczenie i tak w kolko...

Link do komentarza
Share on other sites

@farmaceuta a z ciekawości - co by było, gdybyś ustawił czas pauzy sztywno na 16 msec i nie bawił się w odejmowanie? Czyli: impuls o określonej zmiennej długości plus stała pauza?

Ja jestem leniem i po prostu podpinam sterownik na I2C, nie bardzo mi się chce bawić w generowanie przebiegów na esp32 czy rpi pico (pomijając fakt, że jak masz dziesięć serw i jeszcze parę led to się piny kończą). Ale tam też mogę ustawić częstotliwość...

Link do komentarza
Share on other sites

Yyyy czekajcie bo troche się pogubiłem. Ja napisze jakbym chciał to zrobić a Wy mi powiecie czy Ok 😄 Powiedzmy, że sobię ustawie 1Mhz/64 presc/ wybiore 8bitowy fast pwm... .. I pozycją serva sterujemy poprzez zmiane wartosci OCRxx ? Oj bo chyba coś źle mysle 😛

Link do komentarza
Share on other sites

Nie no nic sie nie stanie, zaraz zaczne to skladac. Na arduino to bylo prostackie, nie martwilem sie takimi rzeczami, byla gotowa biblioteka servo.h podlaczalem i działało. Teraz jak to zaczynam poznawać od srodka to jednak trzeba sie nad tym duzo glebiej pochylic. 

Link do komentarza
Share on other sites

No to poczytaj sobie kod biblioteki servo dla Arduino.  Naprawdę ciekawe!

A zauważ, że biblioteka nie korzysta w ogóle ze sprzętowego pwm, a jakoś jest w stanie w czasie rzeczywistym machać dwunastoma serwami...

Edytowano przez ethanak
Link do komentarza
Share on other sites

47 minut temu, ethanak napisał:

@farmaceuta a z ciekawości - co by było, gdybyś ustawił czas pauzy sztywno na 16 msec i nie bawił się w odejmowanie? Czyli: impuls o określonej zmiennej długości plus stała pauza?

Bedzie dzialac z roznymi "pauzami"... ja to tak sobie zrobilem jako cwiczenie.. (troszke sie zakrecilem..ja nie odejmuje tylko licze sobie i w odpowiednim momencie robie co mam robic...)

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>



volatile uint16_t x = 0;   //uint16 = 50Hz / uint8 = prawie 8 razy wieksza czestotliwosc (x sam sie "przekreci" po 256 przerwaniach
volatile uint8_t pw = 0;


void setup() {
 Serial.begin(115200);
  
 DDRD |= (1 << PD2);        //pin 2 jako wyjscie
 
 TCCR2B &= 0x00;
 TCCR2A &= 0x00;
  TCCR2A |= (1<<WGM21);     //CTC tryb                           
 
  TCCR2B |= (1<<CS21);      //preskaler na 8
 // TCCR2B |= (1<<CS20);    //preskaler na 0
   
   TIMSK2 |= (1<<OCIE2A);    //wlaczenie przerwania od porownania
   OCR2A = 20;  //255 max    //przypisanie wartosci startowej do licznika
  sei();                    // przerwania globalne wlacz
}

void loop() {

 //pw = map(analogRead(A0), 0, 1023, 0, 100);
 pw++;
 if(pw == 100) {
  pw = 0;
 }
 delay(50);
 
}

ISR (TIMER2_COMPA_vect)
{   x++;
      
    if (x < (100 + pw)) {       //1ms + wartosc wypelnienia 0-100 (1ms)
        PORTD |= (1 << PD2);  //stan wysoki
  } else {
     if (x < 2000) {     //20ms cykl
        PORTD &= ~(1 << PD2);         //stan niski
      }  else {
      x = 0;       // jesli minelo 20ms zacznij od nowa liczyc 
    }
  }
}

z tym ze u mnie rozdzielczosc to 0-100...przerwanie nastepuje co 10us, a jak juz wiadomo zakres dla serwa to 1-2ms...ten sam kod lekko zmieniony tak zeby "pauza" byla sztywna tez dziala bez zarzutu, przerwy co 10ms/20ms/50ms a nawet 100ms tez dziala z tym ze przy tych dluzszych przerwach juz widac/slychac wyraznie "kroki"...

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.