9 years, 1 month ago.

How to set an InterruptIn on a digitalIn PIN?

I 've got a Freedom K22F mbed microcontroller. My problem now is to set up correctly an interrupt event on a digital input.

This is my code. My goal is to count time to get frequency from a square wave. i make confusion also with pin names. can someone help me?

Do I use correctly enable and disable IRQ methods?? Thanks

myCode

InterruptIn HL(D7);
InterruptIn LL(D7);

void highLevel();
void lowLevel();

int main()
{
    HL.rise(&highLevel);
    LL.fall(&lowLevel);
    
    while (true) {

        HL.enable_irq();
        LL.enable_irq();
        
        wait(1);
        
        float period = tempo.read_us();
        float freq = 1000000.0f / period;
        serial.printf("TEMPO = %f FREQUENZA = %f \n\r", period, freq);
        wait (1);
        
    }
}

void highLevel()
{
    led_red = 1;
    tempo.start();
    HL.disable_irq();
}

void lowLevel()
{
    tempo.stop();
    LL.disable_irq();
}

Question relating to:

Example Interrupt code for FRDM platforms FTF2014, hands-on, lab

1 Answer

9 years, 1 month ago.

The disable_irq functions on InterruptIn disable all interrupts on that specific interrupt vector, which makes it not that useful imo for most programs. A better way to disable an interrupt is to attach NULL, so HL.rise(NULL);. This disables only that specific interrupt. Now when the highLevel interrupt fires it will disable effectively also the low level interrupt.

Note that they aren't level interrupts, they are edge interrupts. And finally in your current code what can happen is that first lowLevel fires which stops the timer, and then the highlevel. You could for example let the highLevel code enable the lowlevel interrupt and disable itself, and then the lowlevel one disables itself. At the beginning of your loop you then only enable the highlevel interrupt.

Finally: There are libraries which do this for you if you are interested in the functionality and now how to create the functionality, if you want to learn how to use it, carry on :).

Thanks Erik for helping me solving this problem. There was also a logical error in my code. Cause i would stop the timer at the next rising edge, not at next falling one.

Here is the code

#include "mbed.h"

bool isHigh = false;
Timer tempo;
Serial serial(USBTX, USBRX);

InterruptIn interr(D7);

void interruptClock();

int main()
{
    serial.baud(9600);
    
    while (true) {
        
        interr.rise(&interruptClock);
        wait(1);
            
        float period = tempo.read_us();
        float freq = 1000000.0f / period;
        
        serial.printf("TEMPO = %f FREQUENZA = %f \n\r", period, freq);
        
        tempo.reset();
        wait(1);
    }
}

void interruptClock()
{
    if (!isHigh)
    {
        tempo.start();
        isHigh = true;
    }
    else
    {
        tempo.stop();
        interr.rise(NULL);
        isHigh = false;
    }
    
}
posted by Alessandro Canicatti 07 Mar 2015