Ten post chciałbym poświęcić na przygotowanie programu pozwalającego na wygenerowanie sygnału PWM programowo. Pozwoli to na generację tego sygnału z każdej dostępnej nogi mikrokontrolera. Do poprawnego ustawienia sygnału będzie wykorzystywany licznik Systick.
Program demonstracyjny będzie miał za zadanie ustawienie odpowiedniego sygnału PWM na każdym z dostępnych diod wbudowanych.
W przykładzie sygnał będzie generowany razem z wywołaniem obsługi przerwania od Systicka, czyli co 1ms.
Poniżej cześć inicjalizacji Systicka wraz z delayem.
PWM programowy opiera się na zastosowaniu odpowiedniego czasu załączenia i wyłączenia poprzez dobór wartości w pętlach, co pozwoli na sterowanie częstotliwości generowanego sygnału.
Funkcja działa następująca, w pierwszej kolejności sprawdzane jest czy została przekroczona maksymalna wartość zmiennej PWM_PART_2, gdy została to zmienna zostaje zresetowana i na wybranym pinie ustawiany jest stan wysoki, gdy natomiast wartość PWM_PART_1 osiągnie wartość określoną w deklaracji, to jej stan jest zmieniany z wysokiego na niski, dalej gdy zmienna znajduje się pomiędzy wartościami zdefiniowanymi to licznik zostaje zwiększony, podczas gdy stan niski jest ciągle utrzymywany na linii. Dzięki temu podczas zmiany wartości PWM_PART_1 oraz PWM_PART_2 można otrzymać różne rodzaje wypełnienia oraz częstotliwości.
Zaletą zdecydowanie jest możliwość wygenerowania sygnału na każdym wyprowadzeniu mikrokontrolera.
Poniżej program pozwalający na generowanie różnych wartości wypełnienia z wykorzystaniem standardowo jednej z diod wbudowanych.
Aby tego dokonać należy lekko zmodyfikować funkcje zgodnie z poniższym wzorem:
Program
Program demonstracyjny będzie miał za zadanie ustawienie odpowiedniego sygnału PWM na każdym z dostępnych diod wbudowanych.
W przykładzie sygnał będzie generowany razem z wywołaniem obsługi przerwania od Systicka, czyli co 1ms.
Poniżej cześć inicjalizacji Systicka wraz z delayem.
- volatile uint16_t time_delay = 0;
- uint8_t SYSTICK_ON()
- {
- if (SysTick_Config(SystemCoreClock / 1000))
- { while (1); }
- }
- void delay_ms(uint16_t delay)
- {
- time_delay = delay;
- while(time_delay) { }
- }
PWM programowy opiera się na zastosowaniu odpowiedniego czasu załączenia i wyłączenia poprzez dobór wartości w pętlach, co pozwoli na sterowanie częstotliwości generowanego sygnału.
- uint16_t PWM_LICZNIK = 0;
- uint16_t PWM_PART_1 = 10;
- uint16_t PWM_PART_2 = 25;
- void PWM_GENERATE(void)
- {
- if(PWM_LICZNIK >= PWM_PART_2)
- {
- PWM_LICZNIK = 0;
- GPIOD->BSRRL = GPIO_Pin_15;
- }
- else if(PWM_LICZNIK == PWM_PART_1)
- {
- PWM_LICZNIK++;
- GPIOD->BSRRH = GPIO_Pin_15;
- }
- else { PWM_LICZNIK++; }
- }
Funkcja działa następująca, w pierwszej kolejności sprawdzane jest czy została przekroczona maksymalna wartość zmiennej PWM_PART_2, gdy została to zmienna zostaje zresetowana i na wybranym pinie ustawiany jest stan wysoki, gdy natomiast wartość PWM_PART_1 osiągnie wartość określoną w deklaracji, to jej stan jest zmieniany z wysokiego na niski, dalej gdy zmienna znajduje się pomiędzy wartościami zdefiniowanymi to licznik zostaje zwiększony, podczas gdy stan niski jest ciągle utrzymywany na linii. Dzięki temu podczas zmiany wartości PWM_PART_1 oraz PWM_PART_2 można otrzymać różne rodzaje wypełnienia oraz częstotliwości.
Zaletą zdecydowanie jest możliwość wygenerowania sygnału na każdym wyprowadzeniu mikrokontrolera.
Poniżej program pozwalający na generowanie różnych wartości wypełnienia z wykorzystaniem standardowo jednej z diod wbudowanych.
Aby tego dokonać należy lekko zmodyfikować funkcje zgodnie z poniższym wzorem:
- uint16_t PWM_LICZNIK = 0;
- volatile uint16_t PWM_PART_1 = 0;
- const uint16_t PWM_PART_2 = 100;
- void delay_simple(int time)
- {
- int i=0;
- for(i=0; i<=time; i++) { __NOP(); }
- }
- void PWM_GENERATE(void)
- {
- if(PWM_LICZNIK >= PWM_PART_2)
- {
- PWM_LICZNIK = 0;
- GPIOD->BSRRL = GPIO_Pin_15;
- PWM_A++;
- }
- else if(PWM_Counter == PWM_PART_1)
- {
- PWM_LICZNIK++;
- PIOD->BSRRH = GPIO_Pin_15;
- }
- else
- { PWM_LICZNIK++; }
- if(PWM_A > PWM_B) { PWM_A = 0; }
- delay_simple(100);
- }