2025-01-19 08:09 PM - last edited on 2025-01-20 12:14 PM by KnarfB
Hello,
I am working with an STM32G071. I am using Comp2. I have configured it with the STM32CubeIDE. Presently, It is set to "medium" speed/power, and Rising Edge Input with High Hysteresis. The positive input is set to INP/PB6. The negative input is set to Internal VRef. (I can't find anywhere in the manual what that value is. Maybe its only in the data sheet!?) Anyway, my problem is when I enable the AC it instantly triggers the interrupt. However, I don't see any evidence that VALUE is ever high. Meaning It doesn't look like the comparator is actually triggered but maybe its some type of configuration initialization issue? If I ignore this first trigger the AC seems to work fine afterwards.
I have checked the flags in EXTI and they are not set until the exact moment the AC is enabled.
Any idea what could be causing this? I haven't found anything on the forums that might point to an explanation.
2025-01-19 10:15 PM - edited 2025-01-19 10:16 PM
> Maybe its only in the data sheet!?
good idea, look it up.
> when I enable the AC
No idea what you are saying here, please show code and external wiring.
hth
KnarfB
2025-01-20 05:11 AM
AC = Analog Comparator.
2025-01-20 06:34 AM
Stm32cubeIde produces the following relevant source
static void MX_COMP2_Init(void)
{
/* USER CODE BEGIN COMP2_Init 0 */
/* USER CODE END COMP2_Init 0 */
/* USER CODE BEGIN COMP2_Init 1 */
/* USER CODE END COMP2_Init 1 */
hcomp2.Instance = COMP2;
hcomp2.Init.InputPlus = COMP_INPUT_PLUS_IO2;
hcomp2.Init.InputMinus = COMP_INPUT_MINUS_1_4VREFINT;
hcomp2.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED;
hcomp2.Init.WindowOutput = COMP_WINDOWOUTPUT_EACH_COMP;
hcomp2.Init.Hysteresis = COMP_HYSTERESIS_HIGH;
hcomp2.Init.BlankingSrce = COMP_BLANKINGSRC_NONE;
hcomp2.Init.Mode = COMP_POWERMODE_MEDIUMSPEED;
hcomp2.Init.WindowMode = COMP_WINDOWMODE_DISABLE;
hcomp2.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING;
if (HAL_COMP_Init(&hcomp2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN COMP2_Init 2 */
/* USER CODE END COMP2_Init 2 */
}
void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hcomp);
bWeldFlag = true;
}
/* USER CODE BEGIN 4 */
void StartCMP(void)
{
HAL_COMP_Start(&hcomp2);
}
void StopCMP(void)
{
HAL_COMP_Stop(&hcomp2);
}
/* USER CODE END 4 */
Upon calling StartCMP the callback HAL_COMP_TriggerCallback is immediately called. Using breakpoints I have verified that the rising edge flag is set on EXTI 18. After this initial false trigger, the COMP functions as expected. Triggering on an appropriate level on the circuit and not triggering otherwise.
The Weld_Chk_sens is connected to MCU pin PB6. No other MCU functions are connected to PB6. The circuit shown is always at 0V when the COMP is activated and the interrupt is triggered.
2025-01-20 06:44 AM - edited 2025-01-20 07:12 AM
I have also used
hcomp2.Init.InputMinus = COMP_INPUT_MINUS_3_4VREFINT;
As well as using DAC1 output as the COMP negative input. Still same behavior. Initial false trigger then normal operation.
2025-01-20 08:12 AM - edited 2025-01-20 08:27 AM
I've created a new project for the STM32G071RB Nucleo demo board. Same thing. During the call to HAL_COMP_Start the interrupt is triggered. Here is the function
HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
{
__IO uint32_t wait_loop_index = 0UL;
HAL_StatusTypeDef status = HAL_OK;
/* Check the COMP handle allocation and lock status */
if (hcomp == NULL)
{
status = HAL_ERROR;
}
else if (__HAL_COMP_IS_LOCKED(hcomp))
{
status = HAL_ERROR;
}
else
{
/* Check the parameter */
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
if (hcomp->State == HAL_COMP_STATE_READY)
{
/* Enable the selected comparator */
SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
/* Set HAL COMP handle state */
hcomp->State = HAL_COMP_STATE_BUSY;
/* Delay for COMP startup time */
/* Wait loop initialization and execution */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles, scaling in us split to not */
/* exceed 32 bits register capacity and handle low frequency. */
wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
while (wait_loop_index != 0UL)
{
wait_loop_index--;
}
}
else
{
status = HAL_ERROR;
}
}
return status;
}
The interrupt happens while this function is in the while loop. I haven't found any documentation that says to ignore interrupts until after the return of this function. Curious though what the purpose is of the wait loop. It doesn't really "do" anything but delay the return of this function. Does that imply significance to the return of this function? i.e. nothing can change during the wait.
Update:
per LL_COMP_Enable the wait is a delay until the COMP actually starts working. Its for the propagation delay.
2025-01-20 08:15 AM - edited 2025-01-20 08:17 AM
2025-01-20 09:24 AM
Correction: The COMP Output does go high in my demo test if I monitor it with an oscilloscope. The Input remains low however.
2025-01-20 11:50 AM - edited 2025-01-20 12:19 PM
Interesting. Don't have a G071 board here, but used my Nucleo-L432KC. Connected INP firmly to GND and used vrefint/4 for INM.
Same effect here: initial interrupt is fired.
Stepping though the generated code, I see that
MX_COMP2_Init does the initialization, including setting COMP2 CSR and clearing and preparing the EXTI line.
But, MX_COMP2_Init does not yet enable COMP2.
When HAL_COMP_Start enables COMP2 this (somehow) immediately triggers that interrupt.
Have copied the CSR initialization plus COMP2 enable into few lines of code which I have put into an early user code block:
/* USER CODE BEGIN SysInit */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
(void)RCC->APB2ENR; // Delay after an RCC peripheral clock enabling
COMP2->CSR = 0x00c10104; // value copied from HAL_COMP_Init
COMP2->CSR |= COMP_CSR_EN; // enable COMP2
/* USER CODE END SysInit */
Now, COMP2 is enabled well before the EXTI and NVIC stuff is initialised, and there is no more initial interrupt.
hth
KnarfB
2025-01-20 12:21 PM - edited 2025-01-20 12:27 PM
> I've created a new project for the STM32G071RB Nucleo demo board.
and tied the INP externally to GND?