2022-10-02 08:44 AM
I copied the code for my timer setup, and the plan was every time the capture compare was equal the CC1IF would set and I toggle the LED in the IRQHandler; however, upon loading in the code it seems the IRQHandler only gets called once to turn the LED on, and then never again. The clock is set to the default of 4MHz
void timer_config(){
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN; // Enable TIMER 2 clock
TIM2->CR1 &= ~TIM_CR1_DIR; // Counting direction: 0 = up-counting, 1 = down-counting
TIM2->PSC = 3; // Prescaler = 3 // 4MHz/(1+PSC) = 4MHz/4 = 1MHz //Target PWM frequency = 100Hz // ARR=1MHz /100 Hz-1=9999
TIM2->ARR = 9999; // Auto-reload: Upcouting (0..ARR),Downcouting (ARR..0)
TIM2->CCMR1 &= ~TIM_CCMR1_OC1M; // Clear ouput compare mode bits for channel 1
TIM2->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // OC1M = 110 for PWM Mode 1 output on ch1
TIM2->CCMR1 |= TIM_CCMR1_OC1PE; // Output 1 preload enable
TIM2->CCER &= ~TIM_CCER_CC1NP; // Select output polarity: 0 = active high, 1 = active low // select active high
TIM2->CCER |= TIM_CCER_CC1NE; // Enable output for ch1N: 0 = Disable, 1 = Enable
TIM2->BDTR |= TIM_BDTR_MOE; // Main output enable (MOE): 0 = Disable, 1 = Enable
TIM2->DIER |= TIM_DIER_UDE; // Enable DMA request on channel 1
TIM2->CCR1 = TIM2->ARR/2; // Init duty cycle to 50% ARR/2
TIM2->SR &= ~TIM_SR_UIF;
TIM2->CCMR1 &= ~TIM_CCMR1_IC1F;
NVIC_SetPriority(TIM2_IRQn,2);
TIM2->DIER |= 0x02; // Enable Timer Interrupts
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1 |= TIM_CR1_CEN; // Enable Counter
}
void TIM2_IRQHandler(void){
if(TIM2->SR & TIM_SR_UIF){
overflowCount++;
TIM2->SR &= ~TIM_SR_UIF; // Disable the CC1 Interrupt Flag
//GPIOA->ODR ^= (1 << 5); // Toggle PA5
}
if(TIM2->SR & TIM_SR_CC1IF){
TIM2->SR &= ~TIM_SR_CC1IF; // Disable the CC1 Interrupt Flag
TIM2->SR &= ~TIM_SR_CC1OF; // Disable the CC1 Interrupt Flag
GPIOA->ODR ^= (1 << 5); // Toggle PA5
}
//GPIOA->ODR ^= (1 << 5); // Toggle PA5
}
Solved! Go to Solution.
2022-10-02 01:13 PM
I believe my problem with this was I only toggled LED when I was getting interrupts from the capture/compare on channel 1 but I also did not account for the LED toggle I would have to do at an overflow/underflow.
So changing the duty cycle was not actually doing anything and the LED just appeared to always be on even though it was blinking quite fast.
KB
2022-10-02 12:20 PM
How do you observe this? 50Hz is too fast to be seen by naked eye. Use oscilloscope/LA, or increase TIM2_ARR significantly.
If still problems, read out TIM and relevant GPIO registers content using debugger and check/post.
Also, probably not the problem here, but don't use RMW to clear TIM_SR flags.
JW
2022-10-02 12:43 PM
The idea was to set CCR1 to different values to change the duty cycle. For instance, CCR1 = 9998 I would expect the LED to be off for a considerable amount of time but it is still just always on and the light never gets dimmer.
KB
2022-10-02 01:13 PM
I believe my problem with this was I only toggled LED when I was getting interrupts from the capture/compare on channel 1 but I also did not account for the LED toggle I would have to do at an overflow/underflow.
So changing the duty cycle was not actually doing anything and the LED just appeared to always be on even though it was blinking quite fast.
KB