atmega32 INT2

Hi...

 

I have an atmega 32... I want to use all of the 3 interrupts... I got problems with INT2...

 

I set it up as a falling edge and via a 10K resistor put the button to ground...

 

while(bit_is_set(PINB, PB2));

_delay_ms(5000);

//init interupt

GICR |= (1<<INT0) | (1<<INT1) | (<<INT2);

sei();

 

 

 

the problem is that after the while... when the interrupts are initialized... the pull-up drops out...

tried pulling it up after sei(); again, and before too but doesn't helped...

 

any ideea? I had to change the board... the button needs to be put from GND to VC++

hey djhesit8

can you post more of your code perhaps?  It looks like your snippet of code is initializing at the beginning of your main, is that right? If so I’m curious why you are blocking initilization with the while and 5 second delay which stops doing anything for 5 seconds.

Cheers man- hope I can be of help but I might be MIA with exams and all

it was like this DDRB |=

it was like this

 

DDRB |= 0x00;

PORTB | = (1<<PB2);

while(bit_is_set(PINB, PB2));

_delay_ms(5000);

GICG |= (1<<PB2);

sei();

 

problem is that until while… I measure 4.98V on PB2… than after button press it’s 0.02V

 

anyway

I had a problem with the button… it has to be wired to both VCC and GND… I made it this way:

 

GND -> 10K -> button -> AVR

 

now the wiring is like this:

GND -> 10K - avr -> button -> VCC

 

working like a charm…

 

I still have problem…

 

I have a TSOp1138 with pull-up to 5V… INT2 as falling edge… theproblem is that this at the smallest change it cause an intterupt… any ideea?

have you considered using

have you considered using the internal pullup resistor and making your button short the pin to ground?

that was the intention…

that was the intention… but

 

DDRB = 0x00;

PORTB |= (1<<PB2);

while(bit_is_set(PINB, PB2));     //here voltmeter sais 4.98V

GICR |= (1<<INT2);

MCUCRS |= (1<<ISC02);       //falling edge

sei();                                 //voltmetter says 0.03V

 

ISR(INT2_vect)

{

if(bit_is_clear(PINB, PB2))    //button shorts to ground, to be shure that it was pressed and isn’t a voltage fluctuation

   {

   //do the thing

   }

}

 

 

simply after enable pull-up… it’s oke…

 

sei();… clears pull up…

 

 

tried this way:

 

DDRB = 0

PORTB - pull up PB2

while button isn’t pressed

 

set interrupt 2

falling edge

sei();

portb - pull up again…

 

nothing

setting the global interrupt

setting the global interrupt enable shouldn’t effect an internal pullup resistor setting.

What is

while(bit_is_set(PINB, PB2));     //here voltmeter sais 4.98V

supposed to do? (why are you using a while statement) And where is this in the code?

Are you running just the code necessary to verify this, and can you post that full C file including bit_is_set and bit_is_clear functions?

