Thursday 13 February 2014

INTERFACING SWITCH WITH AVR MICROCONTROLLER WITH INTERRUPT

           Switches are used to do intended actions or a task when pressed. This is most common in embedded devices. But polling a key press can cause more code to repeat until a valid key is recognized & power will be wasted.

           One solution is to use the keys with interrupt. So the ISR will be made to do the task of the key. In the main loop this task is removed so the MCU can be put into sleep mode, where an interrupt will make MCU to wake up. Here we present a simple code with 3 switches connected to interrupt the CPU when pressed. Note that Sleep mode is not used in this project, but it is simple to add.

CLICK HERE TO VIEW SLEEP MODE EXAMPLE.


         In this example we have used AVR Atmega8 microcontroller, the keypress ISR determines which key is pressed & displays it in USART. Note that the ISR returns only when the pressed is released. This is added for proper key de-bounce action, but much longer key press can cause lock-up until it is released. So triple check the circuit connections for errors & short circuits before powering up. This is optional & can be removed.

Circuit Diagram:

Program:
THIS WORK IS INTENDED TO BE USED FOR HOBBY & LEARNING PURPOSE ONLY. NO PART OF THIS CAN BE PUBLISHED OR USED IN COMMERCIAL PRODUCTS WITHOUT A WRITTEN PERMISSION FROM ELECDUDE.

#define F_CPU 1000000UL

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

/*****************MACRO's DEFINITION*********************************/
#define BIT(x)        (1 << (x))    //Set a particular bit mask
#define CHECKBIT(x,b)     (x & BIT(b))    //Checks bit status
#define SETBIT(x,b)     x|=BIT(b);    //Sets the particular bit
#define CLEARBIT(x,b)     x&=~BIT(b);    //Sets the particular bit
#define TOGGLEBIT(x,b)     x^=BIT(b);    //Toggles the particular bit
unsigned char ch='A';
#include "USART.h"

//ISR_ALIAS(INT1_vect, INT0_vect);//1->0
ISR(INT0_vect)
{
    ch=PINC; //read key status
    while(bit_is_clear(PIND,2)); //wait for de-bounce
    ch=((~ch) & 0x07);
    uart_puts_p("Switch ");
    switch(ch)
     {
      case 1:uart_putc('1');break;
      case 2:uart_putc('2');break;
      case 4:uart_putc('3');break;
     }
    uart_puts_p(" is pressed\n\r");
}

int main()
{
    PORTD=0xFF;//enable pull ups @ PD
            //int1 posedge        int0 posedge
    MCUCR|=(0<<ISC11)
|(0<<ISC10)|(1<<ISC01)|(0<<ISC00);
    GICR |= (0<<INT1)|(1<<INT0);//enable INT1 & INT0

    DDRD=0x00;//for i/P
   
    DDRB=0xFF;
    DDRC=0xF0;
    PORTC=0x0F;
   
    uart_init(9600,2);
    _delay_ms(50);
    uart_puts_p("Welcome...\n\r");
    sei();

     while(1)
         {
        //
        //
        }
 return 0;
}

// waits (pauses) for ms milliseconds
void WaitMs(unsigned int ms)
{
    unsigned int m;

    for(m=0;m<=ms/10;m++)
    {
        _delay_ms(10);
    }
}
Click here to goto USART example download.

Proteus Simulation Output Snapshot:






If you enjoyed this post plz let us know your views via comments.
This helps us to do much more better.
Thankyou.

0 comments:

Post a Comment

Search Here...