Witam,
Piszę program w C. Procek ATmega8 taktowany zewn kwarcem 16MHz i fusy oczywiście przestawione prawidłowo.
1. Ustawiam sobie Timer2 w tryb CTC
2. Ustawiam preskaler na 8
3. Ustawiam OCR2 na 20
4. Odblokowuję przerwanie CompareMatch
dzięki czemu uzyskuję przerwanie co 10us
w przerwaniu mam zmienną (licznik) którą inkrementuję do 999 i znowu na 0
mam zmienną sr której wartość porównywana jest z tym licznikiem w przerwaniu i generuję tak sobie ładnego PWM'a o częstotliwości 50Hz
bo 16.000.000 / 8 / 20 / 1000
F_CPU prescaler OCR2 kroki
czyli teoretycznie jeśli
zmienna sr=100 to wypełnienie powinno mieć impuls = 1,0ms
dla sr=150 impuls powinien być 1,5ms
dla sr=200 impuls powinien być 2,0ms
ale się niebyt chce obracać
SERVO jest Vellman'a o symbolu ES-035 (i testowane w Bascomie działa choć tam reload musiałem ustawiać na 20us bo przy 10us też jakoś było nieruchawe)
ale ok u mnie zachowuje się to bardzo dziwolągowato bo dopiero jeśli dam
sr=50 - to przyjmuje pozycję 0st
a gdy
sr=210 - to przyjmuje pozycję 180st
Gdzie popełniam błąd w założeniach? obliczeniach? czy w czym?
program wygląda mniej więcej tak:
powiem więcej, na oscylu bardzo ładnie widać jak działa ten PWM więc o co tu może chodzić ???
Piszę program w C. Procek ATmega8 taktowany zewn kwarcem 16MHz i fusy oczywiście przestawione prawidłowo.
1. Ustawiam sobie Timer2 w tryb CTC
2. Ustawiam preskaler na 8
3. Ustawiam OCR2 na 20
4. Odblokowuję przerwanie CompareMatch
dzięki czemu uzyskuję przerwanie co 10us
w przerwaniu mam zmienną (licznik) którą inkrementuję do 999 i znowu na 0
mam zmienną sr której wartość porównywana jest z tym licznikiem w przerwaniu i generuję tak sobie ładnego PWM'a o częstotliwości 50Hz
bo 16.000.000 / 8 / 20 / 1000
F_CPU prescaler OCR2 kroki
czyli teoretycznie jeśli
zmienna sr=100 to wypełnienie powinno mieć impuls = 1,0ms
dla sr=150 impuls powinien być 1,5ms
dla sr=200 impuls powinien być 2,0ms
ale się niebyt chce obracać
SERVO jest Vellman'a o symbolu ES-035 (i testowane w Bascomie działa choć tam reload musiałem ustawiać na 20us bo przy 10us też jakoś było nieruchawe)
ale ok u mnie zachowuje się to bardzo dziwolągowato bo dopiero jeśli dam
sr=50 - to przyjmuje pozycję 0st
a gdy
sr=210 - to przyjmuje pozycję 180st
Gdzie popełniam błąd w założeniach? obliczeniach? czy w czym?
program wygląda mniej więcej tak:
volatile uint16_t sr;
TCCR2 |= (1<<WGM21) // CTC
TCCR2 |= (1<<CS21) // prescaler = 8
OCR2 = 20;
TIMSK |= (1<<OCIE2); // odblokowanie przerwania CompareMatch
DDRC |= (1<<PC5);
sei();
while(1)
{
sr=100;
_delay_ms(1000);
sr=150;
_delay_ms(1000);
sr=200;
_delay_ms(1000);
}
....
....
....
ISR(TIMER2_COMP_vect)
{
static uint16_t i=0;
if(sr<=i) PORTC &= ~(1<<PC5); else PORTC |= (1<<PC5);
i++;
if(i>999) i = 0;
}powiem więcej, na oscylu bardzo ładnie widać jak działa ten PWM więc o co tu może chodzić ???