Skip to main content
Explorer
February 16, 2024
Solved

Input capture not detecting square wave

  • February 16, 2024
  • 7 replies
  • 3601 views

I have built a sine wave to square wave circuit and now want to measure its frequency with the STM. I can see on the oscilloscope that the circuit works, however I can detect neither a rising nor a falling edge with the chip. It is not a problem with the code as I can detect both when they are generated by the chip with PWM or externally with a generator (which is old and its square wave really isn't that square) but also they are much slower.

The frequency of the wave is 1.24MHz, measured with the oscilloscope. I don't think that this is too fast, the timer runs at 96Mhz, but maybe using interrupts at this speed is too much?

The minimum voltage of the wave is 0.6V. I am suspecting that might be too high to be considered a logical 0 but I can't find documentation.

I would appreciate any input and also if you could point me to documentation that would be nice!

waves.JPG

    This topic has been closed for replies.
    Best answer by TDK

    > The frequency of the wave is 1.24MHz, measured with the oscilloscope. I don't think that this is too fast, the timer runs at 96Mhz, but maybe using interrupts at this speed is too much?

    Using interrupts at 1.24 MHz is not realistic. You should expect to be limited to tens of kHz in general.

    You can use DMA to capture frequencies at this rate. Capture IC to a DMA buffer and process it at the half- and/or full-complete interrupts.

    7 replies

    Super User
    February 16, 2024

    >point me to documentation

    See ds and rm from your chip (on STM website )

    AScha3_0-1708090841728.png

     

    +

    To count frequency, need to use external clk input for timer .

    AScha3_1-1708091081843.png

    This from F407 ds , you didnt tell your device.

    QwyntexAuthor
    Explorer
    February 16, 2024

    I am using the STM32F411CEU6.
    In its datasheet it says "1.7V<=V_DD<=3.6V". I am correct to then say that my 0.6V should get read as a logical low, right?

    Using a HSE clock, TIM2; PCLK1 runs at 48MHz,  PCLK2 runs at 96MHz. I am using Input capture direct mode, if that matters.
    I don't really know why it doesn't work then, if voltage isn't the problem and TIM2 runs fast enough to be able to detect edges.

    Super User
    February 16, 2024

    You didnt understand, what i tried to say : 

    you should not use "capture mode" or so, but external clk input + gating the timer for (typical 0,1 ...1 sec);

    then you see in counter the counted pulses, in 1 sec gating -> 1,2 mio pulses (only with TIM2 , 32bit possible),

    otherwise 16bit counter would overflow.

    AScha3_0-1708098827906.png

    TIMx_ETR is the input for counting external frequency . So you get max. resolution .

    Super User
    February 16, 2024

    Hardware error? Bug in the software?

    Write a simple experimental program, which sets that input pin as GPIO input and some other pin as GPIO output; and the program does nothing else in main loop just reads the state of input and writes the output accordingly. If you avoid Cube and set reasonable optimization, this should be fast enough so that on output you'll see "copy" of the input (you can try also with some slower input signal source first).

    JW

    TDKAnswer
    Super User
    February 16, 2024

    > The frequency of the wave is 1.24MHz, measured with the oscilloscope. I don't think that this is too fast, the timer runs at 96Mhz, but maybe using interrupts at this speed is too much?

    Using interrupts at 1.24 MHz is not realistic. You should expect to be limited to tens of kHz in general.

    You can use DMA to capture frequencies at this rate. Capture IC to a DMA buffer and process it at the half- and/or full-complete interrupts.

    Super User
    February 16, 2024

    > Using interrupts at 1.24 MHz is not realistic.

    True (especially so if Cube/HAL is involved), but how does that explain

    >> I can detect neither a rising nor a falling edge with the chip

    ?

    By interrupt flooding, and "detect" relying on some software output, without actually looking at the TIMx_CCRx registers in debugger?

    JW

    Super User
    February 16, 2024

    @Qwyntex To address your point and @waclawek.jan 's question about if the logic level of the square wave is sufficient, you can look directly at the bit in the GPIOx->IDR register for that pin. It should be flipping between 0 and 1 with some regularity. (With debugger running, hit pause, resume a few times to get new values). Probably that is not the issue. 640 mV should work as logic low.

    Visitor II
    February 17, 2024

    a) if your logic level is not really 3V3 CMOS (where high level is above the limit to see a high, e.g. 2.4V) or the inputs use a Schmitt Trigger (with a hysteresis) - you might not see all pulses properly:
    https://learn.sparkfun.com/tutorials/logic-levels/all

    b) Nyquist or Shannon Theorem:
        You need 2xFs in order to realize a sine wave (doubled sampling frequency compared to the frequency of the signal)
        for 1.24 MHz sine wave expected (or able to see) - you have to sample (at least) with 2.48 MHz

    QwyntexAuthor
    Explorer
    February 16, 2024

    For my application it is beneficial to get the measurement in the shortest amount of time, which is the length of one period. (Even if there is some small error to it)

    I will try DMA first and see if that helps. If it doesn't I will use your suggestion.

    Super User
    February 16, 2024

    Ok - but even if you make the gating time only 1 ms , still you get much better resolution , than checking only 1 input pulse.

    1,24 MHz -> 806 ns ;

    with 96 M counter you get 77 +/- 1 counts ;

    with 1ms gate, you get 1240 +/-1 counts ; 

    Depends, whether you can live with 2% tolerance, or want 0,1% or better .

    QwyntexAuthor
    Explorer
    February 17, 2024

    Using DMA instead of interrupts fixed it. I guess I really shouldn't have used them in the first place.

    I am now executing two 'HAL_TIM_IC_Start_DMA' back to back with different variables. I am not entirely certain how they behave when used like that but I think it should start the first one and then immediately start the second one when it finished, like with circular.