/* p11_5.c Comparison between edge-aligned and center-aligned PWM * * In this program, TIM16 Ch1 is configured as edge-aligned PWM with * output on PB8 pin and TIM3 Ch1 is configured as center-aligned PWM * with output on PA6 pin for comparison. * * You will find two differences between these two PWM generation: * 1. For edge-aligned PWM, the counter counts from 0 to the value * of ARR then it takes one clock cycle to reset to 0. So to * count 1000 clock cycles, the ARR should be loaded with 999. * For center-aligned PWM, the counter counts up from 0 to the * value of ARR then immediately counts down back to 0. So to * count 1000 clock cycles, the ARR should be loaded with 500. * 2. The output of PWM is active when the counter value is below * the value of CCRx register. For edge-aligned PWM, the output * is active counting up from 0 and turned off when it reaches * the value of CCRx. For an output pulse of 300 clock cycles, * 300 is loaded in the CCRx register. For center-aligned PWM, * the output is active when counting down below the value of * CCRx until it is counting up to the value of CCRx. For an * output of 300 cycles, 150 should be loaded in the CCRx. * * This program was tested with Keil uVision v5.23 with DFP v2.0.0. */ #include "stm32f0xx.h" void TIM16_edge_aligned(void); void TIM3_center_aligned(void); int main(void) { TIM16_edge_aligned(); TIM3_center_aligned(); while(1) { } } void TIM16_edge_aligned(void) { RCC->AHBENR |= 0x00040000; /* enable GPIOB clock */ GPIOB->AFR[1] |= 0x00000002; /* PB8 pin for TIM16 channel N1 */ GPIOB->MODER &= ~0x00030000; GPIOB->MODER |= 0x00020000; /* setup TIM16 */ RCC->APB2ENR |= 0x00020000; /* enable TIM16 clock */ TIM16->PSC = 8 - 1; /* divided by 8 */ TIM16->ARR = 1000 - 1; /* divided by 2000 */ TIM16->CNT = 0; TIM16->CCMR1 = 0x0060; /* PWM mode */ TIM16->CCER = 1; /* enable PWM Ch1 */ TIM16->CCR1 = 300; /* pulse width 300 */ TIM16->BDTR |= 0x8000; /* enable output */ TIM16->CR1 = 0x01; /* edge-aligned enable timer */ } void TIM3_center_aligned(void) { RCC->AHBENR |= 0x00020000; /* enable GPIOA clock */ GPIOA->AFR[0] |= 0x01000000; /* PA6 pin for TIM3 channel 1 */ GPIOA->MODER &= ~0x00003000; GPIOA->MODER |= 0x00002000; /* setup TIM3 */ RCC->APB1ENR |= 0x00000002; /* enable TIM3 clock */ TIM3->PSC = 8 - 1; /* divided by 8 */ TIM3->ARR = 500; /* divided by 1000 */ TIM3->CNT = 0; TIM3->CCMR1 = 0x0060; /* PWM mode */ TIM3->CCER = 1; /* enable PWM Ch1 */ TIM3->CCR1 = 150; /* pulse width 300 */ TIM3->CR1 = 0x21; /* center-aligned, enable timer */ }