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++
rogue
March 17, 2011, 3:07am
2
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?
rogue
March 18, 2011, 3:59am
4
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
rogue
March 21, 2011, 11:42pm
6
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; } }
rogue
March 23, 2011, 3:05am
8
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
rogue
March 23, 2011, 6:42pm
10
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?