interrupt in project

Thread Starter

Parth786

Joined Jun 19, 2017
642
I have read about interrupt. Interrupts are events that cause the microprocessor to stop what it is doing, and handle a high-priority task first. After the interrupt is handled, the microprocessor goes back to whatever it was doing before.

There are two type of interrupt
  • hardware interrupt
  • software interrupt
Suppose I have microcontroller Buzzer, Switch and LCD. What I can make with all four of them that may be useful and can be use interrupt in project.

My main purpose is learn to use of interrupt in project. I have seen example like digital clock. What I can make useful with all four of them
 

nsaspook

Joined Aug 27, 2009
13,086
Here is a interrupt example in xc8 18f1320 for the HD POV toy I am playing with where we don't have vectored interrupts for each source, only high/low. The moving line control software runs during interrupts while the remote control software runs in the main loop.


https://github.com/nsaspook/hd_pov/blob/xc8/pov_mon.c
https://github.com/nsaspook/hd_pov/blob/xc8/pov_mon.h

The program spends most if its time in this loop.
C:
void main(void)
{
/* configure system */
init_povmon();
/* Loop forever */
while (true) { // busy work
sw_work(); // run housekeeping for non-ISR tasks
}
}

/* main loop work routine */
int16_t sw_work(void)
{
static uint8_t position = 0, offset = 0, rx_data;
static uint8_t *L_tmp_ptr;
static union L_union_type { // so we can access each byte of the command structure
uint8_t L_bytes[sizeof(L[0]) + 1];
L_data L_tmp;
} L_union;
int16_t ret = 0;
if (V.l_state != ISR_STATE_WAIT)
ret = -1;
if (!SW1) {
USART_putsr("\r\n Timer limit,");
itoa(V.str, V.l_full, 10);
USART_puts(V.str);
USART_putsr(" Timer value,");
itoa(V.str, L_ptr->strobe, 10);
USART_puts(V.str);
}
/* command state machine
* u/U update the current display buffer with remote RS232 data
* d/D display the current display buffer on RS232 port
* e/E clear/set end of lines flag on display buffer
* i/I timer info command
* z/Z null command
*/
if (!ringBufS_empty(&ring_buf1)) {
rx_data = ringBufS_get(&ring_buf1);
switch (V.comm_state) {
case APP_STATE_INIT:
switch (rx_data) {
case 'u':
case 'U':
V.comm_state = APP_STATE_WAIT_FOR_UDATA;
break;
case 'd':
case 'D':
V.comm_state = APP_STATE_WAIT_FOR_DDATA;
break;
case 'e':
V.comm_state = APP_STATE_WAIT_FOR_eDATA;
puts_ok(V.l_size);
break;
case 'E':
V.comm_state = APP_STATE_WAIT_FOR_EDATA;
puts_ok(V.l_size);
break;
case 'i':
case 'I': // info command
USART_putsr(" Timer limit,");
itoa(V.str, V.l_full, 10);
USART_puts(V.str);
USART_putsr(" OK");
break;
case 'z':
case 'Z': // null command for fillers, silent
break;
default:
USART_putsr("\r\n NAK_I");
ret = -1;
break;
}
break;
case APP_STATE_WAIT_FOR_eDATA:
case APP_STATE_WAIT_FOR_EDATA:
case APP_STATE_WAIT_FOR_DDATA:
case APP_STATE_WAIT_FOR_UDATA:
position = rx_data;
if (position >= strobe_max) {
USART_putsr(" NAK_P");
V.comm_state = APP_STATE_INIT;
ret = -1;
break;
}
offset = 0;
switch (V.comm_state) {
case APP_STATE_WAIT_FOR_UDATA:
V.comm_state = APP_STATE_WAIT_FOR_RDATA;
break;
case APP_STATE_WAIT_FOR_DDATA:
V.comm_state = APP_STATE_WAIT_FOR_SDATA;
break;
case APP_STATE_WAIT_FOR_eDATA:
INTCONbits.GIEH = 0;
L[position].sequence.end = 0; // clear end flag
INTCONbits.GIEH = 1;
V.comm_state = APP_STATE_WAIT_FOR_SDATA;
break;
case APP_STATE_WAIT_FOR_EDATA:
INTCONbits.GIEH = 0;
L[position].sequence.end = 1; // set end flag
INTCONbits.GIEH = 1;
V.comm_state = APP_STATE_WAIT_FOR_SDATA;
break;
default:
break;
}
USART_putsr(" OK");
break;
case APP_STATE_WAIT_FOR_RDATA: // receive
L_union.L_bytes[offset] = rx_data;
offset++;
if (offset >= sizeof(L_union.L_tmp)) {
INTCONbits.GIEH = 0;
L[position] = L_union.L_tmp;
INTCONbits.INT0IF = false;
INTCONbits.GIEH = 1;
USART_putsr(" OK,");
utoa(V.str, (uint16_t) L_union.L_tmp.strobe, 10);
USART_puts(V.str);
V.comm_state = APP_STATE_INIT;
}
break;
case APP_STATE_WAIT_FOR_SDATA: // send
L_tmp_ptr = (void*) &L[position]; // set array start position
do { // send ascii data to the rs232 port
USART_putsr(" ,");
if (offset) {
itoa(V.str, *L_tmp_ptr, 16); // show hex
} else {
itoa(V.str, *L_tmp_ptr, 2); // show bits
}
USART_puts(V.str);
L_tmp_ptr++;
offset++;
} while (offset < V.l_size);
V.comm_state = APP_STATE_INIT;
USART_putsr(" OK");
break;
default:
USART_putsr(" NAK_C");
V.comm_state = APP_STATE_INIT;
if (ringBufS_full(&ring_buf1))
ringBufS_flush(&ring_buf1, 0);
ret = -1;
break;
}
}
return ret;
}
but when a interrupt happens (from several possible sources) it jumps to here and saves the current program context for the main loop.
C:
void interrupt high_priority tm_handler(void) // timer/serial functions are handled here
{
LED1 = 1;
// line rotation sequencer
if (INTCONbits.INT0IF) { // Hall effect index signal, start of rotation
INTCONbits.INT0IF = false;
RPMLED = (uint8_t)!RPMLED;
if (V.l_state == ISR_STATE_LINE) { // off state too long for full rotation, hall signal while in state
V.l_full += strobe_adjust; // off state lower limit adjustments for smooth strobe rotation
}
V.l_state = ISR_STATE_FLAG; // restart lamp flashing sequence, off time
L_ptr = &L[V.line_num]; // select line strobe data
V.rotations++;
/* limit rotational timer values during offsets */
switch (L_ptr->sequence.down) {
case false:
L_ptr->strobe += L_ptr->sequence.offset;
if (L_ptr->strobe < V.l_full)
L_ptr->strobe = V.l_full; // set to sliding lower limit
break;
case true:
L_ptr->strobe -= L_ptr->sequence.offset;
if (L_ptr->strobe < V.l_full)
L_ptr->strobe = strobe_limit_h;
break;
default:
L_ptr->strobe -= L_ptr->sequence.offset;
if (L_ptr->strobe < V.l_full)
L_ptr->strobe = strobe_limit_h;
break;
}
V.line_num++;
if (L_ptr->sequence.end || (V.line_num >= strobe_max)) { // rollover for sequence patterns
V.line_num = 0;
V.sequences++;
}
}
// line RGB pulsing state machine
if (PIR1bits.TMR1IF || (V.l_state == ISR_STATE_FLAG)) { // Timer1 int handler, for strobe rotation timing
PIR1bits.TMR1IF = false;
switch (V.l_state) {
case ISR_STATE_FLAG:
WRITETIMER1(L_ptr->strobe); // strobe positioning during rotation
T1CONbits.TMR1ON = 1;
G_OUT = 0;
R_OUT = 0;
B_OUT = 0;
V.l_state = ISR_STATE_LINE; // off time after index to start time
break;
case ISR_STATE_LINE:
WRITETIMER1(V.l_width);
if (!L_ptr->sequence.skip) {
if (L_ptr->sequence.R)
R_OUT = 1;
if (L_ptr->sequence.G)
G_OUT = 1;
if (L_ptr->sequence.B)
B_OUT = 1;
}
V.l_state = ISR_STATE_WAIT; // on start time duration for strobe pulse
break;
case ISR_STATE_WAIT: // waiting for next HALL sensor pulse
default:
T1CONbits.TMR1ON = 0; // idle timer
G_OUT = 0; // blank RGB
R_OUT = 0;
B_OUT = 0;
break;
}
}
// remote command data buffer
if (PIR1bits.RCIF) { // is data from RS-232 port
V.rx_data = RCREG; // save in state machine register
if (RCSTAbits.OERR) {
RCSTAbits.CREN = 0; // clear overrun
RCSTAbits.CREN = 1; // re-enable
}
ringBufS_put(&ring_buf1, V.rx_data); // buffer RS232 data
}
// check timer0 for blinker led
if (INTCONbits.TMR0IF) {
INTCONbits.TMR0IF = false;
WRITETIMER0(TIMEROFFSET);
LED5 = (uint8_t)!LED5; // active LED blinker
}
LED1 = 0;
}
Each possible interrupt source is checked in sequence for its flag and if that flag is set then that section of code is executed in sequence down the coded checks for interrupt flags.
At the end of the interrupt code the main loop program context is restored, we jump back to the main loop with a special return from interrupt call and the main loop continues.


