2023-02-25 11:58 AM
Hello,
I am having some problems with Timer Capture/PWM Input
The target device will be an STM32F091CC, however my test device for this function is an STM32F030K6
I'm trying to input 3 different PWM devices but I have limited access to certain pins as they are used up by other functions
The timers I am using are
- TIM3_CH1/TIM3_CH2
- TIM15_CH1/TIM15_CH2
- TIM1_CH3/TIM2_CH4 (This is the problem)
I'll start with saying that using the ST Example code, I am able to get the PWM input using Capture Compare examples perfectly on TIM3 CH1 & CH2, and on TIM15 CH1 & CH2.
The problem is when I try to use CH3 and CH4 on any timer. In this case it happens to be TIM1.
I have my PWM input phyiscally connected to TIM1_CH4 but do not have access to TI2FP2.
All of the ST examples use CH1 & CH2 of their respective timer for PWM input, but do not make any mention of trying to do PWM input on CH3 & CH4
When I use the ST Example code and switch it to CH3&CH4, firstly I cannot use TI2FP2 or TI1FP1, and as such I try using a different trigger source in Slave mode. Usually between ITR0 - ITR3. I believe this is wrong however.
The data I get is completely arbitrary when I try to measure Frequency and Duty Cycle. Can anyone see what I'm doing wrong here, or have any good links or information to using CH3&CH4 of any timer for PWM input? I've found some other links through searching but the links within are usually broken. Otherwise this doesn't seem to be covered too often.
This to start the TIM1 in Input Capture
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_4);
HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_3);
This is my TIM1 initialization
static void MX_TIM1_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0xA;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xFFFF;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
Here is my Capture Callback Code
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
/* Get the Input Capture value */
uwIC4Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);
if (uwIC4Value != 0)
{
/* Duty cycle computation */
DutyCycle1 = (((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3)) * 100.0) / uwIC4Value) * 100.0;
/* uwFrequency computation
TIM1 counter clock = (RCC_Clocks.HCLK_Frequency) */
Frequency1 = ((HAL_RCC_GetHCLKFreq()) / uwIC4Value) / (TIM1->PSC + 1.0);
}
else
{
DutyCycle1 = 5000;
Frequency1 = 0;
}
}
}
Thank You
2023-02-25 02:08 PM
> I try using a different trigger source in Slave mode
You can't, the slave-mode controller has no input from CH3/CH4.
But you don't need it. If the input frequency is not too high, you can simply use plain captures on the opposite edges, calculate duty as difference of captures on the two channels (taking into account both possible edge orderings) and calculate period from differences of subsequent captures on the same channel.
JW
2023-02-26 08:11 AM
Thank you for the advice. I tried your suggestion and couldn't get it to work. No matter what I did the duty cycle remained an arbitrary number, even when I was no longer paying attention to the frequency since the input PWM signal is only 150Hz.
I had tried for a few days prior to my post on here, but after hours of trying more things last night I finally gave in and looked into if it's possible to rearrange the pins so I could get the CH1 or CH2 as the direct input on each of the 3 timers trying to measure PWM signals.
I was able to rearrange quite a bit of it to get it to work. I would like to revisit this problem in the future as I'm sure it will come up again in the near future, but for right now this will get the project back on track.
Thank you