Skocz do zawartości

Konfiguracja PWM - zmiana (liczby) wejść


Tomy89

Pomocna odpowiedź

Witam,

Dopiero zaczynam przygodę z ARM oraz językiem C, dlatego zakupiłem zestaw ZL32ARM oraz książkę "Mikrokontrolery LPC 1100...".

Od dłuższego czasu staram się opanować tajne linijki kodu z książki generującego PWM, który jest bardzo obszerny. Posiłkuję się również kodem zawartym w kursie na Forbocie. Męczę się już kilka ładnych dni, jak zmienić ilość wyjść PWM czy zmienić ich porty.

Na przykład jak na podstawie poniższego kodu, który generuje sygnał PWM na nóżkach PIO0_9 oraz PIO0_10, wygenerować sygnał dodatkowo na nóżkach PIO0_2 oraz PIO0_8?

Ewentualnie w ogóle zmienić port?

#define _BV(x) 	(1<<(x))
#define PWM_PERIOD	48000

volatile uint32_t global_timer = 0;

void SysTick_Handler(void)
{
global_timer++;
}

void TIMER16_0_IRQHandler(void)
{
LPC_TMR16B0->IR = 0x1f; // clear interrupt flag
}

void delay(uint32_t time)
{
uint32_t start = global_timer;
while (global_timer < start + time);
}

void pwm_set(int32_t l_proc, int32_t r_proc)
{
LPC_TMR16B0->MR1 = PWM_PERIOD*(100-l_proc)/100;
LPC_TMR16B0->MR2 = PWM_PERIOD*(100-r_proc)/100;
}

int main(void)
{
LPC_GPIO0->DIR |= LED_1_PIN|LED_2_PIN;
LPC_GPIO2->DIR |= 0x80;

SysTick_Config(480000); // 10ms

LPC_SYSCON->SYSAHBCLKCTRL |= 0x80; // CT16B0 clock enable
LPC_TMR16B0->TCR = 2; // timer reset
LPC_TMR16B0->MCR = 3; // reset and interrupt on MR0
LPC_TMR16B0->MR0 = PWM_PERIOD; // 1ms
LPC_TMR16B0->MR1 = PWM_PERIOD;
LPC_TMR16B0->MR2 = PWM_PERIOD;
LPC_TMR16B0->PWMC = 0x06;
LPC_TMR16B0->PR = 0; // prescaler 1
LPC_TMR16B0->TCR = 1; // timer enable
NVIC_EnableIRQ(TIMER_16_0_IRQn); // interrupt enable

LPC_IOCON->PIO0_9 = 0x02;
LPC_IOCON->SWCLK_PIO0_10 = 0x03;

pwm_set(25, 80);

Domyślam się że odpowiadają za to linijki:

LPC_TMR16B0->PWMC = 0x06;

oraz:

LPC_IOCON->PIO0_9 = 0x02;
LPC_IOCON->SWCLK_PIO0_10 = 0x03;

Proszę o pomoc, bo już załamuję ręce jak się za to zabieram 🙁

Link do komentarza
Share on other sites

Proponuję przejrzeć dokładnie dokumentacje od procesora tzn. UM10398 (UserManual) oraz LPC11xx Datasheet. A dowiesz się z nich że na PIO0_2 nie da się wygenerować sprzętowego PWM gdyż pin ten nie posiada takiej funkcji. Masz książkę i coś wydaje mi się że nawet nie przeczytałeś całego rozdziału o licznikach w którym zawarta jest informacja podobnie jak w Manualu że PWM można generować z nóżek oznaczonych jako MATx

LPC_IOCON->PIO0_9 = 0x02; 
LPC_IOCON->SWCLK_PIO0_10 = 0x03;

Tab 79 i 80. strona 78 UserManual (UM10398) - jest to wybór funkcji pinu

LPC_TMR16B0->PWMC = 0x06;

Tab 229. strona 263-264 UserManual (UM10398) - wybór aktywnych kanałów PWM timera CT16B0

Te informacje plus książka którą posiadasz powinna wystarczyć do opanowania PWM.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dzięki za wskazówki, bez nich naprawdę bym sobie nie poradził. Trochę poszukałem i teraz już rozumiem skąd to wszystko się bierze. Naprawdę ciężko jest mi się przesiąść z wygodnych AVR i Bascoma.

W celu "uzupełnienia internetu" wrzucę konfigurację Timerów 32 bitowych pod LPC1114 dla płytki ZL32ARM. Może komuś się przyda.

#define PWM_PERIOD	(48000-1)

void TIMER32_1_IRQHandler(void)
{
LPC_TMR32B1->IR = 0x1f; // clear interrupt flag
}

void TIMER32_0_IRQHandler(void)
{
LPC_TMR32B0->IR = 0x1f; // clear interrupt flag
}

void pwm_set(int32_t p_p, int32_t p_l, int32_t t_p, int32_t t_l)
{
LPC_TMR32B1->MR1 = PWM_PERIOD*(100-p_p)/100;
LPC_TMR32B1->MR2 = PWM_PERIOD*(100-p_l)/100;
LPC_TMR32B1->MR3 = PWM_PERIOD*(100-t_p)/100;
LPC_TMR32B0->MR1 = PWM_PERIOD*(100-t_l)/100;
}

int main(void)
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10) | (1<<9); 
LPC_TMR32B1->PR = 0; 
LPC_TMR32B1->MR0 = 48000-1; 
LPC_TMR32B1->MCR = (1<<0) | (1<<1); 
NVIC_EnableIRQ(TIMER_32_1_IRQn); 

LPC_TMR32B0->PR = 0; 
LPC_TMR32B0->MR0 = 48000-1; 
LPC_TMR32B0->MCR = (1<<0) | (1<<1); 
NVIC_EnableIRQ(TIMER_32_0_IRQn); 

LPC_IOCON->R_PIO1_2 = 0x03;
LPC_IOCON->SWDIO_PIO1_3 = 0x03;
LPC_IOCON->PIO1_4 = 0x02;
LPC_IOCON->PIO1_7 = 0x02;

LPC_TMR32B1->PWMC = (1<<1) | (1<<2) | (1<<3);
LPC_TMR32B0->PWMC = (1<<1);

LPC_TMR32B1->TCR = 2; 
LPC_TMR32B1->TCR = 1; 

LPC_TMR32B0->TCR = 2; 
LPC_TMR32B0->TCR = 1; 

 pwm_set(15, 25, 50, 75);
}

Nie chciałbym zakładać nowego tematu, ale obecnie męczę się z obsługą funkcji trygonometrycznych. Po dodaniu do projektu math.h wyskakuje mi error:

User\math.h(18): error:  #5: cannot open source input file "crtdefs.h": No such file or directory

Przejrzałem plik math.h i jest tam odwołanie właśnie do tego pliku...Może mam niewłaściwy plik math.h ? w internecie również nie znalazłem rozwiązania...

Link do komentarza
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.