Methods of I/O Operation Synchronous I/O operation. This is possible when the I/O device operates at the same speed as that of MCU. In this case the I/O operation with the device is performed by the MCU assuming that the device is always ready . Asynchronous I/O Operation. In this case, generally the I/O device is very slow when compared to the MCU. Then, it can perform I/O operation by the following methods: By polling. By using interrupts.
I/O Operation by Polling Polling results in waste of MCU time and power and does not permit masking of devices since all devices have to be checked .
Polling Example
I/O Operation by Interrupts The MCU keeps on doing some useful operation, or it remains in a low-power state after enabling interrupts . When I/O device is ready, it interrupts the MCU . The MCU completes execution of the current instruction, saves the return address on the stack, and then jumps to the Interrupt Service Routine (ISR) to serve the device . After this, the MCU returns back to the interrupted program by loading the return address from the stack to the Program Counter . Interrupts can be enabled or disabled dynamically and when multiple interrupts come simultaneously priorities can be assigned.
Interrupt Example
Default Interrupt Vectors in Atmega328P
Interrupt Vectors in Atmega328P Interrupt vector is a definite address in the program memory where a JMP instruction should be written to jump to the ISR corresponding to the interrupt . Each interrupt vector occupies two program memory words in order to provide space for JMP instruction . In Atmega328P, the RESET Vector is affected by BOOTRST fuse and the Interrupt Vector start address is affected by IVSEL bit in the MCUCR.
Enabling and Disabling Interrupts in Atmega328P In SREG if I = 1, then all interrupts are enabled. We can make I = 1 by using SEI instruction in ALP and sei () function in C program. In SREG if I = 0, then all interrupts are disabled. We can make I = 0 by using CLI instruction in ALP and cli () function in C program. Upon reset I = 0 so all interrupts are disabled.
Bits of (EICRA) External Interrupt Control Register A Control Nature of INT1 and INT0 Bits 7, 6, 5, and 4 are not used and are always read as 0.
Bits of EIMSK( External Interrupt Mask Register) Mask/Unmask INT1 and INT0 Masking/unmasking means disabling/enabling respectively. When INT1 = 1 INT1 is unmasked if I = 1 in SREG. When INT1 = 0 INT1 is masked even if I = 1 in SREG. When INT0 = 1 INT0 is unmasked if I = 1 in SREG. When INT0 = 0 INT0 is masked even if I = 1 in SREG. Activity on the pins of INT1/INT0 will cause an interrupt request even if the corresponding pins are configured as output pins. Bits 2 to 7 are unused and will always be read as 0.
Bits of (EIFR) External Interrupt Flag Register Show Status of INT1 and INT0 Bits 2 to 7 are unused and will always be read as 0. When INT1 interrupt is triggered, INTF1 becomes 1. This flag is cleared when ISR is executed. When INT0 interrupt is triggered, INTF0 becomes 1. This flag is cleared when ISR is executed. INTF1/INTF0 flags can be cleared by writing a logical 0 to the respective bit. INTF1/INTF0 flags are always cleared when the respective interrupts are configured as a level interrupt. R
Interrupts Type 1 – Event is remembered when interrupt is disabled If interrupt is not enabled, flag is set When interrupt is enabled again, interrupt takes place, and flag is reset Type 2 – Event is not remembered when interrupt is disabled Signal level causes interrupt If level occurs when interrupt is enabled, interrupt takes place If interrupt is not enabled, and level goes away before the interrupt is enabled, nothing happens
When Will External Interrupts be Triggered ? When the INT0 or INT1 interrupts are enabled and are configured as low level triggered (Type 2), the interrupts will trigger as long as… The pin is held low. The low level is held until the completion of the currently executing instruction. The level is held long enough for the MCU to completely wake-up (assuming it was asleep). – Low level interrupt on INT0 and INT1 are detected asynchronously (no clock required). The I/O clock is halted in all sleep modes except idle mode. Therefore low level interrupts can be used for waking the part from all sleep modes. Among other applications, low level interrupts may be used to implement a handshake protocol.
When the INT0 or INT1 interrupts are enabled and are configured as edge or logic change (toggle) triggered, (Type 11) the interrupts will trigger as long as… The I/O clock is present. – This implies that these interrupts cannot be used for waking up the part from sleep modes other than idle mode. The pulse lasts longer than one I/O clock period. Shorter pulses are not guaranteed to generate an interrupt.
In addition to our two (2) external interrupts, twenty-three (23) pins can be programmed to trigger an interrupt if there pin changes state. These 23 pins are in turn divided into three (3) interrupt groups (PCI 2:0) corresponding to the three GPIO Ports B, C, and D Each of the groups are assigned to one pin change interrupt flag (PCIF) bit (2:0). A pin change interrupt flag will be set, if the interrupt is enabled (see How to Enable a Pin Change Interrupt), and any pin assigned to the group changes state (toggles).
How to Enable a PIN Change Interrupt In addition to our two (2) external interrupts, twenty-three (23) pins PCINT 23:16, 14:0 can be programmed to trigger an interrupt if there pin changes state . These 23 pins are divided into three (3) interrupt groups (PCI 2:0) of eight (8), seven (7) and (8 ). Consequently to enable and individual pin change interrupt 3 interrupt mask bits must be set to one (1). The SREG global interrupt enable bit I The pin change interrupt enable bit (PCIE 2:0) group the pin is assigned. Specifically, a pin change interrupt PCI2 will trigger if any enabled PCINT23..16 pin toggles . A pin change interrupt PCI1 will trigger if any enabled PCINT14..8 pin toggles. A pin change interrupt PCI0 will trigger if any enabled PCINT7..0 pin toggles.
The individual pin change interrupt enable mask bit assigned to the pin (PCINT 23:0) is set. These mask bits are located in the three pin change mask registers assigned to each group.
Arduino Language Support for External Interrupts attachInterrupt (interrupt, function, mode) interrupt: 0 or 1 function: interrupt function to call mode: LOW, CHANGE, RISING, FALLING detachInterrupt (interrupt) interrupts( ) – Enable interrupts : sei ( ) noInterrupts ( ) – Disable interrupts : cli ( )
int pin = 2 ; //define interrupt pin to 2 volatile int state = LOW ; // To make sure variables shared between an ISR //the main program are updated correctly,declare them as volatile. void setup () { pinMode ( 13 , OUTPUT ); //set pin 13 as output attachInterrupt ( digitalPinToInterrupt ( pin ), blink , CHANGE ); //interrupt at pin 2 blink ISR when pin to change the value } void loop () { digitalWrite ( 13 , state ); //pin 13 equal the state value } void blink () { //ISR function state = ! state ; //toggle the state when the interrupt occurs }