2018-05-19 03:48 AM
Hello ,
I am using stm32f446re nucleo board . and i face some issue in timer input capture .
here i am using 2 timers TIM6 ( for time base generation ) and TIM2 (free running input capture purpose)
actually my code is working fine when i run the first timer(TIM6) at 10 micro or 100 micro second time base generation . I actually toggle the gpio in IRQ handler of TIM6 and that is input to the TIM2 input channel where i detect the gap between rising and falling edge of a gpio . TIM2 actually DMA the content of CCR1 to memory .
as i said this works fine when i use the TIM6 for 10 micro and 100 micro time base generation
but when i use the TIM6 for 1 mirco second time base generation , the TIM2 is not giving correct values for the gpio toggling . Can you please help me to understand what is going wrong ?
i am using AHB = 84Mhz, timer clock = 48Mhz.
Here is a code
int main(void)
{ /* USER CODE BEGIN 1 */ uint32_t diffCapture=0; double frequency=0; char msg[30];/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init(); MX_DMA_Init(); MX_USART2_UART_Init(); MX_TIM6_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t*) captures, 2); HAL_TIM_Base_Start_IT(&htim6);/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */ while (1) {if (captureDone != 0) {
if (captures[1] >= captures[0]) diffCapture = captures[1] - captures[0]; else diffCapture = (htim2.Instance->ARR - captures[0]) + captures[1];frequency = HAL_RCC_GetPCLK1Freq() / (htim2.Instance->PSC + 1);
frequency = (float) frequency / diffCapture;sprintf(msg, 'Input frequency: %.3f\r\n', frequency);
//HAL_UART_Transmit(&huart2, (uint8_t*) msg, strlen(msg), HAL_MAX_DELAY); //while (1); }}
}
/* TIM2 init function */
static void MX_TIM2_Init(void){TIM_MasterConfigTypeDef sMasterConfig;
TIM_IC_InitTypeDef sConfigIC;htim2.Instance = TIM2;
htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_IC_Init(&htim2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
/* TIM6 init function */
static void MX_TIM6_Init(void){TIM_MasterConfigTypeDef sMasterConfig;
htim6.Instance = TIM6;
htim6.Init.Prescaler = 0; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; htim6.Init.Period = 47; if (HAL_TIM_Base_Init(&htim6) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
/* USER CODE BEGIN 4 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { captureDone = 1; }}2018-05-19 04:28 AM
actually toggle the gpio in IRQ handler of TIM6
when i use the TIM6 for 1 mirco second time base generation , the TIM2 is not giving correct values for the gpio toggling
Executing the IRQ handler probably takes more than 1 microsecond.
Observe the waveform with an oscilloscope or logic analyzer. Better yet, use a timer with output channel and generate the waveform purely in hardware (PWM).
JW
2018-05-19 06:42 AM
Thanks for the reply ,
Actually TIM2 runs till 65535( @48Mhz) that is ~1.3ms , even if TIM6 IRQ handler takes more than 1mirco second , it shouldnt be problem for input compare isnt it ?
2018-05-19 08:19 AM
TIM2 should be 32-bit, you should use full range (0xFFFFFFFF)
diffCapture = captures[1] - captures[0]; // should work with ALL values, wrapping will be managed/contained within the uint32_t math
The TIM Clock on APB1 (PCLK1) will typically be PCLK*2 for any divider other than 1
>>i am using AHB = 84Mhz, timer clock = 48Mhz.
Half of 84 is 42, not 48, the TIMCLK in this context will almost certainly be 84 MHz
2018-05-19 08:27 AM
'
when i use the TIM6 for 1 mirco second time base generation ,'
make sure the ISR can be executed within that time framework.
2018-05-19 10:31 AM
The 8-ball here says ''signs point to no''
2018-05-19 10:47 AM
Problem is not with the input capture of TIM2, but with the signal generation using interrupt of TIM6.
JW
2018-05-20 01:22 AM
Thanks . now i understood basically the gpio cannot able to toggle exactly at 1mirco second due to delay caused by IRQ processing . now suppose if i want to toggle the gpio at 1 micro second ,what is the alternate ? i tried output compare toggle mode and max i can achieve is 300KHz switching frequency . How can i increase this to 1Mhz ? There also IRQ processing is involved where i need to feed the output compare register like below code
if i switch to DMA can i achieve 1 MHz toggling ?
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *tim)
{uint32_t pulse;/* TIM2_CH1 toggling with frequency = 50KHz */
if(tim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { pulse = HAL_TIM_ReadCapturedValue(tim, TIM_CHANNEL_1); /* Set the Capture Compare Register value */ __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (pulse + ch1_pulse_value)); }}2018-05-20 01:26 AM
Thanks . i am sorry, the config is AHB=84Mhz and timer clock = 84Mhz as you said. can i get 1Mhz of output toggling using timer 2 ? is there any register where i can configure the pulse value and it generates output waveform auto feeding the output compare register ? instead of feeding it through DMA or IRQ handler ?
2018-05-20 04:30 PM
Autonomously outputting pulses - this is what the PWM mode of timer is all about.
So, read about PWM.
JW