Linux serial port control test program.
https://github.com/nsaspook/pov_control/blob/master/main.c
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,619
I have read about interrupt. Interrupts are events that cause the microprocessor to stop what it is doing, and handle a high-priority task first. After the interrupt is handled, the microprocessor goes back to whatever it was doing before.

There are two type of interrupt
  • hardware interrupt
  • software interrupt
If using Picmicro, there are also version that have high or low priority interrupts also, e.g. a high INT will take precedence even if a low priority is being processed.
Also even when the Interrupt feature is NOT enabled, functions will set an interrupt flag regardless the state of the overall enable.
This means an interrupt won't occur but the status can be read by a routine.
Max.
 

avayan

Joined Oct 30, 2015
38
Boy, so many things you could try! For the most part, your code is always running some sort of infinite loop where you can be doing whatever you want. It could be checking the switch, updating the LCD output, articulating the buffer, etc. At this point in time your code can do all of these things without a single interrupt.

But now say you want to use a TIMER Interrupt and you configure your timer resource to trigger an Interrupt every 1 ms. You can have your infinite loop doing nothing until 1 ms has elapsed. Then, the infinite loop only performs tasks every 1 ms. There are many reasons why this is good practice. For example, in low power applications you can disable the microcontroller and save power. Then you have the TIMER resource bring the CPU back to life every 1 ms, which is when the code is executed. This would be a very typical examples of interrupts being used.

