Skocz do zawartości

[C][STM32] Sterowanie serwem PWM


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 to post
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 to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.