AnsweredAssumed Answered

6 CH PWM on TIM1 (What is Wrong with my Code)

Question asked by slimsly on Feb 6, 2013
Latest reply on Feb 6, 2013 by waclawek.jan

Hello,

I am currently migrating from Microchip MIP to ST ARM Cortex M3 so I am new to Cortex M3.I have been trying for days to configure Advance TIM1 in STM32F103RB to output 6 Channel PWM but it has prove to be a difficult task. When I probe PA8--PA10 using my Salae Logic Analyzer, there are no PWM on those Pins..

I have gone through my Code, Data sheet and App Note several times but I can not get it to Work. I do not want to use ST Peripheral Library. I prefer bare metal because it enable me to understand the Hardware.My Code is below and I desperately need help

Note: CoCoox IDE and ARM GNU 4.7 C Compiler Used in building the Code.

=====================
#include "stm32f10x.h"

void PWM_init(void);


int main(void)
{
  volatile uint32_t dly;
  RCC-> CFGR |= RCC_CFGR_ADCPRE_DIV4;     //ADC divided by 4
  /*Enable all GPIO Clock & Alternate Function Clock*/
  RCC->APB2ENR = RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN;
  /*Enable ADC1 & ADC2 Clock*/
  RCC->APB2ENR |= RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN;
  /*Enable TIMER1 & USART1 Clock*/
  RCC->APB2ENR |= RCC_APB2ENR_TIM1EN | RCC_APB2ENR_USART1EN;
  /*Enable TIMER2, TIMER3 & I2C1 Clock*/
  RCC->APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN |RCC_APB1ENR_I2C1EN | RCC_APB1ENR_TIM4EN;
  RCC->AHBENR = RCC_AHBENR_DMA1EN ;   //DMA1 clock enable

  GPIOB->CRH = 0x44444222;          //Configure PB8 & PB9 as Output (Push Pull)
  GPIOA->CRH = 0x44444AAA;           //PA8 - PA10 Alternate Function Push Pull Output
  AFIO->MAPR |= AFIO_MAPR_USART1_REMAP; // Remap TX=>PB6, RX=>PB7)

  PWM_init();                       //Initialize 20KHz PWM on CH 1-3
    while(1)
    {
        for(dly = 0; dly < 500000; dly++);
        GPIOB->BSRR = (1 << 8);
        GPIOB->BSRR = (1 << 9);
        for(dly = 0; dly < 500000; dly++);
        GPIOB->BRR = (1 << 8);
        GPIOB->BRR = (1 << 9);
    }
}


/* PWM CH1=>PA8, PWM CH2=>PA9, PWM CH1=>PA10*/

void PWM_init()

{ /* channel 1&2 is configured as output*/
  TIM1->CCMR1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
  TIM1->CCMR2 &= ~(TIM_CCMR2_CC3S);    //channel 3 is configured as output
  /* Channel 1,2& 3 active high */
  TIM1->CCER = TIM_CCER_CC1P | TIM_CCER_CC2P | TIM_CCER_CC3P;
  TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; //PWM mode 1
  TIM1->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; //PWM mode 1
  TIM1->CR1 = TIM_CR1_CMS_1  | TIM_CR1_ARPE;  //Center-aligned mode 2
  TIM1->CR2 = TIM_CR2_CCPC;                    //CCxE, CCxNE and OCxM bits are preloaded

  TIM1->BDTR = TIM_BDTR_MOE | TIM_BDTR_AOE | TIM_BDTR_OSSR;
  TIM1->PSC = 0;
  TIM1->ARR = 2800;        // Auto reload value 2800 (PWM Period = 50us)
  TIM1->CCR1 = 1400;       // Start PWM duty for channel 1
  TIM1->CCR2 = 700;        // Start PWM duty for channel 2
  TIM1->CCR3 = 350;        // Start PWM duty for channel 3

  /* CH 1-3 Output Compare Enable*/
  TIM1->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E;
  TIM1->CCER = TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE;
  TIM1->CR1 = TIM_CR1_CEN;  // Counter enable

}
===================
Thanks
Please Forgive my English

Outcomes