My Objective is to Generate PWM with duty cycle = 50 % , Frequency = 50 Hz using General Purpose Timer 2 in output channel 2 which is at PA1 or pin number 11 My Target System is STM32 BluePill development board

  • Target Controller is STM32F103C8T6 MEDIUM DENSITY DEVICE
  • Target board crystal is 8 MHz
  • I use Keil Micro vision 4 evaluation version IDE for programming and debugging
  • Debugger : ST-LINK V2

I configured the GPIOA in Alternate function output Push Pull mode with maximum frequency not exceeding 50 MHz, I connected an LED bulb to the GPIOA pin 1, but the LED went on glowing without reduction in the brightness level. The LED was still glowing even after i performed a test with duty cycle set to 0. On the debugger window I could see exactly all the parameters I configured and the Count register was getting incremented. I cannot find information regarding selection of alternate functions for a GPIO Port.

my code:

/**************************** Header file *******************************/

/*************************** user defined function **********************/

Name        : PWM_Init()
Description : Initializes PWM hardware and associated GPIO ports
              Enables clocks for peripherals and configure modes
Parameters  : None
Return_val  : None
void PWM_Init()

/****configure clocks for PORTA & TIMER2********/

  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;           // enable port a clock
  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;           // enable clock for timer 2

/*****  configure GPIOA mode *******************/

   /* Porta Pin 1 &2 as alternate function output Push pull 50 MHz */
    GPIOA->CRL = 0x000000bb;  

/*******Set timer 2 Period for PWM**************        
  Timer Clock                   = 72MHz = 72000000 Hz
  Time Period Required          = (1/50Hz) = 0.02 Seconds
  Let ARR value be 65535 then,
  Prescalar + 1                 = 72000000/((ARR+1)*50Hz)
  Prescalar                     = 21 (approx)   

    TIM2->ARR = 65535;                      // Set Auto reload value
    TIM2->PSC = 21;                         // Set Prescalar value

    /* Output Compare Mode, ENABLE Preload,PWM  mode:2*/
    TIM2->CCMR1  = 0x00007800; 

    TIM2->EGR |= TIM_EGR_UG;       // ENABLE update generation

    /*CC2E : channel 2 enabled; polarity : active high*/         

    TIM2->CCER = 0x00000010;  

    TIM2->CR1 |= TIM_CR1_ARPE;      // Auto preload ENABLE
    TIM2->CR1 |= TIM_CR1_CEN;       // ENABLE Timer counter     

/**************Main Function**********************************/
int main()
    PWM_Init();                                  // initialize PWM

            TIM2->CCR2  = 32768;                 // SET duty cycle to 50%

Kindly have a view of my source code and please notify me the corrections that need to be done. The target specifications are mentioned in the source code.

Thank you


Finally, after some experiments I found what was going wrong, The problem wasn't really with the code, as I configured the PWM mode as Mode 2 the pulse is negative instead of Positive with PWM 1. So The signal is actually inverted. At duty cycle set to '0', the pulse will be at peak amplitude and LED will glow ( with active high configuration), also because of the fast blinking the decrease in the intensity is not clearly visible even at 50% duty cycle. I changed the duty cycle to about 80%-90% and I got the LED getting less illuminated.

  • \$\begingroup\$ I am trying to create a PWM on a bluepill board and so far have not been able to get anything working. I've tried your code but I am using AC6 for development. There is no <stm32f10x.h> in my environment but instead it has a <stm32f103xb.h> In any case, I am not getting any PWM out of the board with your program. Have you tried your program in other environments? \$\endgroup\$ – Michel Sep 9 '18 at 4:20
  • \$\begingroup\$ PS: I created a new clean project and your code works. Thanks for the simplest working example I have found for generating a PWM on a STM32 MCU. I am working on what I hope to be a portable C++ library but had too many troubles so far with generating PWM. GPIO was working but not PWM. Now I have something to work from. I have to figure out why the same code inside the other project is not working. \$\endgroup\$ – Michel Sep 9 '18 at 4:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.