Skip to main content
P.Santos
Associate
April 4, 2019
Solved

PWM low level configuration.

  • April 4, 2019
  • 3 replies
  • 1522 views

Hi, I am new to microcontroller programming and I am having some trouble making a PWM wave with a STM32F767ZI Nucleo board. I was able to make a led blink with interrupts and now I am trying to fade it in and out, but for some reason I can't. While debuging and can se that at the moment the code executes:

TIM4->CCER |= 0x10;					//Enables the result of CC on the corresponding pin

The blue led immediately ligghts up with full power, even though the counter has not been started yet. The full code is shown bellow. Has anyone any idea as to why this is happening, I have read it through The technical reference manual countless times and the General purpose timer cookbook

#include "stm32f767xx.h"
 
void RCC_Config(void);
void GPIOB_Init(void);
void Config_TIM4(void);
 
int main(void){
 
	RCC_Config();
 
	GPIOB_Init();
 
	Config_TIM4();
 
	while(1){
 
			}
}
 
void GPIOB_Init(){
	GPIOB->MODER |= 0x8000;			
//Sets PB7 as output (Blue led)
	
 GPIOB->AFR[0] |= 0x20000000;		
//Sets alternate function on PB7 to 2 TIM4_Ch2
}
 
void RCC_Config(){
	int a;
 
	RCC->AHB1ENR |= 0x02;				
//Enables clock for PORTB
 
	RCC->APB1ENR |= 0x04;				
//Enables clock for TIM4
 
	a = RCC->AHB1ENR;					
//Small delay
}
 
 
void Config_TIM4(void){
/*	Setting frequency:
 *
 *	PWM frequency 	= 1KHz
 *	PWM Steps		= 500 OR 	0x1F4
 *
 *	Counter_Freq	= 1KHz * 500
 *	Counter_Freq	= 500KHz
 *
 *	Prescaler 		= (16MHz / 500KHz)-1
 *	Prescaler		= 31 OR 0x1F
 *
 *	DutyCycle 		= 50%
 *	TIM4->CCR1 		= 50% * 500
 *	TIM4->CCR1		= 250 OR 0xFA
 *
 * */
	TIM4->ARR = 0x1F4;	
//PWM Steps = 500
 
	TIM4->PSC = 0x1F;					
//Prescaler = 31
 
	TIM4->CCMR1 |= 0x00007000;			
//Sets the PWM mode to 2 (OC2M = 0111) bits 14, 13 and 12
 
	TIM4->CCER |= 0x10;					
//Enables the result of CC on the corresponding pin
 
	TIM4->CCR1 = (0xFA);				
//Sets the duty cycle, in this case approximately 50%
 
	TIM4->CR1 |= 0x05;					
//Enables the counter
 
}

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

> TIM4->CCR1 = (0xFA);

For CH2, you want TIM4->CCR2.

If in doubt, it helps to read out the registers content in the debugger and check against expectations.

JW

3 replies

S.Ma
Principal
April 4, 2019

I share my LED dimming file which includes blinking also, using systick.

Don't copy paste the code is not yet ready for this, only to grab ideas.

(can only attach one file, thanks salesforce!)

waclawek.jan
waclawek.janBest answer
Super User
April 4, 2019

> TIM4->CCR1 = (0xFA);

For CH2, you want TIM4->CCR2.

If in doubt, it helps to read out the registers content in the debugger and check against expectations.

JW

P.Santos
P.SantosAuthor
Associate
April 4, 2019

Oh my god.... I can't believe this was the mistake....... Indeed TIM4->CCR2 is the correct parameter to address and now it works. Thank you so much. I spent the whole day trying to figure this out and was something like that. Thanks again.