But there is a pentillion others! You can have interrupts:

1. With an UART, whenever a byte is receive or a byte is sent (similar with I2C, SPI, CAN, etc).
2. With a GPIO whenever an input has changed state (each micro is different on how this one works, but usually on a rising or falling edge).
3. With a Watchdog Timer, whenever the CPU has gone awry and has stopped responding as it should.
4. With an ADC, whenever a conversion is complete (if available on your platform).
5. With a fault, such as the CPU executing an instruction which does not exist (signals some serious problem).
6. etc.

Each micro will have their own collections of interrupts to explore, but I think TIMERS are some of the easiest to learn with. Good luck on your experiments!
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
You all explained interrupt in detail but the original question is different. I repeat my question if we have only micro-controller and LCD then what useful we can make using interrupt.

I think we can do like LCD should be updates in every 2 minutes automatically. so we have to set timer interrupt for 2 minutes after starting program. whenever interrupt will happen LCD will update but I think it's not meaningful example. what are the real life example to set interrupt for LCD
 

nsaspook

Joined Aug 27, 2009
13,086
You all explained interrupt in detail but the original question is different. I repeat my question if we have only micro-controller and LCD then what useful we can make using interrupt.

I think we can do like LCD should be updates in every 2 minutes automatically. so we have to set timer interrupt for 2 minutes after starting program. whenever interrupt will happen LCD will update but I think it's not meaningful example. what are the real life example to set interrupt for LCD
In general LCD updates are slow so you normally don't want that code executing in a interrupt routine. The timer interrupt could set a flag the main routine monitors to trigger a LCD update outside the ISR.
If you have a LCD with a serial data connection the ISR could handle those serial transfers using a buffer to separate the slower processes of formatting the display data from the much faster task of sending the data.

