How to get to the timer registers to setup center aligned

Post here first, or if you can't find a relevant section!
Post Reply
bmentink
Posts: 3
Joined: Tue Apr 16, 2024 12:50 am

How to get to the timer registers to setup center aligned

Post by bmentink »

Hi all,

I am very new to stm32duino. I have installed the arduino framework in platformio.

So far I have managed to get the stm32f103 bluepill to run at 72Mhz by some PLL code, and I have a PWM with interrupts working.

However for my motor controller project I need 3-phase pwm off the same timer (TIM1) and to be able to get at the registers to setup
centre-aligned PWM and set the deadtime. There does not seem to be a way to do this on the standard official API. I know the arduino framwork has HAL and CMSIS underneath, maybe that will help me?

I am using this site for Arduino API : https://github.com/stm32duino/Arduino_C ... er-library

Can anyone help here?
bmentink
Posts: 3
Joined: Tue Apr 16, 2024 12:50 am

Re: How to get to the timer registers to setup center aligned

Post by bmentink »

I think I have made some progress, this is what I have so far using the HAL layer:

TIM_HandleTypeDef htim1;
TIM_OC_InitTypeDef *sConfig = nullptr;
void Setup()
{
// some other setup stuff

HAL_TIM_PWM_Init(&htim1);
HAL_TIM_PWM_ConfigChannel(&htim1,sConfig,TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim1,sConfig,TIM_CHANNEL_2);

// Set up Timer1 for Complimentary PWM on Channel 1 and Channel 2
TIM1->CCER |= b2+b6; // these are bit definitions i.e b2 is bit2=4
// Dead time 500ns
TIM1->BDTR |= b1+b5;
// Center ALigned PWM
TIM1->CR1 |= b6;
TIM1->ARR = 5000; // Frequency
TIM1->CCR1 = 1200; // Duty

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
That all is compiled ok, but I am not sure how to link the timer/channels to pins, is it done in the config? (TIM_OC_InitTypeDef), or is it auto assigned?

I am sure I am missing heaps, anyone please jump in and bail me out :)
bmentink
Posts: 3
Joined: Tue Apr 16, 2024 12:50 am

Re: How to get to the timer registers to setup center aligned

Post by bmentink »

Seems like I am having a wee chat with myself ... :lol:

I have managed to get one complementary channel going with deadband, by using a combo of hardware timer and register access, this is what I have to far:
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pinAH), PinMap_PWM);
uint32_t channel_AH = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pinAH), PinMap_PWM));
uint32_t channel_AL = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pinAL), PinMap_PWM));

// Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished.
MyTim = new HardwareTimer(Instance);

// Configure and start PWM
MyTim->setPWM(channel_AH, pinAH, 20000*2, 30); // 20Khz, center aligned so x2, 30%duty
MyTim->attachInterrupt(Update_IT_callback);
MyTim->attachInterrupt(channel_AH, Compare_IT_callback);

MyTim->setMode(channel_AH,TIMER_OUTPUT_COMPARE_PWM1,pinAH);
MyTim->setMode(channel_AL,TIMER_OUTPUT_COMPARE_PWM2,pinAL);

// Set up Timer1 for Complimentary PWM on Channel 1 and Channel 2
TIM1->CCER |= b2+b6;
// Center aligned PWM
TIM1->CR1 |= b6;
// Dead time 500ns, seems to be more like 300ns
TIM1->BDTR |= b1+b5;
I just don't know how to add the other 2 complentary outputs to the above. (I need 3-phase comp PWM)
Post Reply

Return to “General discussion”