Electrical – stm32f103c8t6 : Problem in PWM generation on timer output channel

armembeddedpwmstm32

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 *******************************/
#include<stm32f10x.h>

/*************************** 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

        while(1)
        {
            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

Best Answer

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.