Skip to main content
arganasss
Associate III
January 16, 2014
Question

STM32f3 embedded comparators

  • January 16, 2014
  • 16 replies
  • 2367 views
Posted on January 16, 2014 at 16:09

Firstable, sorry for so many new topics, but as i dig deeper and deeper into programming stm32 boards, i find a lot new questions. I wasn't able to find a topic which relates to my problem, so i just created a new, and here is my question: I know stm32f3 board has embedded comparators. Is it possible to put a ramp signal from external generator into one into I/O pins and the same signal into one of comparator's input. Then detect a falling edge of the signal go to interrupt which starts timer, and stops it when signal reaches threshold value? Is it possible to change treshold value in my program? Maybe there are some examples written by ST for comparators usage? Any help and answers to my this problem will be highly appreciated. Thanks in advance.

Edit: I found example on OPAMP_PGA for stm32, but that just gives me understanding how to configure comparator.
    This topic has been closed for replies.

    16 replies

    arganasss
    arganasssAuthor
    Associate III
    January 20, 2014
    Posted on January 20, 2014 at 18:10

    Edit: Thank you for your help. Now my code is working and comparator work's as it should. I have a question though. If i look up no PF4 with scope, i see small voltage “jumps“ even without running my code. I also see that on some PA pins. Have u any idea why is that?

    Thank you very much for your help again and answers.
    raptorhal2
    Lead
    January 20, 2014
    Posted on January 20, 2014 at 20:43

    i see small voltage “jumps“

    PF4 pin is digital logic. As long as it doesn't jump between logic level ''0'' and ''1'' levels, this is normal noise pickup.

    If you see the same problem on PA1 when the signal source is connected, then further investigation might be needed.

    Cheers, Hal

    arganasss
    arganasssAuthor
    Associate III
    January 24, 2014
    Posted on January 24, 2014 at 11:41

    Thank you for your help. I still didn't manage to do what i want. I want to use the EXTI interrupt to detect the falling edge of the signal connected to the I/O pin, then start a timer which would stop when comparator output goes to high level, however nothing works. My code now goes as follows:

    #include

    ''main.h''

    #include

    ''stdio.h''

    TIM_ICInitTypeDef TIM_ICInitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    EXTI_InitTypeDef EXTI_InitStructure;

    COMP_InitTypeDef COMP_InitStructure;

    void

    EXTI1_IRQHandler(

    void

    )

    {

    if

    (EXTI_GetITStatus(EXTI_Line1) != RESET)

    //

    Check

    if

    EXTI_Line1

    is

    asserted

    {

    GPIOE->ODR ^= GPIO_Pin_8;

    }

    EXTI_ClearITPendingBit(EXTI_Line1);

    //

    Clear

    EXTI

    LINE1

    pending

    bit

    }

    void

    EXTI1_Config(

    void

    )

    {

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource1);

    //

    Connect

    EXTI1

    Line

    to

    PA1

    pin

    /*

    Configure

    EXTI1

    line

    */

    EXTI_InitStructure.EXTI_Line = EXTI_Line1;

    //

    Line1

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    //

    Interrupt

    mode

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

    //

    Detect

    falling

    edge

    of

    the

    external

    signal

    connected

    to

    PA1

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    //

    Enable

    EXTI

    line

    EXTI_Init(&EXTI_InitStructure);

    //

    Send

    parameters

    to

    the

    registers

    /*

    Configure

    NVIC

    */

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

    //

    Select

    NVIC

    channel

    to

    be

    configured

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =

    0x0F

    ;

    //

    Set

    priority

    to

    the

    lowest

    NVIC_InitStructure.NVIC_IRQChannelSubPriority =

    0x0F

    ;

    //

    Set

    sub-priority

    to

    the

    lowest

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    //

    Enable

    IRQ

    channel

    NVIC_Init(&NVIC_InitStructure);

    //

    Send

    parameters

    to

    the

    registers

    }

    void

    Comparator_Config(

    void

    )

    {

    /*

    Configure

    PA1

    analog

    mode:

    It

    is

    used

    as

    Comparator1

    analog

    input

    */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

    //

    Analog

    mode

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /*

    Configure

    PF4

    in

    Alternate

    Function

    mode:

    it

    is

    used

    as

    Comparator1

    output

    */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    //

    Alternate

    function

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOF, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOF, GPIO_PinSource4, GPIO_AF_2);

    //

    Connect

    Port

    A

    pin

    6

    to

    comparator

    output

    COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_VREFINT;

    COMP_InitStructure.COMP_NonInvertingInput = COMP_NonInvertingInput_IO1;

    COMP_InitStructure.COMP_Output = COMP_Output_None;

    COMP_InitStructure.COMP_BlankingSrce = COMP_BlankingSrce_None;

    COMP_InitStructure.COMP_OutputPol = COMP_OutputPol_NonInverted;

    COMP_InitStructure.COMP_Hysteresis = COMP_Hysteresis_No;

    //

    Do

    not

    use

    Hysteresis

    COMP_InitStructure.COMP_Mode = COMP_Mode_UltraLowPower;

    //

    Ultra

    low

    power

    mode

    COMP_Init(COMP_Selection_COMP1, &COMP_InitStructure);

    //

    Enable

    COMP

    parameters

    COMP_Cmd(COMP_Selection_COMP1, ENABLE);

    //

    Enable

    comparator1

    }

    int

    main(

    void

    )

    {

    RCC->AHBENR |=

    1

    <<

    21

    ;

    //

    Enable

    clock

    for

    port

    E

    RCC->APB1ENR |=

    1

    <<

    1

    ;

    //

    enable

    clock

    for

    Timer3

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    //

    Timer2

    clock

    on

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    //

    GPIOA

    clock

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    //

    Enable

    the

    SYSCFG

    APB

    clock

    to

    get

    write

    access

    to

    comparator

    register

    and

    EXTI

    line

    interrupts

    COMP_DeInit(COMP_Selection_COMP1);

    //

    Reset

    comp1

    parameteres

    to

    default

    values

    //

    Port

    E

    pin

    8

    (blue

    LED)

    configuration

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOE, &GPIO_InitStructure);

    EXTI1_Config();

    EXTI1_IRQHandler();

    //

    Comparator_Config();

    //

    Uncomment

    this

    line

    and

    comparator

    works,

    but

    the

    code

    never

    jumps

    to

    EXTI1_IRQHandler.

    Comment

    this

    line

    and

    then

    code

    goes

    to

    EXTI1_IRQHandler

    while

    (

    1

    )

    {

    //

    Do

    nothing

    }

    }

    As i stated in the code, uncommenting the line Comparator_Config() in the main function get's comparator to work, but then code never jumps to EXTI line IRQ handler. If i comment that line, comparator obviously doesn't work, but then my code is able to jump to EXTI_IRQHandler. Could anyone explain why this behaviour is caused? Is it because EXTI Line 1 uses the same pin as Comparator input? OR is it because that it requires GPIO pins to be configured in input mode if i want to use EXTI interrupt, but i already have configured the pin in analog mode for Comparator? Or i have completely wrong understanding of how EXTI interrupts work? I'll appreciate any help for solving this problem. Thanks in advance.

    raptorhal2
    Lead
    January 24, 2014
    Posted on January 24, 2014 at 22:21

    You seem to have taken a step backwards. After setting up your comparator falling edge detect criteria and connecting the comparator output to PF4, you then connect the EXT interrupt to PA1, bypassing the comparator output.

    My guess is that you are confused over the edge detector logic in the EXT ciruitry. As I stated before, this is a digital logic edge criteria, your sine wave input is an analog signal, so you need to use the setup you have in place for the comparator inputs as your edge detector.

    See Section 11.2.6 in the F3 reference manual. The table there identifies EXTI4 as the interrupt connected to PF4, and that should then be the handler that starts the timer going.

    After you get the timer going correctly, then you need to set up another comparator with low level detection connected to another EXT interrupt to stop the timer when the low level criteria is met.

    Cheers, Hal

    arganasss
    arganasssAuthor
    Associate III
    January 24, 2014
    Posted on January 24, 2014 at 23:32

    From your post i now see that i misunderstood the EXTI interrupt and edge detecting criteria. Thanks a lot for your help and time. I'll try to do this now and give you a feedback. 

    Cheers, Arganas.

    arganasss
    arganasssAuthor
    Associate III
    January 28, 2014
    Posted on January 28, 2014 at 14:12

    I just wanted to give you a feedback. Thank you for your help, time and comments. It helped me a lot and i managed to do what i want.