ad space

Programming ATmega32 External Interrupt

Many application requires that some external event trigger an interrupt to the microcontroller so that microcontroller can take action. Example of application would be triggering an interrupt when there is detection of fire by temperature sensor, gas sensor or when some threshold count is reached. Most microcontroller like ATmega32 are equipped with external interrupt feature on some of their pins. Here we illustrate how we can program ATmega32A to detect an external event that then trigger an interrupt.

 

Programming ATmega32 External Interrupt

 

The ATmega32/ATmega32A has 3 external hardware interrupt INT0, INT1 and INT2 at pins PD2, PD3 and PB2 respectively. When external interrupt on these pins are activated, the microcontroller CPU is interrupted and jumps to the ISR(Interrupt Service Routine) to execute code in that ISR. 

 

There are 5 registers involved in configuring the external hardware interrupt. They are

1. GICR (General Interrupt Control Register)

- used to enable/disable INT0, INT1 and INT2 external interrupt

2. SREG (Status Register)

- used only to enable the global interrupt

3. MCUCR (MCU Control Register)

- used to configure INT0 and INT1 edge or level triggered interrupt 

4.  MCUCSR (MCU Control and Status Register)

- used to configure INT2 edge triggered interrupt  

5.  GIFR (General Interrupt Flag Register)

 

1. GICR (General Interrupt Control Register)

In order to activate the external hardware interrupt the interrupt(s) must be first activated. The interrupt can be activated by setting the INTx bit(x=0,1,2) in the GICR (General Interrupt Control Register)register. The GICR (General Interrupt Control Register)register is shown below.

 

 2. SREG (Status Register)

For enabling the external interrupt, the I-bit in the Status Register (SREG) must also set.

 

 3. MCUCR (MCU Control Register)

By default, the INT0, INT1 and INT2 are all low level triggered interrupt. That is when the triggering signal into the interrupt pins are low then interrupt is generated by the hardware. But the INT0 and INT1 external interrupt can be configured to generate interrupt according to rising edge, falling edge or logical change detection of the input signal. INT2 is only edge-level triggered interrupt(either rising or falling).

For INT0 and INT1 interrupt, we can configure what kind of signal state or transition at the interrupt input pins can generate interrupt by using the MCU Control Register(MCUCR). The MCUCR is shown below.


The ISC01 and ISC00 bits are the interrupt sense bits for the external interrupt 0(INT0). These two bits combination defines which type of signal transition triggers the interrupt. 


Similarly, the ISC11 and ISC10 bits defines which type of signal transition causes external interrupt 1(INT1).


 

 4.  MCUCSR (MCU Control and Status Register)

For INT2, the ISC2 bit in the MCUCSR register controls whether to use rising or falling edge detection for generating external interrupt.


If the ISC2 bit is 0 then the falling edge of INT2 generates interrupt and when it is 1 then the rising edge of INT2 generates the interrupt.


5.  GIFR (General Interrupt Flag Register)

The GIFR register contains INTF0, INTF1 and INTF2 flag bits which are set whenever external interrupt occurs. We can use monitor these bits to know whether there is any interrupt. 



Programming ATmega32 External Interrupt

Example 1:

In the following example code, we will use external interrupt on INT0(that is on Port D pin 2). A switch is connected to the INT0 pin which is pulled high internally. So the INT0 reads high in normally operation. Whenever the INT0 input goes low, by pressing the switch to ground, interrupt is generated which will toggle the state of a LED which is connected to Port D pin 7.

The following shows the circuit diagram for external interrupt on INT0 pin.

atmega32 external interrupt INT0 circuit diagram

Program Code:

The following is the program code to generate external interrupt INT0 and toggle LED in ISR(Interrupt Service Routine) for INT0.

#include <avr/io.h>
#include <avr/interrupt.h>

int main()
 { 
	DDRD |= (1<<PD7);	//set PD7 as output for LED
	PORTD |= (1<<PD2); 	//enable pull-up
	GICR |= (1<<INT0);	//enable external interrupt 0
	sei();		//enable global interrupt

   while (1);

	return 0;
 }

ISR(INT0_vect){
	PORTD ^= (1<<PD7);
}


Here, first we have to include the interrupt.h file in order to use interrupt feature. We then have to set up the Port D pin 7 as output since LED is connected to it. Then we enable the INT0 external interrupt by setting the INT0 bit in the GICR register. After this we enable the global interrupt using sei() function. In order to use the interrupt, we have to use the ISR() function with specific interrupt vector name which is in this case INT0_vect.

See the following video demonstration



Example 2:

In this external interrupt example, we will illustrate how to use the edge detection interrupt. For this we will use INT1 external interrupt as falling edge triggered interrupt. In this case, whenever the INT1 goes low, it will toggle the LED connected to the Port D pin  7 only once. 

The circuit schematic is shown below.

atmega32 external interrupt INT1 circuit diagram

 

 Program Code:

The program to configure INT1 external interrupt with falling edge triggered interrupt is as below.

#include <avr/io.h>
#include <avr/interrupt.h>

int main()
 { 
	DDRD |= (1<<PD7);	//set PD7 as output for LED
	PORTD |= (1<<PD3); 	//enable pull-up
	GICR |= (1<<INT1);	//enable external interrupt 1
	MCUCR |= (1<<ISC10);		//set ISC10 bit to configure INT1 as falling edge triggered interrupt
	sei();		//enable global interrupt

   while (1);

	return 0;
 }

ISR(INT1_vect){
	PORTD ^= (1<<PD7);
}

 

In the code, we have included the interrupt.h header file in order to use interrupt. We have setup the Port D pin 7 as output for the LED. 

 The following video demonstrates this.


Post a Comment

Previous Post Next Post