cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401RE Board PWM doesn't work on this port

CMcC.1
Associate II

Hi everyone

I have an STM32F401RE board and I have an LED from pin PB6 to GND.

In the same project that this snippet code below comes from I have a PWM running on PA5 pin and it is blinking.

I have been at this all night and I can't figure out why PB6 is not blinking with the PWM. Here is the code. I am using Timer5 and as far as I know the AFR[0] is set correctly.

I hope anybody can see something wrong cause if not then I really don't know what to do : /

Also another question is.. if I want to start and stop the PWM output on that pin instantly and on a regular basis what would be the best way to do so? Disable the PWM or reset the PORT MODE to something else?

Thanks

void step_init(){
	RCC->AHB1ENR |= (1 << 2);  //Enable clock access to port B
 
	GPIOB->AFR[0] |= (1<<25); //Set PB6 for TIM5
	GPIOB->MODER |= (1<<13); //Sets oub PB6 for alternate functions
	//Timer Setup
 
	RCC->APB1ENR |= (1<<3); //Enables Timer5
	TIM5->PSC = 1600-1; //Prescaker of 1600
	TIM5->ARR = 10000; //Reload at 10000 counts
	TIM5->CNT = 0; //
	TIM5->CCMR1 = 0b1100100; //OC1M PWM Mode1 and Output compare 1 preload enable
	//TIM5->CCMR1 = 0x0060; // Enable PWM mode //1100000
	TIM5->CCER |= 1; //Enable PWM ch1
	TIM5->CCR1 = 5000; //50%DC
	TIM5->CR1 |= 1; //Enable
}

5 REPLIES 5
TDK
Guru

You need to wait a few cycles between enabling the clock and actually using the peripheral. It's possible that is causing the issue.

Best way to start/stop PWM would be to start/stop the timer, IMO. Set/clear the CR1_EN bit, and reset CNT to 0 if needed.

If you feel a post has answered your question, please click "Accept as Solution".

> RCC->AHB1ENR |= (1 << 2); //Enable clock access to port B

That enables GPIOC and not GPIOB.

Also, there's no TIM5 channel on PB6; there is TIM4_CH1 at AF2 - see Alternate function mapping table in Datasheet.

You might want to use the symbols defined in the CMSIS-mandated device header (you are using them anyway, RCC, TIM5 etc. come from that header too).

As TDK said, you may want to make a delay between enabling clock to a peripheral and using that peripheral, see Delay after an RCC peripheral clock enabling erratum; tht time best to be utilized for enabling other clocks:

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;  // enable GPIOB clock
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;  // enable TIM4 clock
GPIOB->AFR[0] |= 2 << GPIO_AFRL_AFSEL6_Pos;   // set PB6 for AF2  = TIM4_CH1
GPIOB->MODER |= 0b10 << GPIO_MODER_MODE6_Pos;   // set PB6 to AF
etc.

The preload bit in TIMx_CCMRx is bit 3, not bit 2:

TIM4->CCMR1 = 0
  | (0b00 << TIM_CCMR1_CC1S_Pos)  // set CH1 to Compare
  | (0b110 << TIM_CCMR1_OC1M_Pos)  // set CH1 to PWM1
  | TIM_CCMR1_OC1PE  // enable preload for CH1
;

Note, that the value you've set into CCR1 gets active only after the first period (which is also shorter due to PSC being implicitly preloaded, too)

JW

CMcC.1
Associate II

Thanks allot for the input.

I just want to try bare metal before I jump into the MCU Specific headers etc.

I will eventually get there of course.

I somehow missed that its set to TIM5 and not 4.

Thanks it is working now.

Thanks allot for the input.

I just want to try bare metal before I jump into the MCU Specific headers etc.

I will eventually get there of course.

I somehow missed that its set to TIM5 and not 4.

Thanks it is working now.

CMcC.1
Associate II

Ok I followed your advice and it works great now thanks allot!