2021-06-21 04:42 PM
Hi!
I have enabled encoder and input capture and only encoder works.
The reason is that CCR3 and CCR4 is zero.
HAL_TIM_ReadCapturedValue
Why does this happen? I have enabled NVIC for TIM4 and TIM19 and HAL_TIM_IC_CaptureCallback is called when the Input Capture get a rising edge, but still, CCR3 and CCR4 is zero. Why?
Here is when I am in the debug mode.
Here is my complete and very simple C-code.
/*
* Counter.c
*
* Created on: Jun 13, 2021
* Author:
*/
#include "Functions.h"
static uint16_t encoder[2];
volatile static uint16_t input_capture[3];
void STM32_PLC_Start_Counters(TIM_HandleTypeDef* htim4, TIM_HandleTypeDef* htim19) {
/* Encoder */
HAL_TIM_Encoder_Start_IT(htim4, TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start_IT(htim19, TIM_CHANNEL_ALL);
encoder[0] = 0x8000; /* Initial settings */
encoder[1] = 0x8000;
/* Input Capture */
HAL_TIM_IC_Start_IT(htim4, TIM_CHANNEL_3);
HAL_TIM_IC_Start_IT(htim4, TIM_CHANNEL_4);
HAL_TIM_IC_Start_IT(htim19, TIM_CHANNEL_3);
input_capture[0] = 0; /* Initial settings */
input_capture[1] = 0;
input_capture[2] = 0;
}
void STM32_PLC_Encoder0(TIM_HandleTypeDef* htim) {
bool encoder0_direction = !(__HAL_TIM_IS_TIM_COUNTING_DOWN(htim));
/* Values between 0 and 0xFFFF */
if(encoder0_direction)
encoder[0] = 0x8000 + __HAL_TIM_GetCounter(htim); /* Positive rotation: 0x8000 - 0xFFFF */
else
encoder[0] = __HAL_TIM_GetCounter(htim) - 0x8000; /* Negative rotation: 0 - 0x7FFF */
}
void STM32_PLC_Encoder1(TIM_HandleTypeDef* htim) {
bool encoder1_direction = !(__HAL_TIM_IS_TIM_COUNTING_DOWN(htim));
/* Values between 0 and 0xFFFF */
if(encoder1_direction)
encoder[1] = 0x8000 + __HAL_TIM_GetCounter(htim); /* Positive rotation: 0x8000 - 0xFFFF */
else
encoder[1] = __HAL_TIM_GetCounter(htim) - 0x8000; /* Negative rotation: 0 - 0x7FFF */
}
uint16_t STM32_PLC_Encoder_Get(uint8_t i) {
return encoder[i];
}
void STM32_PLC_Input_Capture0(TIM_HandleTypeDef* htim) {
input_capture[0] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);
}
void STM32_PLC_Input_Capture1(TIM_HandleTypeDef* htim) {
input_capture[1] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
}
void STM32_PLC_Input_Capture2(TIM_HandleTypeDef* htim) {
input_capture[2] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
}
uint16_t STM32_PLC_Input_Capture_Get(uint8_t i) {
return input_capture[i];
}
/* Callbacks for Encoder and Input Capture */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim){
if (htim->Instance == TIM4) {
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
STM32_PLC_Input_Capture1(htim);
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
STM32_PLC_Input_Capture0(htim);
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 || htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
STM32_PLC_Encoder0(htim);
} else if (htim->Instance == TIM19) {
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
STM32_PLC_Input_Capture2(htim);
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 || htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
STM32_PLC_Encoder1(htim);
}
}
Solved! Go to Solution.
2021-06-22 05:03 AM
2021-06-21 05:47 PM
CNT is also zero. Seems reasonable that the input capture was triggered when CNT=0, which would lead to CCR3=0 as well. What value are you expecting it to be?
Not sure if encoder and IC can be used simultaneously, but if they can, they share the same counter.
2021-06-21 11:39 PM
> Not sure if encoder and IC can be used simultaneously
Yes it can, and, as you've said, it captures the value counted for the encoder. For time measurement, another timer has to be used.
Also, nonzero prescaler in encoder mode leads to nonsensical readings.
JW
2021-06-22 02:34 AM
Thank you.
I have set the prescaler to 0.
So I need to have a counter that measure the time between two interrupts?
2021-06-22 02:35 AM
I'm expecting that CNT would remember its past value.
How can I set up another timer for measuring speed for Input capture?
2021-06-22 04:18 AM
There is only one counting element in one timer. You either use it for the encoder, or for measuring time, can't do both in the same timer.
JW
2021-06-22 04:25 AM
So the reason why I'm getting CCR3 = 0 all the time, is because I'm using the Encoder at the same timer.
So if I want to measure the difference between two interrupts, I can just use HAL_SysTick() to get a value and the next interrupt, I compare the old SysTick value with next SysTick value?
2021-06-22 05:03 AM
That is one of the ways how to do it.
JW
2021-06-22 05:08 AM
Thank you!