Skip to main content
Domen Visnar
Associate
February 2, 2018
Question

STM32F103C8T6 PWM Generation

  • February 2, 2018
  • 3 replies
  • 4809 views
Posted on February 02, 2018 at 14:49

Hello! I have a question: How to generate a PWM on STM32F103C8T6 in Keil uVision 5. I watched some tutorials but I couldn't make it work, I want to enable TIM1 on pin PA11 and PA12. PWM needs to run at 20kHz => period = 3600.

It will be used for motor control on a robot. This is what I managed to do:

&sharpinclude 'stm32f10x.h'

int main(void){

RCC-> APB2ENR |= RCC_APB2ENR_TIM1EN; 

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

GPIOA->ODR |= GPIO_ODR_ODR11;

GPIOA->CRH |= GPIO_CRH_MODE11_1;

GPIOA->CRH &= ~(GPIO_CRH_MODE11_0);

TIM1->PSC = 0;

TIM1->ARR = 3600;

TIM1->CCR4 = 1800;

TIM1->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE; 

TIM1->CCER |= TIM_CCER_CC4E; 

TIM1->BDTR |= TIM_BDTR_MOE;

TIM1->CR1 |= TIM_CR1_CEN; 

TIM1->EGR |= TIM_EGR_UG;

while(1)

{

//User code

}

}

I watched this tutorials:

https://www.youtube.com/watch?v=xs9lGF--QcU

 

https://www.youtube.com/watch?v=fJZl_rACO-0

 

https://www.youtube.com/watch?v=UHqqhKXVmSc

 

Maybe if you have some more tutorials on PWM and encoder readings with timers I would be very glad!

Thank you in advance!

Any help would be appreciated!

#rotary-encoder #stm32 #stm32f103c8t6 #tim-pwm
This topic has been closed for replies.

3 replies

henry.dick
Associate II
February 2, 2018
Posted on February 02, 2018 at 15:17

a few suggestions:

1) I generally organize my pwm code into two pieces: 1) initialize the time base, like setting up the prescaler and period, set up the particular channels, 2) change the channel's duty cycle.

if I were to do your case, I would have written two pieces, t1pwm_init(1, 3600); and t1pwm4_setdc();

you have most of the code pieces there but if you want I can share mine with you.

2) '

TIM1->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE; '

that's a very dangerous piece of code as it assume a certain state of CCMR2 prior to that line. I would have done a more explicit line.

hope it helps.

Domen Visnar
Associate
February 2, 2018
Posted on February 02, 2018 at 16:09

Thank you for a quick reply. I would be grateful for your code.

waclawek.jan
Super User
February 2, 2018
Posted on February 02, 2018 at 16:41

You need to set also the CNF11 bits in GPIO_CRH to Alternate function.

(Btw., there is no TIM4 functionality for PA12)

JW

Tesla DeLorean
Guru
February 4, 2018
Posted on February 04, 2018 at 15:08

These need to be written as N-1, ie divide by 1000 set as 999

TIM1->PSC = 0; // DIV1

TIM1->ARR = 3600; // DIV3601

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
crazy crazy
Visitor II
February 14, 2018
Posted on February 14, 2018 at 01:26

#include 'stm32f10x.h'

int main(void){

RCC-> APB2ENR |= RCC_APB2ENR_TIM1EN;

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

GPIOA->CRH &=0xFFFF0FFF; //PA11

GPIOA->CRH |=0x0000B000; //Alternate function output Push-pull Output mode, max speed 50 MHz.

TIM1->PSC = 0;

TIM1->ARR = 3600;

TIM1->CCR4 = 1800;

TIM1->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4PE;

TIM1->CCER |= TIM_CCER_CC4E;

TIM1->BDTR |= TIM_BDTR_MOE;

TIM1->CR1 |= TIM_CR1_CEN;

TIM1->EGR |= TIM_EGR_UG;

while(1)

{ //User code

}

}