cancel
Showing results for 
Search instead for 
Did you mean: 

trigger ADC exactly at midpoint of PWM ON time in Center-Aligned PWM Mode 2 (TIM1)?

김형건
Associate II

_0-1747148083376.png

(I'm using NUCLEO-F103RB)

Hello,

I'm currently working on a BLDC motor control project using STM32CubeMX and STM32CubeIDE with STM32 TIM1 peripheral.

I have configured TIM1 in Center-Aligned PWM Mode 2, with:

Prescaler = 3

ARR = 899

So, PWM frequency is 10kHz (from a 72MHz system clock).

In this mode, since the counter counts up and down between 0 and ARR, the counter reaching ARR marks the exact midpoint of the PWM ON time.
I would like to trigger an ADC conversion exactly at that point (i.e., at 50% of the ON time).

To do this, I thought of using TRGO = Update Event, since the update event happens when CNT = ARR in Center-Aligned Mode 2.
However, I am not fully sure if this is guaranteed to occur at that midpoint and whether it's the most precise method.

:question_mark:My questions are:
Is TRGO = Update Event guaranteed to occur exactly when CNT = ARR in Center-Aligned Mode 2?

Is this the best practice to trigger ADC at the center of the PWM ON duration?

If not, is there a more accurate or recommended method?

Any insight or clarification would be greatly appreciated.
Thank you in advance!

15 REPLIES 15
waclawek.jan
Super User

Update event occurs both on CNT=0 and CNT=ARR.

If you want trigger only upon CNT=ARR, set one channel to CCRx=ARR+1 and trigger on that.

Note, that there may be a delay between the Compare event and ADC trigger, due to resynchronization if the timer is at a different bus than ADC (or maybe even if it's on the same bus). Also note, that ADC trigger starts the sampling process, the ADC conversion start is further delayed by the sampling time.

What's the reason to use particularly Center-Aligned Mode 2?

JW

skverma92
Associate II

I'm also facing the same issue in the STM32G030C8T6 series Controller. I want to trigger the ADC using the TRGO2 trigger event on a specific Output compare OC2REF of timer 1, but it's not working. It seems to be a CUBEMX code generation error or a Timer Library-related issue. @st, please help us resolve this issue.

Maybe show your work instead of just saying it doesnt work. No reason to doubt the reference manual.

If you feel a post has answered your question, please click "Accept as Solution".

Dear TDK, I'm sharing the code I tried, but it's not working. It's triggering only once, but not getting regular interrupts. I want to trigger the ADC using the TRGO2 trigger event on a specific Output compare OC4REF (Wrongly mentioned OC2REF in previous msg) of timer 1

 

void MX_TIM1_Init(void)
{

/* USER CODE BEGIN TIM1_Init 0 */

/* USER CODE END TIM1_Init 0 */

TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

/* USER CODE BEGIN TIM1_Init 1 */

/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = FSW_26KHZ_PSC;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = FSW_26KHZ;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC2REF;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_OC4REF;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
sConfigOC.Pulse = 399;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sConfigOC.Pulse = 99;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
__HAL_TIM_ENABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_4);
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.BreakAFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.Break2AFMode = TIM_BREAK_AFMODE_INPUT;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */

/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);

}

waclawek.jan
Super User

> It's triggering only once, but not getting regular interrupts.

Are you talking about ADC interrupts? Maybe ADC does not convert upon the subsequent trigger, for example if it overflows. Read ADC chapter in RM.

JW

 

skverma92
Associate II

Dear Waclawek,
Yes, I'm talking about ADC working in Timer trigger interrupt Mode. ADC does its job perfectly if I select Trigger Event (TRGO2) as Update Event, but if I select OC4REF as Trigger Event (TRGO2) then it works only once.
Thanks.

waclawek.jan
Super User

> I'm using NUCLEO-F103RB

STM32F103 does not have TRGO2 in TIM1. See TIM1 and ADC chapters in RM0008.

JW

skverma92
Associate II

Dear Waclawek,
Ok, but I'm talking about the STM32G030C8T6 microcontroller.
Thanks.

waclawek.jan
Super User

@skverma92,

I've just noticed that you are not the original poster.

Please don't hijack other threads - start your own. Present a coherent description of your problem. Describe your hardware setup, and also describe what is in your software. Describe your observations and how are they different from the expected behaviour.

Read out and check/post content of relevant registers - TIM, ADC, maybe DMA if you use it. Check, if the flags which are supposed to trigger the interrupt, are set or not. A generic "interrupt does not fire" checklist is here.

JW