LCD data via SPI interrupt example code fragment:
C:
if (PIE1bits.SSPIE && PIR1bits.SSPIF) { // send data to SPI bus
spi_link.int_count++;
PIR1bits.SSPIF = LOW;
ct1 = SSPBUF; // read to clear the BF flag, don't care about the data with LCD but AUX might
/*
* the SPI data is not sent here, it's scheduled by timer0
* with about 63us for the whole process with LCD data byte to next byte with timer0 LCD delay
* fixed times: ~8us per byte 1MHz clock, 27.3us LCD instruction execution time
* and ~18us overhead for this part
*/
if (spi_link.SPI_LCD) {
if (spi_link.tx1b->count == 0) { // data buffer is empty but maybe the delay is not done, 3.6us overhead
PIE1bits.SSPIE = LOW; // stop data transmitter
spi_link.LCD_TIMER = LOW;
if (spi_link.LCD_DATA) INTCONbits.TMR0IF = HIGH; //set interrupt flag
} else {
ct_spi = ringBufS_get(spi_link.tx1b); // get the 16 bit data
spi_link.config = ct_spi >> 8;
if (spi_link.config & LCD_CMD_MASK) { // is this command data
/*
* check for clear and home commands
*/
if ((ct_spi & 0xff) > LCD_CLEAR_HOME) { // check only the data bits for the last 2 bits
spi_link.delay = LCD_LONG; // needs at least 1.08 ms LCD instruction execution time
} else {
spi_link.delay = LCD_SHORT; // needs at least 27.3us LCD instruction execution time
}
RS = LOW; // sending LCD command data
} else {
spi_link.delay = LCD_SHORT;
RS = HIGH; // sending character data
}
CSB = LOW; // select the display SPI receiver
/*
* setup timer0 for SPI delay and buffer write
*/
spi_link.LCD_TIMER = HIGH;
spi_link.LCD_DATA = HIGH;
INTCONbits.TMR0IF = HIGH; //set interrupt flag to update timer0 as we fall down the ISR
}
}

* This is a little tricky, it normally runs at a very slow speed for a system heartbeat
* but it also times a delay for SPI data to a LCD display for data and commands
* ~36us for data and ~1.2ms for commands set in spi_link.delay
* with ~3us overhead for this part
*/
if (INTCONbits.TMR0IF) { // check timer0 1 second timer & SPI delay int handler
DLED3 = S_ON;
if (spi_link.LCD_TIMER) {
spi_link.LCD_TIMER = LOW;
/*
* send the SPI data then reset timer0 for fast speed data delay
* send time per byte 11us
*/
if (spi_link.LCD_DATA) {
PIE1bits.SSPIE = LOW; // don't process the receive interrupt from the send yet
SSPBUF = ct_spi; // send data
}
/*
* set the link delay
*/
timer.lt = spi_link.delay; // Copy timer value into union
TMR0H = timer.bt[HIGH]; // Write high byte to Timer0
TMR0L = timer.bt[LOW]; // Write low byte to Timer0
} else {
if (spi_link.LCD_DATA) { // we are in a delay from sending a byte
spi_link.LCD_DATA = LOW; // clear the data sent flag
PIE1bits.SSPIE = HIGH; // enable to receive byte when ISR exits, ISR will be called again in ~5us to get it
}
// set normal delay
TMR0H = timer_long.bt[HIGH]; // Write high byte to Timer0
TMR0L = timer_long.bt[LOW]; // Write low byte to Timer0
}
INTCONbits.TMR0IF = LOW; //clear interrupt flag
DLED3 = S_OFF;
}

// external interrupts for buttons that trigger tasks in a low priority ISR routine
if (INTCONbits.INT0IF) {
INTCONbits.INT0IF = LOW;
V.buttonint_count++;
hid0_ptr->bled_on = !hid0_ptr->bled_on;
}
if (INTCON3bits.INT1IF) {
INTCON3bits.INT1IF = LOW;
V.buttonint_count++;
hid1_ptr->bled_on = !hid1_ptr->bled_on;
}
It works with a timer to sequence the data at the slower speed of the LCD device to eliminate delays in the ISR.

https://github.com/nsaspook/e220/blob/master/ll_vector.c

https://forum.allaboutcircuits.com/threads/light-link-system-tester.114228/
 
Last edited:

Sensacell

Joined Jun 19, 2012
3,432
The first thing to contemplate is why use interrupts at all?

Interrupts are good when...

Timing and latency are critical.
You usually write them to handle only the time-critical aspects of a task, then quickly return back to the mainline code.
If you find yourself writing big long loops of code in your interrupt routine, you are not making good use of the concept.
 

avayan

Joined Oct 30, 2015
38
Well, you had also specified a buzzer and a button, but if it is only an LCD and an MCU, then there is not much an interrupt can be used other than refresh rates. For two minutes, I would not bother with using an interrupt, though. I would continue having a 1 ms interrupt based heart beat and then use the ISR to update a variable or allow the main() subroutine to do something. The beauty of this technique is that now you can have a state machine that does different things at different times.

Notice Interrupts are meant to work with real time issues. If your LCD can wait 2 minutes for a refresh, then this is hardly a real time constraint. If you needed to refresh 30 or 60 times per second, then that would be a different matter.
 

MrChips

Joined Oct 2, 2009
30,720
Here is a real life application - a stop watch that show times in seconds and milliseconds.

What you need:

Hardware timer
LCD
START/STOP push-button
RESET push-button

Hardware timer serviced by interrupt.
Push-buttons serviced by interrupt.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
The first thing to contemplate is why use interrupts at all?.
That's what I am looking for when to use interrupt and why use interrupt
Here is a real life application - a stop watch that show times in seconds and milliseconds.

Hardware timer serviced by interrupt.
Push-buttons serviced by interrupt.
stop watch continuously show the time on screen. so if i want to stop that I have to set hardware interrupt for push button. when I press push button hardware interrupt will activate. if I don't press push button it will show the time continuously. I think I have to set hardware interrupt for both Push button and reset button

Do I have to set interrupt for reset button ?

if I set interrupt for reset button button so it will clear the screen. so if I press reset button interrupt will happen
 

simozz

Joined Jul 23, 2017
125
That's what I am looking for when to use interrupt and why use interrupt
You need interrupts when you need to handle asynchronous events.

Another real life example is the matrix keyboard circuit where I suggested you to use interrupts (a few days ago).
The MCU doesn't know when the user will push a key. He only knows that it will happen asynchronously, at an undetermined time of execution.
So when interrupt happens, the MCU must stop to do what he was doing, jump to the ISR, do the ISR task, and then go back to the task he left before the ISR.

It's good to keep the ISR function as short as possible.
 

spinnaker

Joined Oct 29, 2009
7,830
Do I have to set interrupt for reset button ?

if I set interrupt for reset button button so it will clear the screen. so if I press reset button interrupt will happen

You don't NEED to use interrupts for buttons. You application will depend on the need.

As far as rest, it depends on what you are resetting. If you want to reset the MCU then for sire no you would not use an interrupt. What happens if the MCU is hung up in the interrupt routine? Or if the interrupt is not working? How are you going to reset it? Most MCUs have a dedicated reset pin.
 

nsaspook

Joined Aug 27, 2009
13,086
Last edited:

Thread Starter

Parth786

Joined Jun 19, 2017
642
Interrupt hardware and software design is a big subject, you won't really learn much here just asking about it. You need to do it, first for study and then second for fun to explore the possibilities. If it never becomes fun then maybe you're doing the wrong thing.
I have read it and even I have written interrupt program for LED. I want to make interrupt program that may be useful

If i write interrupt program for LCD, then what should be the purpose of my program that may useful. same for keypad If i write interrupt program for keypad, then what should be the purpose of my program
 

atferrari

Joined Jan 6, 2004
4,764
Also even when the Interrupt feature is NOT enabled, functions will set an interrupt flag regardless the state of the overall enable.
This means an interrupt won't occur but the status can be read by a routine.
Max.
Yes. One of the most ignored but really useful features. After reading it, do not forget to reset the flag of interest.
 

atferrari

Joined Jan 6, 2004
4,764
Suppose I have microcontroller Buzzer, Switch and LCD. What I can make with all four of them that may be useful and can be use interrupt in project.

My main purpose is learn to use of interrupt in project. I have seen example like digital clock. What I can make useful with all four of them
I understand you are trying to design an application with them that could require the use of interrupts. When you need to solve some critical timing, then you go for interrupts. Do not force a solution that is not required.

You said you applied interrupts with LEDs. Could you describe how it was implemented?
 

nsaspook

Joined Aug 27, 2009
13,086
Yes. One of the most ignored but really useful features. After reading it, do not forget to reset the flag of interest.
The flags can also be set inside a ISR to modify later actions of the ISR.

In the LCD data via SPI interrupt example above the timer0 state machine is triggered by setting:
if(spi_link.LCD_DATA) INTCONbits.TMR0IF= HIGH;//set interrupt flag
in the SPI flag code section. The Timer0 code that's later in the ISR sequence then 'before a counter interrupt' starts to sequence the proper timing of LCD commands using counter interrupts until the SPI ring buffer is empty. Then the SPI interrupt section of the code resets the state machine. That's fun!
 
Last edited:

Thread Starter

Parth786

Joined Jun 19, 2017
642
You said you applied interrupts with LEDs. Could you describe how it was implemented?


code for interrupt : led blink at every 60 ms
C:
#include<reg51.h>
sbit LED = P1^7;
int main(void)
{
/* Make all ports zero */
   P0 = 0x00;
   P1 = 0x00;
   P2 = 0x00;
   P3 = 0x00;

/* Stop Timer 0   */
   TR0 = 0;

/*Clear the interrupt flag */
   TF0 = 0;

/*Set timer0 in mode 1*/
   TMOD = 0x01;

/* 60 ms reloading time */
   TH0 = 0x27;
   TL0 = 0xFD;

/* Enable Timer0 interrupts */
   ET0 = 1;

/* Global interrupt enable */
   EA  = 1;

/* Start Timer 0 */
   TR0 = 1;

while (1)
    {
      /* Do Nothing */
    }

/* It is called after every 60ms */
void timer(void) interrupt 1
    {
        LED=~LED;               /*toggle LED on interrupt */
        TH0=0x48;                /* initial values loaded to timer */
        TL0=0x01;
        TF0 = 0;                  /*Clear the interrupt flag */

    }
In this program, I understand how the interrupt works for Lad. After this I want to make program for LCD where interrupt require. I don't have much knowledge of programming that's why i want to play simple thing's. if i write program successfully for LCD then I will jump on keypad

What should be problem statement for the LCD where interrupt require
 
Last edited:

spinnaker

Joined Oct 29, 2009
7,830
Some LCDs have a pin that tells you if it is OK to send another character. You could use an external interrupt on your MCU to monitor that pin and only send a character when the LCD is ready.

This would allow your program to send data to the LCD without blocking. IMHO way more trouble than it is worth unless you absolutely need it. You usually sending so little data to the LCD, the amount of blocking that will occur is minimal.
 

Thread Starter

Parth786

Joined Jun 19, 2017
642
I am little bit confuse on interrupt service routine

Here is my program for timer interrupt

C:
#include<reg51.h>

sbit  LED = P2^0;                // Led connected to P2^0

void  initialize_Port(void);    //Function declarations

void initialize_Port(void)
{
       P0 = 0x00;
       P1 = 0x00;
       P2 = 0x00;
       P3 = 0x00;
}

void main (void)
{
       initialize_Port();

       TR0 = 0;         // Stop Timer 0
       TF0 = 0;         // Clear the interrupt flag
       TMOD  = 0x01;    // Set timer0 in mode 1
       TH0 = 0x27;      // 60 ms reloading time
       TL0 = 0xFD;

       ET0 = 1;         // Enable Timer0 interrupts
       EA  = 1;         // Global interrupt enable

       TR0 = 1;         // Start Timer 0

       while(1)         // Do nothing
          {
            }
}

void Timer0_ISR (void) interrupt 1   // It is called after every 60 ms
{
    LED = ~LED;      // Toggle the LED pin
    TH0 = 0x4B;        // initial values loaded to timer  (50ms)
    TL0 = 0xFD;
    TF0 = 0;         // Clear the interrupt flag
}
When timer overflows then interrupt occur. So the program code in ISR start to execute. In my example interrupt happen at 60 ms.
suppose my ISR code

C:
void Timer0_ISR (void) interrupt 1   // It is called after every 60 ms
{

     if (Button = Pressed)
     {
         LED = ON;
     }
     else
     {
         LED = OFF;
     }
      TF0 = 0;         // Clear the interrupt flag
}
What will happen when interrupt occur?

Does this process happen

first check button after 60 ms and if button pressed turn on LED otherwise turn of LED
Again check button after every 60 ms and if button pressed turn on LED otherwise turn of LED
Again check button after every 60 ms and if button pressed turn on LED otherwise turn of LED .. ..Do this forever

check button after every 60 ms and if button pressed turn on LED otherwise turn ofF LED.

So when interrupt happen, do the task in ISR till the interrupt is active

Note : code for the button is not complete. This is only example I have taken for good understanding
 
Last edited:
Top