Skip to main content
Graduate II
January 20, 2025
Question

Analog Comparator False Initial Trigger

  • January 20, 2025
  • 8 replies
  • 1910 views

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.

    This topic has been closed for replies.

    8 replies

    Super User
    January 20, 2025

     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.

    How to write your question to maximize your chances to find a solution

    hth

    KnarfB

    Carl_GAuthor
    Graduate II
    January 20, 2025

    AC = Analog Comparator.

    Carl_GAuthor
    Graduate II
    January 20, 2025

    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.

     

    Carl_GAuthor
    Graduate II
    January 20, 2025

    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.

     

    Carl_GAuthor
    Graduate II
    January 20, 2025

    Correction: The COMP Output does go high in my demo test if I monitor it with an oscilloscope. The Input remains low however.

    Super User
    January 20, 2025

    Interesting. Don't have a G071 board here, but used my Nucleo-L432KC. Connected INP firmly to GND and used vrefint/4 for INM. 

    KnarfB_0-1737402416444.png

    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

    Super User
    January 20, 2025

    I've created a new project for the STM32G071RB Nucleo demo board.

    and tied the INP externally to GND?

     

    Carl_GAuthor
    Graduate II
    January 21, 2025

    Yes, I tied the pin directly to GND, and the COMP output monitored with an oscilloscope.

    I have added a post as a bug report here

    https://community.st.com/t5/stm32-mcus-products/comparator-bug-report-on-stm32g0/td-p/763733

     

    I think your solution would work. My alternate was to disable the interrupt just before I enable COMP.  Then reenable it afterward. This is because I enable and disable COMP based on the operating state of my module.

    Its the COMP itself that is sending a trigger to EXTI.