Skip to main content
Explorer
May 4, 2023
Solved

PWM Channels 3 and 4 of TIM2 not working on STM32L053

  • May 4, 2023
  • 9 replies
  • 3772 views

As per the title: I am using Timer 2 for a PWM. Channel 1 and 2 work just fine, but Channel 3 and 4 won't output anything. Created the project with CubeMX. Tried enabling all 4 channels with all the same values except pulse (CCR) and probed the output-pins. The only user code is enabling the PWM with HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1), ..._2), ..._3) and ..._4).

In the created code the Config-Struct is created, Channel 1 is initialized, only the pulse variable is changed, Channel 2 is initialized, etc.

The only difference between Channel 1 and 2 and Channel 3 and 4 I found is the CCMR1 / CCRM2 register.

Has anyone an idea where this error might stem from?

    This topic has been closed for replies.
    Best answer by waclawek.jan

    On Nucleo64, PA2 and PA3 are connected through solder bridges to the onboard STLink's VCP Rx and Rx. See Nucleo manual and schematics.

    I guess CubeMX caters for this connection. I don't use Cube/CubeMX and I generally recommend against using it.

    JW

    9 replies

    Super User
    May 4, 2023

    Read out and check/post content of TIM and relevant GPIO registers.

    What hardware? Are you sure the pins for TIM2_CH3/CH4 are properly connected? You can check them by setting them to GPIO output and toggling "manually".

    JW

    EPrüß.1Author
    Explorer
    May 5, 2023

    Didn't check the GPIO registers yesterday. TIM registers look fine, GPIOA registers are not. In MODER the bits for all channels are set correctly to 0b10 (alternate function). The other registers have PA2 and PA3 set to the wrong type, speed, etc.. I don't know why that is as all GPIOs are initialized with the same arguements in HAL_TIM_MspPostInit and there isn't a second function in hal_msp that could set it to different values. Also all GPIOs are initialized with low speed, but Ch1 has high speed set in OSPEEDR. Similar with OTYPER, PUPDR.

    My hardware is a NUCLEO-L053R9 board.

    EPrüß.1Author
    Explorer
    May 5, 2023

    Found my problem: The solder bridges on the bottom of the board.

    GPOI registers were fine, just a bit confusing to read as the binary cuts off leading zeros.

    To connect PA2 and PA3 to the 2.54mm pins, SB62 and SB63 must be bridged.

    Super User
    May 5, 2023

    On Nucleo64, PA2 and PA3 are connected through solder bridges to the onboard STLink's VCP Rx and Rx. See Nucleo manual and schematics.

    I guess CubeMX caters for this connection. I don't use Cube/CubeMX and I generally recommend against using it.

    JW

    Graduate
    August 2, 2024

    Hey i wanted to ask that there are more bridges that are unslodered on my stm32f401re board do i need to solder them too like i am facing the same problem of channel 4 and channel 3 pwm output though ch1 and 2 are working correctly . also can u tell me more about like why these boards come with unsoldered bridges  as i am beginner.

    thank u 

    Super User
    August 2, 2024

    Check in UM1724 and in the schematics: you can find both on the Nucleo's web folder, one under Documentation and the other under CAD Resources tab.

    JW

    Graduate
    August 2, 2024

    Thanks 

     

    Graduate
    August 12, 2024

    Hey can u also tell me like i am implemeting usar1 on my stm32f401re baremetal and whenever i put this condition if ( USART2->SR & USART_SR_RXNE ) in the reception function i never enters the condition and it cant return the recieved data.

    also if i just recive data without any condition it works properly and i am also observing that the rxe bit in the sr register never sets .

    can u help me with this issue 

    this is  the code snipeet of reception code 

     

    volatile uint8_t Uart_Receive(int Uart_Module) {

    uint8_t receivedData = 0; // Variable to hold received data

     

    if (Uart_Module == 1) {

    // Check if data is received (RXNE flag set) for USART1

    //while( !( USART1->SR & RXE )){ // RXNE flag has a direct value of 0x20

    if ( USART2->SR & RXE ){

    receivedData = (uint8_t)USART1->DR; // Read received data

    return receivedData;

    }

    } else if (Uart_Module == 6) {

    // Check if data is received (RXNE flag set) for USART6

    while( !( USART6->SR & RXE )) { // RXNE flag has a direct value of 0x20

    receivedData = (uint8_t)USART6->DR; // Read received data

    return receivedData;

    }

    }

     

    return 0; // Return 0 if no data is received or invalid UART module

    }

    Super User
    August 12, 2024

    > i am implemeting usar1 on my stm32f401re baremetal and whenever i put this condition if ( USART2->SR & USART_SR_RXNE )

    So, USART1 or USART2?

    Also, in the code snippet, you have some RXE symbol, are you sure it's equal to USART_SR_RXNE?

    Also, if you observe the USART registers (namely USART_DR) in the debugger, it will clear the USART_SR.RXNE flag in the same way as if you read it from processor, so don't observe the USART registers in debugger during debugging.

    JW

    Graduate
    August 12, 2024

    yes rxe is same as the usart_sr_rxne i just forgot to format while asking .

    also i am using usart1 now 

    the problem i am facing if i am putting a delay of 10 ms before sending in arduino i am recieving correct data everytime but when i put not delay in transmission then whenever i reset the stm the data value changes in a particluar pattern then again keep on resseting fetches me the correct value i am sending from arduino.

     

    also when i am trying to send from the serial monitor i obsered then whenerver a new number i send the idle line flag sets and resets on its own what does it indicate . 

     

    and also can you please elaborate this more to me   

     "Also, if you observe the USART registers (namely USART_DR) in the debugger, it will clear the USART_SR.RXNE flag in the same way as if you read it from processor, so don't observe the USART registers in debugger during debugging."

     

     

    Super User
    August 12, 2024

    > when i put not delay in transmission then whenever i reset the stm the data value changes in a particluar pattern then again keep on resseting fetches me the correct value i am sending from arduino.

    I don't quite understand what do you mean by this.

    If you transmit a continuous stream of bytes towards the STM32 and you reset the STM32, it may start to receive in the middle of a byte, resulting in confused data. If this is a possibility in reality, your program has to cope with that, e.g. by putting data into frames, adding checksums, etc.

     

    > whenever a new number i send the idle line flag sets and resets on its own what does it indicate

    UART_SR.IDLE indicates, that there was some data transmitted and then there was at least one byte's of "idleness" (no transmission) on the line. As its description in RM says: It is cleared by a software sequence (a read to the USART_SR register followed by a read to the USART_DR register).

     

    > and also can you please elaborate this more to me

    > > "Also, if you observe the USART registers (namely USART_DR) in the debugger, it will clear the USART_SR.RXNE flag in the same way as if you read it from processor, so don't observe the USART registers in debugger during debugging."

    Debugger (the on-chip hardware which talks to the debugging program in PC) is part of the processor. The peripheral can't distinguish accesses from the debugger and from the processor (i.e. from the program). The UART_SR.RXNE bit is cleared, when UART_DR is read, and it does not matter, if the read was from the debugger or from the program.

    JW

    Graduate
    August 12, 2024

    Thank you so much for this explaination.

    but can you show me like the best way to recieve data as i want to recieve  a continous data frame from esp to stm32 without much error , so can u provide me a code snippet which i can refer to create my own recieve function for the usart1 reception of that type of data. on stm32f401re.

     

    Super User
    August 12, 2024

    I'm not writing code on request.

    JW

    Graduate
    August 12, 2024

    i dont want whole code just want a better approach or something to solve this problem,

    like jusr directly storing the dr register contents in a variable and observing it is not the correct way to receive Ig.