2017-08-08 10:47 AM
In my code for pwm on timer 2 in stm32F429, I have to use multiple channels (2 at a time). However only my channel 1 pin is giving pwm output. Please advise me what to do
void enable_gpio1()//setting pin 5 of port a for AF1 which corresponds to timer 2.
{ RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enables port A input output pins by setting the corresponding bit in advanced high performance bus 1 register. GPIOA ->MODER |= GPIO_MODER_MODER5_1; //Configures pin 5 for alternate function mode by setting the corresponding bit in the mode register GPIOA ->OTYPER &= ~(GPIO_OTYPER_OT_5); //Makes the output type as push-pull by resetting the corresponding bit in output type register. GPIOA ->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5_1;//Makes the output high speed. GPIOA ->PUPDR &= ~(GPIO_PUPDR_PUPDR5);//No pull up or pull down. GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20;//Sets the AF1 bit in the AFRL(AFR[0]) register which links AF1 to pin A5 }void enable_gpio2()//setting pin 2 of port a for AF1 which corresponds to timer 2.{ RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enables port A input output pins by setting the corresponding bit in advanced high performance bus 1 register. GPIOA ->MODER |= GPIO_MODER_MODER2_1; //Configures pin 5 for alternate function mode by setting the corresponding bit in the mode register GPIOA ->OTYPER &= ~(GPIO_OTYPER_OT_2); //Makes the output type as push-pull by resetting the corresponding bit in output type register. GPIOA ->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2_1;//Makes the output high speed. GPIOA ->PUPDR &= ~(GPIO_PUPDR_PUPDR2);//No pull up or pull down. GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20;//Sets the AF1 bit in the AFRL(AFR[0]) register which links AF1 to pin A5 }void generate_pwm1(int n){ TIM2 ->CCMR1 |= TIM_CCMR1_OC1M_2; TIM2 ->CCMR1 |= TIM_CCMR1_OC1M_1; TIM2 ->CCMR1 &= ~(TIM_CCMR1_OC1M_0);//Selects pwm mode 1 by writing 110 TIM2 ->CCMR1 |= TIM_CCMR1_OC1PE;// TIM2 ->CR1 |= TIM_CR1_ARPE;//Enables preload register TIM2 ->EGR |= TIM_EGR_UG;//Enables update event whenever cnt equals ccr. TIM2 ->CCER |= TIM_CCER_CC1P;//Sets the polarity of the pwm TIM2 ->CCER |= TIM_CCER_CC1E; TIM2 ->ARR = (int)n*40/250.0;//Sets the value for the auto reload register. TIM2 ->CCR1 = 1;//Sets the value for the ccr register. TIM2 ->CR1 |= TIM_CR1_CEN;//Starts the counter for timer 2.}void generate_pwm2(int n){ TIM2 ->CCMR2 |= TIM_CCMR2_OC3M_2; TIM2 ->CCMR2 |= TIM_CCMR2_OC3M_1; TIM2 ->CCMR2 &= ~(TIM_CCMR2_OC3M_0);//Selects pwm mode 1 by writing 110 TIM2 ->CCMR2 |= TIM_CCMR2_OC3PE;// TIM2 ->CR1 |= TIM_CR1_ARPE;//Enables preload register TIM2 ->EGR |= TIM_EGR_UG;//Enables update event whenever cnt equals ccr. TIM2 ->CCER |= TIM_CCER_CC3P;//Sets the polarity of the pwm TIM2 ->CCER |= TIM_CCER_CC3E; TIM2 ->ARR = (int)n*40/250.0;//Sets the value for the auto reload register. TIM2 ->CCR3 = 1;//Sets the value for the ccr register. TIM2 ->CR1 |= TIM_CR1_CEN;//Starts the counter for timer 2.}My channel 1 pwm is working but channel 3 is not. I have also included the code I have used to enable the gpio pins.
#timer2 #stm32 #pwmSolved! Go to Solution.
2017-08-08 05:02 PM
Hello again Daattavya.
In STM32F429-DISC board PA1 is connected to INT pin of MEMS that by default is keeped low
You have two choices. To init L3GD20 and to make INT1 open drain output .. or to use another AF pin for same channel PB3 Be aware also that PB3 is used as trace data pin . (not con. by default)
2017-08-08 11:03 AM
void enable_gpio2()//setting pin 2 of port a for AF1 which corresponds to timer 2.
...
GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20;//Sets the AF1 bit in the AFRL(AFR[0]) register which links AF1 to pin A5
it overwrites the previous setting of GPIOA->AFR[0]; and it does not set AF for pin 2.
JW
PS. Do you have a debugger? You could make these settings in the debugger, too; and you could also check them back.
2017-08-08 11:04 AM
Hello, which board are you use?
2017-08-08 11:05 AM
GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20;//Sets the AF1 bit in the AFRL(AFR[0]) register which links AF1 to pin A5
Don't do blind writes into registers that already have content in them, and make sure if you want to set pin 2 you don't configure pin 5
2017-08-08 02:33 PM
I made the change regarding the linking of alternate function with the GPIO pins. I am now using channel 1 and channel 2 so I have configured PA5 and PA1 using the following commands:
GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20; // Links pin 5 with AF1
GPIOA ->AFR[0] |= GPIO_AF1_TIM2<<4; // Links pin 1 with AF1
As I have to use multiple pwm channels with the same timer, I have used bitwise or( | ). This should ensure that pin 1 gets linked without affecting pin 5, right? However my code is still not working. Any suggestions?
void enable_gpio1()
{ RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA ->MODER |= GPIO_MODER_MODER5_1; GPIOA ->OTYPER &= ~(GPIO_OTYPER_OT_5); GPIOA ->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5_1; GPIOA ->PUPDR &= ~(GPIO_PUPDR_PUPDR5); GPIOA ->AFR[0] = GPIO_AF1_TIM2<<20; }void enable_gpio2(){ RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; GPIOA ->MODER |= GPIO_MODER_MODER1_1; GPIOA ->OTYPER &= ~(GPIO_OTYPER_OT_1); GPIOA ->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1_1; GPIOA ->PUPDR &= ~(GPIO_PUPDR_PUPDR1); GPIOA ->AFR[0] |= GPIO_AF1_TIM2<<4; }void generate_pwm1()
{ TIM2 ->CCMR1 |= TIM_CCMR1_OC1M_2; TIM2 ->CCMR1 |= TIM_CCMR1_OC1M_1; TIM2 ->CCMR1 &= ~(TIM_CCMR1_OC1M_0);//Selects pwm mode 1 by writing 110 TIM2 ->CCMR1 |= TIM_CCMR1_OC1PE;// TIM2 ->CR1 |= TIM_CR1_ARPE;//Enables preload register TIM2 ->EGR |= TIM_EGR_UG;//Enables update event whenever cnt equals ccr. TIM2 ->CCER &= ~(TIM_CCER_CC1P);//Sets the polarity of the pwm TIM2 ->CCER |= TIM_CCER_CC1E; TIM2 ->ARR = 500;//Sets the value for the auto reload register. TIM2 ->CCR1 = 50;//Sets the value for the ccr register. TIM2 ->CR1 |= TIM_CR1_CEN;//Starts the counter for timer 2.}void generate_pwm2(){ TIM2 ->CCMR1 |= TIM_CCMR1_OC2M_2; TIM2 ->CCMR1 |= TIM_CCMR1_OC2M_1; TIM2 ->CCMR1 &= ~(TIM_CCMR1_OC2M_0);//Selects pwm mode 1 by writing 110 TIM2 ->CCMR1 |= TIM_CCMR1_OC2PE;// TIM2 ->CR1 |= TIM_CR1_ARPE;//Enables preload register TIM2 ->EGR |= TIM_EGR_UG;//Enables update event whenever cnt equals ccr. TIM2 ->CCER |= TIM_CCER_CC2P;//Sets the polarity of the pwm TIM2 ->CCER |= TIM_CCER_CC2E; TIM2 ->ARR = 500;//Sets the value for the auto reload register. TIM2 ->CCR2 = 400;//Sets the value for the ccr register. TIM2 ->CR1 |= TIM_CR1_CEN;//Starts the counter for timer 2.}Again my channel 1 is working, that is, PA5 is giving pwm output however channel 2 is not.
2017-08-08 04:04 PM
I am using stm32f429 discovery board.
2017-08-08 04:06 PM
I do have a debugger. I'll try making these settings. Thanks.
2017-08-08 05:02 PM
Hello again Daattavya.
In STM32F429-DISC board PA1 is connected to INT pin of MEMS that by default is keeped low
You have two choices. To init L3GD20 and to make INT1 open drain output .. or to use another AF pin for same channel PB3 Be aware also that PB3 is used as trace data pin . (not con. by default)
2017-08-09 07:43 AM
Hello!
@'Could you tell me how to initiate L3GD20? I checked the user manual but couldn't figure it out.'
By writing,
before your initialisation functions and just after HAL_Init()
;GYRO_IO_Init();//enable device
uint8_t ctrl3 = 0x10; GYRO_IO_Write(&ctrl3, L3GD20_CTRL_REG3_ADDR, 1); //open drainYou must allready have include in your main file #include 'l3gd20.h'
and add in your project the modules stm32f4xx_hal_spi.c,stm32f4xx_hal_i2c.c(tweak also HAL_conf.h) ,stm32f429i_discovery.c, l3gd20.c and include the coresponding header files.
All theese files are inside your STM32Cube_FW_F4_V1.1x.0\ directory.
2017-08-09 07:55 AM
Could you tell me how to initiate L3GD20? I checked the user manual but couldn't figure it out.