2025-02-18 10:18 AM
I am working with an STM32F303 and trying to generate a PWM signal on TIM3, Channel 1 (PA6). Everything seems to be correctly configured (verified in the debugger – registers appear correct), but there is no PWM signal on PA6. The function responsible for clock configuration worked correctly in the case of USART. In the IRQ handler, the flag registers are set correctly, which I verified using a breakpoint. I would appreciate any help in identifying the possible cause of why the PWM is not activating.
void configureTIMER3(void)
{
//PA6:D12
RCC -> APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->PSC = 711; //72mghz
TIM3->ARR = 99; //PA6
}
void clock_config(void)
{
RCC->CR |= RCC_CR_HSION;
while (!(RCC->CR & RCC_CR_HSIRDY));
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
// FLASH -> ACR = FLASH_ACR_PRFTBE | FLASH_ACR_PRFTBS | FLASH_ACR_LATENCY_2;
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
RCC->CFGR|= RCC_CFGR_PPRE1_DIV2;
//PPL SOURCE MUX
// RCC->CFGR |= RCC_CFGR_PLLMUL9;
RCC->CFGR |= (0x7 << RCC_CFGR_PLLMUL_Pos);
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while(!(RCC->CFGR & RCC_CFGR_SWS));
}
void TIM3_start(void)
{
TIM3->CNT=0;
TIM3->CR1|= TIM_CR1_CEN;
}
void interuptTIM3(void)
{
TIM3 -> DIER |= TIM_DIER_UIE;
TIM3 -> DIER |= TIM_DIER_CC1IE;
NVIC_SetPriority(TIM3_IRQn, 0);
NVIC_EnableIRQ(TIM3_IRQn);
}
void TIM3_IRQHandler(void)
{
if(TIM3 -> SR & TIM_SR_UIF)
{
TIM3 -> SR &= ~(TIM_SR_UIF);
}
if(TIM3 -> SR & TIM_SR_CC1IF)
{
TIM3 -> SR &= ~(TIM_SR_CC1IF);
}
}
void pwmconfigration(void)
{
TIM3 -> CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;
TIM3 -> CCMR1 |= TIM_CCMR1_OC1PE;
TIM3 -> CCR1 = 49;
TIM3->CR1 |= TIM_CR1_ARPE;
TIM3 -> CCER |= TIM_CCER_CC1E;
}
void configPWMPA6(void)
{
GPIOA-> MODER |= GPIO_MODER_MODER6_1;
GPIOA->AFR[0] |= (0x2 << GPIO_AFRL_AFRL2_Pos);
}
int main(void)
{
//SysTick_Config((72000000/ 1000));
//configPWMPA6();
clock_config();
configureTIMER3();
pwmconfigration();
configPWMPA6();
TIM3_start();
interuptTIM3();
//1s = 72 000 000
// 0,001 = x
/* Loop forever */
while(1)
{
}
}
Solved! Go to Solution.
2025-02-18 10:57 AM - edited 2025-02-18 11:00 AM
What hardware is this?
Blinky works?
Did you try continuity from given pin to the point you are measuring, e.g. by setting given pin to GPIO Out and toggling it? Is there any other hardware connected to this pin?
> registers appear correct
Show - both TIM and GPIO.
GPIOA->AFR[0] |= (0x2 << GPIO_AFRL_AFRL2_Pos);
Why GPIO_AFRL_AFRL2_Pos for PA6?
JW
PS. Not the primary issue here, but don't RMW status (here TIMx_SR) flags.
2025-02-18 10:57 AM - edited 2025-02-18 11:00 AM
What hardware is this?
Blinky works?
Did you try continuity from given pin to the point you are measuring, e.g. by setting given pin to GPIO Out and toggling it? Is there any other hardware connected to this pin?
> registers appear correct
Show - both TIM and GPIO.
GPIOA->AFR[0] |= (0x2 << GPIO_AFRL_AFRL2_Pos);
Why GPIO_AFRL_AFRL2_Pos for PA6?
JW
PS. Not the primary issue here, but don't RMW status (here TIMx_SR) flags.
2025-02-18 11:32 AM
A diode is connected to the timer’s output pin. I tested everything using HAL, and it worked fine. In the main loop, I changed the duty cycle to turn the diode on and off.
In the future, I plan to control a stepper motor, and I want to build my career in embedded systems, which is why I am programming this using registers.
In the datasheet of my microcontroller (which is on the Nucleo-F303RE board, "stm32f303xe.h"), it is specified that AF2 should be set to enable the timer. In Cube, the alternate function is also set to push-pull. Initially, I configured the pin as an output.
2025-02-18 12:24 PM - edited 2025-02-18 12:25 PM
I think you missed the part of @waclawek.jan's post where he noted you are setting AF for pin PA2, not PA6. This error is confirmed in your register values.
> Why GPIO_AFRL_AFRL2_Pos for PA6?
2025-02-18 12:54 PM
@TDK Yes, what a *** mistake! I missed that, everything works fine.