TIM2 PWM newbie needs help with bare metal code
Posted: Tue May 16, 2023 10:01 pm
Thanks to GonzoG,dannyf and ag123, this is my first attempt to write code for STM32 with bare metal coding.
We started talking here about other subject:
I'm sorry, please be patient, I am just starting and this part of the road is hard.
Based upon a YouTube original example for an F4 engine, I had to make changes for my F103C8T6 BluePill.
Well...it doesn't work. I should be seeing a PWM signal in PA0, 50% duty cycle, using TIM2.
I am really interested in direct register access coding. I don't like HAL.
Could you help me find the errors so I can study and learn ?
Here is my code.
Thank You !
We started talking here about other subject:
I decided to make a separate post for this issue.
I'm sorry, please be patient, I am just starting and this part of the road is hard.
Based upon a YouTube original example for an F4 engine, I had to make changes for my F103C8T6 BluePill.
Well...it doesn't work. I should be seeing a PWM signal in PA0, 50% duty cycle, using TIM2.
I am really interested in direct register access coding. I don't like HAL.
Could you help me find the errors so I can study and learn ?
Here is my code.
Thank You !
Code: Select all
#define PIN 0
#define PERIOD 100
#define DUTY 50
void setup()
{
// enable clocks for GPIOA and TIMER2
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
// set alternate function on PA0
GPIOA->CRL &= ~0x01; GPIOA->CRL |= (1 << 2); // '10'
GPIOA->CRL |= (1 << 4) ; GPIOA->CRL &= ~(1 << 3); // '10'
// set channel to output mode (defalult after reset)
TIM2->CCMR1 &= ~0x03;
// select the polarity by writing de CCPx bit
TIM2->CCER &= ~0x03;
// select PWM mode 1 or 2 upcounting or downcounting by writing OCxM bits in CCMRx register
TIM2->CCMR1 |= (0x06 << 5);
// Program the period and the duty cycle respectively in ARR and CCRx registers
TIM2->PSC = 7999; // divides the 16 MHz clock so the counter runs at 1KHz
TIM2->ARR = PERIOD;
TIM2->CCR1 = DUTY;
//set the preload bit in the CCMR register and the ARPE bit in the CR1 register
TIM2->CCMR1 |= TIM_CCMR1_OC2PE;
TIM2->CR1 |= TIM_CR1_ARPE;
// select the counting mode PWM edge aligned mode,
// a) the counter must be configured up-counting or down-counting
// b) the counter must be center aligned counting mode (CMS bits different from '00')
// Leave the default DIR = 0 (UPCOUNT) CMS = 0 (EDGE ALIGNED)
//-------------
// Enable the capture / compare
TIM2->CCER |= 0x01; // enable compare
TIM2->CR1 |= TIM_CR1_CEN; // enable count
while(1) ;
}
void loop()
{
}