while(bit_is_set(PINB,

while(bit_is_set(PINB, PB2)); means it has a button pull-ed to ground via 10K… the pull-up is enabled internally and wait until I press the button…

 

bit is set means: (PINB & PB2)==1

 

not a dramatic stuff

 

the whole code ehhh:

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

//define types
#define ADC_VREF_TYPE 0xE0        //internal 2.56V reference

uint8_t distance, d1, d2, int_stop = 0;
int win = 0, winplus = 0, timer = 0, tcc = 0, fpush = 0;
void front(void);
void back(void);
void left(void);
void right(void);
void clear_drive(void);

unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

int main()
    {
    uint8_t distance=0;
    int sl_switch=0, start = 0, emotive = 0, detect = 0;
    DDRA |= 0x00;

    DDRB = (1<<PB0) | (1<<PB1) | (1<<PB3) | (1<<PB4) | (1<<PB5);
    PORTB = 0x00;

    DDRD |= (1<<PD4) | (1<<PD5);
    PORTD = 0x00;

    //ADC setup
    ADMUX=ADC_VREF_TYPE & 0xff;
    ADCSRA=0x87;



    if(bit_is_clear(PINA,PA1))        //check swtich button
    sl_switch=0;
    else
    sl_switch=1;

    //clear port A
    PORTA = 0x00;

    //adc calibration measurement
    distance = read_adc(0);
    _delay_ms(10);
    distance = 0;            //flush the value



    //interrupt for TSOP, LINE, EMERGENCY
    MCUCSR |= (1<<ISC2);            //rising edge trigger
    GICR |= (1<<INT2);
    //MCUCR |= (1<<ISC10) | (1<<ISC01);


    while(bit_is_clear(PINB,PB2));        //wait until I say go
    _delay_ms(5000);

    //motor driver PWM (fast PWM)
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
    TCCR1B |= (1<<WGM12)|(1<<CS11);

    sei();


    if(sl_switch==0)
    {
    while(1)                //sumo
        {
        OCR1A = 255;
        OCR1B = 255;
        if(start==0)            //check position with aritmetic media
        {
        d1=read_adc(0);
        back();
        _delay_ms(100);
        d2=read_adc(0);
        if(d1>d2&&d2>=100)
            {
            clear_drive();
            _delay_ms(250);
            front();
            }
        else
            {
            if(emotive==0)
            {
            back();
            OCR1A = 155;
            OCR1B = 255;
            _delay_ms(250);
            OCR1A = 255;
            OCR1B = 155;
            _delay_ms(250);
            OCR1A = 255;
            OCR1B = 255;
            emotive = 1;
            clear_drive();
            _delay_ms(250);
            }
            left();
            }
        start = 1;
        }
        distance=read_adc(0);
        if(distance>=45)            //first measurement
        {
        front();
        while(distance<=125)
            {
            distance=read_adc(0);
            _delay_ms(5);
            }
        win = 1;
        distance = read_adc(0);
        if(distance>=125)
            {
            fpush = 1;
            front();
            while(bit_is_clear(PIND, PD2));        //change to set when play
            }
        }
        else
        {
        fpush = 0;
        left();
        while(distance<45)
            {
            distance=read_adc(0);
            _delay_ms(5);
            detect = 1;
            }
        if(detect == 1)
            {
            back();
            _delay_ms(250);
            clear_drive();
            _delay_ms(250);
            }
        win = 0;
        }
        if(win==1)
        {
        back();
        _delay_ms(1000);
        for(winplus=0;winplus<=5;winplus++)
            {
            left();
            _delay_ms(250);
            right();
            _delay_ms(250);
            }
        clear_drive();
        //while(1);
        }
        _delay_ms(5);
        };
    }
    else
    {


    OCR1A = 255;
    OCR1B = 255;


    PORTB |= (1<<PB0);        //switch on LED & TSOP


    //Laser 38khz driver
    TCCR2=0x39;
    TCNT2=0x3E;
    OCR2=0xC1;

    //timer0  overflow 2sec = 900
    TCCR0 |= (1<<WGM00) | (1<<CS01) | (1<<CS00);


    while(1)                //laser
        {
        //laser tag code goes here
        };
    }
    }



void front(void)
    {
    clear_drive();
    PORTB |= (1<<PB5) | (1<<PB4);
    }

void back(void)
    {
   clear_drive();
    PORTB |= (1<<PB1) | (1<<PB3);
    }

void left(void)
    {
    clear_drive();
    PORTB |= (1<<PB5) | (1<<PB3);
    }

void right(void)
    {
    clear_drive();
    PORTB |= (1<<PB4) | (1<<PB1);
    }

void clear_drive(void)
    {
    PORTB &= ~(1<<PB5);
    PORTB &= ~(1<<PB4);
    PORTB &= ~(1<<PB3);
    PORTB &= ~(1<<PB1);
    }

ISR(INT0_vect)                    //senzor linie
    {
    if(fpush == 0)
    {
    clear_drive();
    back();
    _delay_ms(1500);
    right();
    _delay_ms(1000);
    clear_drive();

    }
    }

ISR (INT1_vect)                    //TSOP
    {
    //robot full stop
    OCR2=0x00;                    //laser
    OCR1A = 0;
    OCR1B = 0;
    PORTB &= ~(1<<PB0);                //stop TSOP
    _delay_ms(5000);                //5 seconds shot time

    front();
    OCR1A = 255;
    OCR1B = 255;
    OCR2=0xC1;

    //timer0 of 2 sec start here
    timer = 1;
    }

ISR (INT2_vect)                    //emergency STOP BUTTON
    {
    if(bit_is_set(PINB, PB2))
    {
    OCR1A = 0;
    OCR1B = 0;
    PORTB = 0x00;
    PORTA = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    while(1);
    }
    }

ISR(TIMER0_OVF_vect)
    {
    if(timer==1)
    {
    if(tcc<=900)
        {
        tcc++;
        }
    else
        {
        PORTB |= (1<<PB0);        //start TSOP + LED
        OCR2=0xC1;
        }
    timer = 0;
    }
    }

 

if your int2 executes you

if your int2 executes you should know that the button has been pressed as it should short pin 3 (PB2) to ground (don’t use a resistor). So you shouldn’t need to check for it in your ISR of int2, which if you did you would check if the bit is low (not high) as in the button is pressed (so don’t use if(bit_is_set), use if(bit_is_clear)).

Hopefully this solves your problem, but if you still have problems I suggest starting a simple project which just addresses this one task with as little code as possible to narrow down the problem.

in ISR have to check if the

in ISR have to check if the button is under 1.5V (low)… cause any fluctuation in the electric lines even 0.01V fires the interrupt… I shorted the pin to ground too without resistor… nothing… I don’t care about this problem…

 

my problem as I told is:

after enabling global interrupt with sei(); the pull-up goes away :frowning:

The interrupt should only

The interrupt should only fire when the digital state changes, so 0.01V should not fire the interrupt. If you have noise (which you can verify with a digital storage oscilloscope) that can trigger your interrupt.  Motors are very noisy, do you have a noise filtering capacitor in your circuit?