Skocz do zawartości

[C][STM32] Sterowanie serwem PWM


ziger

Pomocna odpowiedź

Witam, raczkuje w programowaniu stm32 (STM32F100RB) i próbuje posterować trochę serwem. Niestety nie działa tak jak tego oczekuje.

#include "stm32f10x.h"

#include "antilib_gpio.h"

#define PIN_GPIO GPIOC

#define PIN_7 7

int main(void)

{

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;

RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

#if (PIN_7 > 7)

PIN_GPIO->CRH = (PIN_GPIO->CRH & CONFMASKH(PIN_7)) | GPIOPINCONFH(PIN_7,
GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));

#else

PIN_GPIO->CRL = (PIN_GPIO->CRL & CONFMASKL(PIN_7)) | GPIOPINCONFL(PIN_7,
GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));

#endif

AFIO->MAPR = AFIO_MAPR_TIM3_REMAP; // Pełny remap TIM3

TIM3->PSC = 23990; // Ustawienie prescalera na 24000 (PSC + 1)

TIM3->ARR = 20; // 20 ms cykl PWM

TIM3->CCR2 = 1; // Pozycja początkowa serwa 1 ms

TIM3->CCMR1 = TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // Załączenie PWM na kanale 2

TIM3->CCER = TIM_CCER_CC2E; //załączenie porównania kanału 2

TIM3->CR1 = TIM_CR1_CEN; // Załączenie timera

Gdy ustawie od 1-1.9 ms na sterowaniu serwa, wychyla się w lewo nie maksymalnie ale cały czas na tą samą pozycje oraz gdy ustawie 2 ms to wychyla sie w prawo także nie maksymalnie. Podłączone mam zasilanie serwa do uC 3V3 bo gdy podłączam na 5V to szaleje serwo i się zawiesza płytka. Załączam również datasheet mojego serwa.

http://datasheet.sparkgo.com.br/SG90Servo.pdf

Link do komentarza
Share on other sites

Peryferia procesora wliczając w to timery posługują się wyłącznie liczbami całkowitymi. Ciekaw jestem jak wpisywałeś do timera 1.4ms?

Jeżeli poprzez prescaler tak ustawiłeś timer by zliczał pełne milisekundy (na co wskazuje okres = 20) to jak chcesz by odmierzył i wygenerował impuls 1.5ms? Przecież przy obecnych ustawieniach czas jest dla tego timera skwantowany do 1ms. Może odmierzyć tylko 1ms, 2ms, 3ms itd. Chcąc mieć impulsy o "ciągłych" czasach między 1 a 2ms musisz zwiększyć rozdzielczość czasową. Ustaw timer tak, by zliczał np. z częstotliwością 1MHz tj z okresem zegara 1us lub innym w tych okolicach. Wtedy okres wynosi 20000 a czas 1ms to 1000. Wpisując 1400 dostaniesz te swoje 1.4ms a w razie potrzeby jesteś w stanie wygenerować impuls o praktycznie dowolnej długości pośredniej np. 1.928ms.

Typowe serwo porusza się po dość krótkiej trasie. Zmiana długości PPM o 0.5ms w górę i w dół od środkowego 1.5ms odchyla je zwykle nie więcej niż o 40-60° od położenia neutralnego. Biorąc pod uwagę, że karmiłeś je impulsami wyłącznie 1 i 2ms (wszystkie inne wpisywane liczby były konwertowane na całkowite przez obcięcie części ułamkowej) to moim zdaniem Twoje serwo zachowuje się prawidłowo.

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.